blob: 01877a143106f846687d840f58fa6cfbec7e089c [file] [log] [blame]
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001/* Parser-tokenizer link implementation */
2
3#include <stdio.h>
4
5#include "PROTO.h"
6#include "malloc.h"
7#include "tokenizer.h"
8#include "node.h"
9#include "grammar.h"
10#include "parser.h"
11#include "errcode.h"
12
13extern int debugging;
14
15
16/* Parse input coming from the given tokenizer structure.
17 Return error code. */
18
19static int
20parsetok(tok, g, start, n_ret)
21 struct tok_state *tok;
22 grammar *g;
23 int start;
24 node **n_ret;
25{
26 parser_state *ps;
27 int ret;
28
29 if ((ps = newparser(g, start)) == NULL) {
30 fprintf(stderr, "no mem for new parser\n");
31 return E_NOMEM;
32 }
33
34 for (;;) {
35 char *a, *b;
36 int type;
37 int len;
38 char *str;
39
40 type = tok_get(tok, &a, &b);
41 if (type == ERRORTOKEN) {
42 ret = tok->done;
43 break;
44 }
45 len = b - a;
46 str = NEW(char, len + 1);
47 if (str == NULL) {
48 fprintf(stderr, "no mem for next token\n");
49 ret = E_NOMEM;
50 break;
51 }
52 strncpy(str, a, len);
53 str[len] = '\0';
54 ret = addtoken(ps, (int)type, str);
55 if (ret != E_OK) {
56 if (ret == E_DONE)
57 *n_ret = ps->p_tree;
58 else if (tok->lineno <= 1 && tok->done == E_EOF)
59 ret = E_EOF;
60 break;
61 }
62 }
63
64 delparser(ps);
65 return ret;
66}
67
68
69/* Parse input coming from a string. Return error code. */
70
71int
72parsestring(s, g, start, n_ret)
73 char *s;
74 grammar *g;
75 int start;
76 node **n_ret;
77{
78 struct tok_state *tok = tok_setups(s);
79 int ret;
80
81 if (tok == NULL) {
82 fprintf(stderr, "no mem for tok_setups\n");
83 return E_NOMEM;
84 }
85 ret = parsetok(tok, g, start, n_ret);
86 if (ret == E_TOKEN || ret == E_SYNTAX) {
87 fprintf(stderr, "String parsing error at line %d\n",
88 tok->lineno);
89 }
90 tok_free(tok);
91 return ret;
92}
93
94
95/* Parse input coming from a file. Return error code. */
96
97int
98parsefile(fp, g, start, ps1, ps2, n_ret)
99 FILE *fp;
100 grammar *g;
101 int start;
102 char *ps1, *ps2;
103 node **n_ret;
104{
105 struct tok_state *tok = tok_setupf(fp, ps1, ps2);
106 int ret;
107
108 if (tok == NULL) {
109 fprintf(stderr, "no mem for tok_setupf\n");
110 return E_NOMEM;
111 }
112 ret = parsetok(tok, g, start, n_ret);
113 if (ret == E_TOKEN || ret == E_SYNTAX) {
114 char *p;
115 fprintf(stderr, "Parsing error at line %d:\n",
116 tok->lineno);
117 *tok->inp = '\0';
118 if (tok->inp > tok->buf && tok->inp[-1] == '\n')
119 tok->inp[-1] = '\0';
120 fprintf(stderr, "%s\n", tok->buf);
121 for (p = tok->buf; p < tok->cur; p++) {
122 if (*p == '\t')
123 putc('\t', stderr);
124 else
125 putc(' ', stderr);
126 }
127 fprintf(stderr, "^\n");
128 }
129 tok_free(tok);
130 return ret;
131}