blob: 31c23853f95477790199e5e2ba14bbbfab7bd3e9 [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;
125
126 if ((ps = newparser(g, start)) == NULL) {
127 fprintf(stderr, "no mem for new parser\n");
128 return E_NOMEM;
129 }
130
131 for (;;) {
132 char *a, *b;
133 int type;
134 int len;
135 char *str;
136
137 type = tok_get(tok, &a, &b);
138 if (type == ERRORTOKEN) {
139 ret = tok->done;
140 break;
141 }
142 len = b - a;
143 str = NEW(char, len + 1);
144 if (str == NULL) {
145 fprintf(stderr, "no mem for next token\n");
146 ret = E_NOMEM;
147 break;
148 }
149 strncpy(str, a, len);
150 str[len] = '\0';
Guido van Rossum3f5da241990-12-20 15:06:42 +0000151 ret = addtoken(ps, (int)type, str, tok->lineno);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000152 if (ret != E_OK) {
Guido van Rossum840bcf11990-11-18 17:39:41 +0000153 if (ret == E_DONE) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000154 *n_ret = ps->p_tree;
Guido van Rossum840bcf11990-11-18 17:39:41 +0000155 ps->p_tree = NULL;
156 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000157 else if (tok->lineno <= 1 && tok->done == E_EOF)
158 ret = E_EOF;
159 break;
160 }
161 }
162
163 delparser(ps);
164 return ret;
165}