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