Added 'list_only' option (and modified 'run()' to respect it).
[python/dscho.git] / Parser / parsetok.c
blob5b0d99050fcc709994e98d7e9b91bf0971d76790
1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
15 permission.
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
32 /* Parser-tokenizer link implementation */
34 #include "pgenheaders.h"
35 #include "tokenizer.h"
36 #include "node.h"
37 #include "grammar.h"
38 #include "parser.h"
39 #include "parsetok.h"
40 #include "errcode.h"
42 int Py_TabcheckFlag;
45 /* Forward */
46 static node *parsetok Py_PROTO((struct tok_state *, grammar *, int,
47 perrdetail *));
49 /* Parse input coming from a string. Return error code, print some errors. */
51 node *
52 PyParser_ParseString(s, g, start, err_ret)
53 char *s;
54 grammar *g;
55 int start;
56 perrdetail *err_ret;
58 struct tok_state *tok;
60 err_ret->error = E_OK;
61 err_ret->filename = NULL;
62 err_ret->lineno = 0;
63 err_ret->offset = 0;
64 err_ret->text = NULL;
66 if ((tok = PyTokenizer_FromString(s)) == NULL) {
67 err_ret->error = E_NOMEM;
68 return NULL;
71 if (Py_TabcheckFlag || Py_VerboseFlag) {
72 tok->filename = "<string>";
73 tok->altwarning = (tok->filename != NULL);
74 if (Py_TabcheckFlag >= 2)
75 tok->alterror++;
78 return parsetok(tok, g, start, err_ret);
82 /* Parse input coming from a file. Return error code, print some errors. */
84 node *
85 PyParser_ParseFile(fp, filename, g, start, ps1, ps2, err_ret)
86 FILE *fp;
87 char *filename;
88 grammar *g;
89 int start;
90 char *ps1, *ps2;
91 perrdetail *err_ret;
93 struct tok_state *tok;
95 err_ret->error = E_OK;
96 err_ret->filename = filename;
97 err_ret->lineno = 0;
98 err_ret->offset = 0;
99 err_ret->text = NULL;
101 if ((tok = PyTokenizer_FromFile(fp, ps1, ps2)) == NULL) {
102 err_ret->error = E_NOMEM;
103 return NULL;
105 if (Py_TabcheckFlag || Py_VerboseFlag) {
106 tok->filename = filename;
107 tok->altwarning = (filename != NULL);
108 if (Py_TabcheckFlag >= 2)
109 tok->alterror++;
112 #ifdef macintosh
114 int tabsize = guesstabsize(filename);
115 if (tabsize > 0)
116 tok->tabsize = tabsize;
118 #endif
120 return parsetok(tok, g, start, err_ret);
123 /* Parse input coming from the given tokenizer structure.
124 Return error code. */
126 static node *
127 parsetok(tok, g, start, err_ret)
128 struct tok_state *tok;
129 grammar *g;
130 int start;
131 perrdetail *err_ret;
133 parser_state *ps;
134 node *n;
135 int started = 0;
137 if ((ps = PyParser_New(g, start)) == NULL) {
138 fprintf(stderr, "no mem for new parser\n");
139 err_ret->error = E_NOMEM;
140 return NULL;
143 for (;;) {
144 char *a, *b;
145 int type;
146 int len;
147 char *str;
149 type = PyTokenizer_Get(tok, &a, &b);
150 if (type == ERRORTOKEN) {
151 err_ret->error = tok->done;
152 break;
154 if (type == ENDMARKER && started) {
155 type = NEWLINE; /* Add an extra newline */
156 started = 0;
158 else
159 started = 1;
160 len = b - a; /* XXX this may compute NULL - NULL */
161 str = PyMem_NEW(char, len + 1);
162 if (str == NULL) {
163 fprintf(stderr, "no mem for next token\n");
164 err_ret->error = E_NOMEM;
165 break;
167 if (len > 0)
168 strncpy(str, a, len);
169 str[len] = '\0';
170 if ((err_ret->error =
171 PyParser_AddToken(ps, (int)type, str,
172 tok->lineno)) != E_OK) {
173 if (err_ret->error != E_DONE)
174 PyMem_DEL(str);
175 break;
179 if (err_ret->error == E_DONE) {
180 n = ps->p_tree;
181 ps->p_tree = NULL;
183 else
184 n = NULL;
186 PyParser_Delete(ps);
188 if (n == NULL) {
189 if (tok->lineno <= 1 && tok->done == E_EOF)
190 err_ret->error = E_EOF;
191 err_ret->lineno = tok->lineno;
192 err_ret->offset = tok->cur - tok->buf;
193 if (tok->buf != NULL) {
194 int len = tok->inp - tok->buf;
195 err_ret->text = malloc(len + 1);
196 if (err_ret->text != NULL) {
197 if (len > 0)
198 strncpy(err_ret->text, tok->buf, len);
199 err_ret->text[len] = '\0';
204 PyTokenizer_Free(tok);
206 return n;