blob: 6453b6afe55a133510a7e6add04cd695b11f66e3 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossumb9f8d6e1995-01-04 19:08:09 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossumf70e43a1991-02-19 12:39:46 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000029
30******************************************************************/
31
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000032/* Parser-tokenizer link implementation */
33
Guido van Rossum3f5da241990-12-20 15:06:42 +000034#include "pgenheaders.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000035#include "tokenizer.h"
36#include "node.h"
37#include "grammar.h"
38#include "parser.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +000039#include "parsetok.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000040#include "errcode.h"
41
Guido van Rossum6135df61998-04-10 19:35:06 +000042int Py_TabcheckFlag;
43
Guido van Rossum3f5da241990-12-20 15:06:42 +000044
45/* Forward */
Guido van Rossum86bea461997-04-29 21:03:06 +000046static node *parsetok Py_PROTO((struct tok_state *, grammar *, int,
Guido van Rossumbd0389d1994-08-29 12:25:45 +000047 perrdetail *));
Guido van Rossum3f5da241990-12-20 15:06:42 +000048
49/* Parse input coming from a string. Return error code, print some errors. */
50
Guido van Rossumbd0389d1994-08-29 12:25:45 +000051node *
Guido van Rossum86bea461997-04-29 21:03:06 +000052PyParser_ParseString(s, g, start, err_ret)
Guido van Rossum3f5da241990-12-20 15:06:42 +000053 char *s;
54 grammar *g;
55 int start;
Guido van Rossumbd0389d1994-08-29 12:25:45 +000056 perrdetail *err_ret;
Guido van Rossum3f5da241990-12-20 15:06:42 +000057{
Guido van Rossumbd0389d1994-08-29 12:25:45 +000058 struct tok_state *tok;
59
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;
65
Guido van Rossum86bea461997-04-29 21:03:06 +000066 if ((tok = PyTokenizer_FromString(s)) == NULL) {
Guido van Rossumbd0389d1994-08-29 12:25:45 +000067 err_ret->error = E_NOMEM;
68 return NULL;
Guido van Rossum3f5da241990-12-20 15:06:42 +000069 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +000070
71 return parsetok(tok, g, start, err_ret);
Guido van Rossum3f5da241990-12-20 15:06:42 +000072}
73
74
75/* Parse input coming from a file. Return error code, print some errors. */
76
Guido van Rossumbd0389d1994-08-29 12:25:45 +000077node *
Guido van Rossum86bea461997-04-29 21:03:06 +000078PyParser_ParseFile(fp, filename, g, start, ps1, ps2, err_ret)
Guido van Rossum3f5da241990-12-20 15:06:42 +000079 FILE *fp;
80 char *filename;
81 grammar *g;
82 int start;
83 char *ps1, *ps2;
Guido van Rossumbd0389d1994-08-29 12:25:45 +000084 perrdetail *err_ret;
Guido van Rossum3f5da241990-12-20 15:06:42 +000085{
Guido van Rossumbd0389d1994-08-29 12:25:45 +000086 struct tok_state *tok;
87
88 err_ret->error = E_OK;
89 err_ret->filename = filename;
90 err_ret->lineno = 0;
91 err_ret->offset = 0;
92 err_ret->text = NULL;
93
Guido van Rossum86bea461997-04-29 21:03:06 +000094 if ((tok = PyTokenizer_FromFile(fp, ps1, ps2)) == NULL) {
Guido van Rossumbd0389d1994-08-29 12:25:45 +000095 err_ret->error = E_NOMEM;
96 return NULL;
Guido van Rossum3f5da241990-12-20 15:06:42 +000097 }
Guido van Rossum6135df61998-04-10 19:35:06 +000098 if (Py_TabcheckFlag || Py_VerboseFlag) {
99 tok->filename = filename;
100 tok->altwarning = (filename != NULL);
101 if (Py_TabcheckFlag >= 2)
102 tok->alterror++;
103 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000104
Guido van Rossum91ece421992-03-25 22:32:00 +0000105#ifdef macintosh
106 {
107 int tabsize = guesstabsize(filename);
108 if (tabsize > 0)
109 tok->tabsize = tabsize;
110 }
111#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000112
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000113 return parsetok(tok, g, start, err_ret);
114}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000115
116/* Parse input coming from the given tokenizer structure.
117 Return error code. */
118
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000119static node *
120parsetok(tok, g, start, err_ret)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000121 struct tok_state *tok;
122 grammar *g;
123 int start;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000124 perrdetail *err_ret;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000125{
126 parser_state *ps;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000127 node *n;
Guido van Rossumd8b1d371992-03-04 16:40:44 +0000128 int started = 0;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000129
Guido van Rossum86bea461997-04-29 21:03:06 +0000130 if ((ps = PyParser_New(g, start)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000131 fprintf(stderr, "no mem for new parser\n");
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000132 err_ret->error = E_NOMEM;
133 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000134 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000135
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000136 for (;;) {
137 char *a, *b;
138 int type;
139 int len;
140 char *str;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000141
Guido van Rossum86bea461997-04-29 21:03:06 +0000142 type = PyTokenizer_Get(tok, &a, &b);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000143 if (type == ERRORTOKEN) {
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000144 err_ret->error = tok->done;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000145 break;
146 }
Guido van Rossumd8b1d371992-03-04 16:40:44 +0000147 if (type == ENDMARKER && started) {
148 type = NEWLINE; /* Add an extra newline */
149 started = 0;
150 }
151 else
152 started = 1;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000153 len = b - a; /* XXX this may compute NULL - NULL */
Guido van Rossum86bea461997-04-29 21:03:06 +0000154 str = PyMem_NEW(char, len + 1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000155 if (str == NULL) {
156 fprintf(stderr, "no mem for next token\n");
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000157 err_ret->error = E_NOMEM;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000158 break;
159 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000160 if (len > 0)
161 strncpy(str, a, len);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000162 str[len] = '\0';
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000163 if ((err_ret->error =
Guido van Rossum86bea461997-04-29 21:03:06 +0000164 PyParser_AddToken(ps, (int)type, str,
Guido van Rossumff0ec521997-07-27 01:52:50 +0000165 tok->lineno)) != E_OK) {
166 if (err_ret->error != E_DONE)
167 PyMem_DEL(str);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000168 break;
Guido van Rossumff0ec521997-07-27 01:52:50 +0000169 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000170 }
171
172 if (err_ret->error == E_DONE) {
173 n = ps->p_tree;
174 ps->p_tree = NULL;
175 }
176 else
177 n = NULL;
178
Guido van Rossum86bea461997-04-29 21:03:06 +0000179 PyParser_Delete(ps);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000180
181 if (n == NULL) {
182 if (tok->lineno <= 1 && tok->done == E_EOF)
183 err_ret->error = E_EOF;
184 err_ret->lineno = tok->lineno;
185 err_ret->offset = tok->cur - tok->buf;
186 if (tok->buf != NULL) {
187 int len = tok->inp - tok->buf;
188 err_ret->text = malloc(len + 1);
189 if (err_ret->text != NULL) {
Guido van Rossumec498271995-01-20 16:59:12 +0000190 if (len > 0)
191 strncpy(err_ret->text, tok->buf, len);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000192 err_ret->text[len] = '\0';
193 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000194 }
195 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000196
Guido van Rossum86bea461997-04-29 21:03:06 +0000197 PyTokenizer_Free(tok);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000198
199 return n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000200}