blob: a0bac20ec6b3042c03e27cdaaf780a262b274fb8 [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);
92 *tok->inp = '\0';
93 if (tok->inp > tok->buf && tok->inp[-1] == '\n')
94 tok->inp[-1] = '\0';
95 fprintf(stderr, "%s\n", tok->buf);
96 for (p = tok->buf; p < tok->cur; p++) {
97 if (*p == '\t')
98 putc('\t', stderr);
99 else
100 putc(' ', stderr);
101 }
102 fprintf(stderr, "^\n");
103 }
104 tok_free(tok);
105 return ret;
106}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000107
108
109/* Parse input coming from the given tokenizer structure.
110 Return error code. */
111
112static int
113parsetok(tok, g, start, n_ret)
114 struct tok_state *tok;
115 grammar *g;
116 int start;
117 node **n_ret;
118{
119 parser_state *ps;
120 int ret;
121
122 if ((ps = newparser(g, start)) == NULL) {
123 fprintf(stderr, "no mem for new parser\n");
124 return E_NOMEM;
125 }
126
127 for (;;) {
128 char *a, *b;
129 int type;
130 int len;
131 char *str;
132
133 type = tok_get(tok, &a, &b);
134 if (type == ERRORTOKEN) {
135 ret = tok->done;
136 break;
137 }
138 len = b - a;
139 str = NEW(char, len + 1);
140 if (str == NULL) {
141 fprintf(stderr, "no mem for next token\n");
142 ret = E_NOMEM;
143 break;
144 }
145 strncpy(str, a, len);
146 str[len] = '\0';
Guido van Rossum3f5da241990-12-20 15:06:42 +0000147 ret = addtoken(ps, (int)type, str, tok->lineno);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000148 if (ret != E_OK) {
Guido van Rossum840bcf11990-11-18 17:39:41 +0000149 if (ret == E_DONE) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000150 *n_ret = ps->p_tree;
Guido van Rossum840bcf11990-11-18 17:39:41 +0000151 ps->p_tree = NULL;
152 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000153 else if (tok->lineno <= 1 && tok->done == E_EOF)
154 ret = E_EOF;
155 break;
156 }
157 }
158
159 delparser(ps);
160 return ret;
161}