blob: ba9841841e1bb91aa6ef716c29cb8b8b9ea4ca35 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
2Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
3Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000025/* Parser-tokenizer link implementation */
26
Guido van Rossum3f5da241990-12-20 15:06:42 +000027#include "pgenheaders.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000028#include "tokenizer.h"
29#include "node.h"
30#include "grammar.h"
31#include "parser.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +000032#include "parsetok.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000033#include "errcode.h"
34
Guido van Rossum3f5da241990-12-20 15:06:42 +000035
36/* Forward */
37static int parsetok PROTO((struct tok_state *, grammar *, int, node **));
38
39
40/* Parse input coming from a string. Return error code, print some errors. */
41
42int
43parsestring(s, g, start, n_ret)
44 char *s;
45 grammar *g;
46 int start;
47 node **n_ret;
48{
49 struct tok_state *tok = tok_setups(s);
50 int ret;
51
52 if (tok == NULL) {
53 fprintf(stderr, "no mem for tok_setups\n");
54 return E_NOMEM;
55 }
56 ret = parsetok(tok, g, start, n_ret);
Guido van Rossum326f5821991-06-03 11:02:09 +000057/*
58XXX Need a more sophisticated way to report the line number.
Guido van Rossum3f5da241990-12-20 15:06:42 +000059 if (ret == E_TOKEN || ret == E_SYNTAX) {
60 fprintf(stderr, "String parsing error at line %d\n",
61 tok->lineno);
62 }
Guido van Rossum326f5821991-06-03 11:02:09 +000063*/
Guido van Rossum3f5da241990-12-20 15:06:42 +000064 tok_free(tok);
65 return ret;
66}
67
68
69/* Parse input coming from a file. Return error code, print some errors. */
70
71int
72parsefile(fp, filename, g, start, ps1, ps2, n_ret)
73 FILE *fp;
74 char *filename;
75 grammar *g;
76 int start;
77 char *ps1, *ps2;
78 node **n_ret;
79{
80 struct tok_state *tok = tok_setupf(fp, ps1, ps2);
81 int ret;
82
83 if (tok == NULL) {
84 fprintf(stderr, "no mem for tok_setupf\n");
85 return E_NOMEM;
86 }
87 ret = parsetok(tok, g, start, n_ret);
88 if (ret == E_TOKEN || ret == E_SYNTAX) {
89 char *p;
90 fprintf(stderr, "Parsing error: file %s, line %d:\n",
91 filename, tok->lineno);
Guido van Rossum56b07c81991-06-07 13:58:56 +000092 if (tok->buf == NULL)
93 fprintf(stderr, "(EOF)\n");
94 else {
95 *tok->inp = '\0';
96 if (tok->inp > tok->buf && tok->inp[-1] == '\n')
97 tok->inp[-1] = '\0';
98 fprintf(stderr, "%s\n", tok->buf);
99 for (p = tok->buf; p < tok->cur; p++) {
100 if (*p == '\t')
101 putc('\t', stderr);
102 else
103 putc(' ', stderr);
104 }
105 fprintf(stderr, "^\n");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000106 }
Guido van Rossum3f5da241990-12-20 15:06:42 +0000107 }
108 tok_free(tok);
109 return ret;
110}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000111
112
113/* Parse input coming from the given tokenizer structure.
114 Return error code. */
115
116static int
117parsetok(tok, g, start, n_ret)
118 struct tok_state *tok;
119 grammar *g;
120 int start;
121 node **n_ret;
122{
123 parser_state *ps;
124 int ret;
Guido van Rossumd8b1d371992-03-04 16:40:44 +0000125 int started = 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000126
127 if ((ps = newparser(g, start)) == NULL) {
128 fprintf(stderr, "no mem for new parser\n");
129 return E_NOMEM;
130 }
131
132 for (;;) {
133 char *a, *b;
134 int type;
135 int len;
136 char *str;
137
138 type = tok_get(tok, &a, &b);
139 if (type == ERRORTOKEN) {
140 ret = tok->done;
141 break;
142 }
Guido van Rossumd8b1d371992-03-04 16:40:44 +0000143 if (type == ENDMARKER && started) {
144 type = NEWLINE; /* Add an extra newline */
145 started = 0;
146 }
147 else
148 started = 1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000149 len = b - a;
150 str = NEW(char, len + 1);
151 if (str == NULL) {
152 fprintf(stderr, "no mem for next token\n");
153 ret = E_NOMEM;
154 break;
155 }
156 strncpy(str, a, len);
157 str[len] = '\0';
Guido van Rossum3f5da241990-12-20 15:06:42 +0000158 ret = addtoken(ps, (int)type, str, tok->lineno);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000159 if (ret != E_OK) {
Guido van Rossum840bcf11990-11-18 17:39:41 +0000160 if (ret == E_DONE) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000161 *n_ret = ps->p_tree;
Guido van Rossum840bcf11990-11-18 17:39:41 +0000162 ps->p_tree = NULL;
163 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000164 else if (tok->lineno <= 1 && tok->done == E_EOF)
165 ret = E_EOF;
166 break;
167 }
168 }
169
170 delparser(ps);
171 return ret;
172}