blob: 386b82fea6177115a9daaa70e7f968f6df5ed99a [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* Parser-tokenizer link implementation */
3
Guido van Rossum3f5da241990-12-20 15:06:42 +00004#include "pgenheaders.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005#include "tokenizer.h"
6#include "node.h"
7#include "grammar.h"
8#include "parser.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +00009#include "parsetok.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010#include "errcode.h"
11
Guido van Rossum6135df61998-04-10 19:35:06 +000012int Py_TabcheckFlag;
13
Guido van Rossum3f5da241990-12-20 15:06:42 +000014
15/* Forward */
Tim Petersfe2127d2001-07-16 05:37:24 +000016static node *parsetok(struct tok_state *, grammar *, int, perrdetail *, int);
Guido van Rossum3f5da241990-12-20 15:06:42 +000017
18/* Parse input coming from a string. Return error code, print some errors. */
Guido van Rossumbd0389d1994-08-29 12:25:45 +000019node *
Thomas Wouters23c9e002000-07-22 19:20:54 +000020PyParser_ParseString(char *s, grammar *g, int start, perrdetail *err_ret)
Guido van Rossum3f5da241990-12-20 15:06:42 +000021{
Tim Petersfe2127d2001-07-16 05:37:24 +000022 return PyParser_ParseStringFlags(s, g, start, err_ret, 0);
23}
24
25node *
26PyParser_ParseStringFlags(char *s, grammar *g, int start,
27 perrdetail *err_ret, int flags)
28{
Guido van Rossumbd0389d1994-08-29 12:25:45 +000029 struct tok_state *tok;
30
31 err_ret->error = E_OK;
32 err_ret->filename = NULL;
33 err_ret->lineno = 0;
34 err_ret->offset = 0;
35 err_ret->text = NULL;
Barry Warsaw38aa14a2000-08-18 05:04:08 +000036 err_ret->token = -1;
37 err_ret->expected = -1;
Guido van Rossumbd0389d1994-08-29 12:25:45 +000038
Guido van Rossum86bea461997-04-29 21:03:06 +000039 if ((tok = PyTokenizer_FromString(s)) == NULL) {
Guido van Rossumbd0389d1994-08-29 12:25:45 +000040 err_ret->error = E_NOMEM;
41 return NULL;
Guido van Rossum3f5da241990-12-20 15:06:42 +000042 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +000043
Guido van Rossum89ce4541998-12-21 18:32:40 +000044 if (Py_TabcheckFlag || Py_VerboseFlag) {
45 tok->filename = "<string>";
46 tok->altwarning = (tok->filename != NULL);
47 if (Py_TabcheckFlag >= 2)
48 tok->alterror++;
49 }
50
Tim Petersfe2127d2001-07-16 05:37:24 +000051 return parsetok(tok, g, start, err_ret, flags);
Guido van Rossum3f5da241990-12-20 15:06:42 +000052}
53
54
55/* Parse input coming from a file. Return error code, print some errors. */
56
Guido van Rossumbd0389d1994-08-29 12:25:45 +000057node *
Thomas Wouters23c9e002000-07-22 19:20:54 +000058PyParser_ParseFile(FILE *fp, char *filename, grammar *g, int start,
59 char *ps1, char *ps2, perrdetail *err_ret)
Guido van Rossum3f5da241990-12-20 15:06:42 +000060{
Tim Petersfe2127d2001-07-16 05:37:24 +000061 return PyParser_ParseFileFlags(fp, filename, g, start, ps1, ps2,
62 err_ret, 0);
63}
64
65node *
66PyParser_ParseFileFlags(FILE *fp, char *filename, grammar *g, int start,
67 char *ps1, char *ps2, perrdetail *err_ret, int flags)
68{
Guido van Rossumbd0389d1994-08-29 12:25:45 +000069 struct tok_state *tok;
70
71 err_ret->error = E_OK;
72 err_ret->filename = filename;
73 err_ret->lineno = 0;
74 err_ret->offset = 0;
75 err_ret->text = NULL;
76
Guido van Rossum86bea461997-04-29 21:03:06 +000077 if ((tok = PyTokenizer_FromFile(fp, ps1, ps2)) == NULL) {
Guido van Rossumbd0389d1994-08-29 12:25:45 +000078 err_ret->error = E_NOMEM;
79 return NULL;
Guido van Rossum3f5da241990-12-20 15:06:42 +000080 }
Guido van Rossum6135df61998-04-10 19:35:06 +000081 if (Py_TabcheckFlag || Py_VerboseFlag) {
82 tok->filename = filename;
83 tok->altwarning = (filename != NULL);
84 if (Py_TabcheckFlag >= 2)
85 tok->alterror++;
86 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +000087
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000088
Tim Petersfe2127d2001-07-16 05:37:24 +000089 return parsetok(tok, g, start, err_ret, flags);
Guido van Rossumbd0389d1994-08-29 12:25:45 +000090}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000091
92/* Parse input coming from the given tokenizer structure.
93 Return error code. */
94
Guido van Rossumda62ecc2001-07-17 16:53:11 +000095static char yield_msg[] =
96"%s:%d: Warning: 'yield' will become a reserved keyword in the future\n";
97
Guido van Rossumbd0389d1994-08-29 12:25:45 +000098static node *
Tim Petersfe2127d2001-07-16 05:37:24 +000099parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret,
100 int flags)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000101{
102 parser_state *ps;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000103 node *n;
Guido van Rossumd8b1d371992-03-04 16:40:44 +0000104 int started = 0;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000105
Guido van Rossum86bea461997-04-29 21:03:06 +0000106 if ((ps = PyParser_New(g, start)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000107 fprintf(stderr, "no mem for new parser\n");
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000108 err_ret->error = E_NOMEM;
109 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000110 }
Tim Petersfe2127d2001-07-16 05:37:24 +0000111 if (flags & PyPARSE_YIELD_IS_KEYWORD)
112 ps->p_generators = 1;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000113
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000114 for (;;) {
115 char *a, *b;
116 int type;
Guido van Rossum6da34342000-06-28 22:00:02 +0000117 size_t len;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000118 char *str;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000119
Guido van Rossum86bea461997-04-29 21:03:06 +0000120 type = PyTokenizer_Get(tok, &a, &b);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000121 if (type == ERRORTOKEN) {
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000122 err_ret->error = tok->done;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000123 break;
124 }
Guido van Rossumd8b1d371992-03-04 16:40:44 +0000125 if (type == ENDMARKER && started) {
126 type = NEWLINE; /* Add an extra newline */
127 started = 0;
128 }
129 else
130 started = 1;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000131 len = b - a; /* XXX this may compute NULL - NULL */
Guido van Rossum86bea461997-04-29 21:03:06 +0000132 str = PyMem_NEW(char, len + 1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000133 if (str == NULL) {
134 fprintf(stderr, "no mem for next token\n");
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000135 err_ret->error = E_NOMEM;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000136 break;
137 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000138 if (len > 0)
139 strncpy(str, a, len);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000140 str[len] = '\0';
Guido van Rossumda62ecc2001-07-17 16:53:11 +0000141
142 /* Warn about yield as NAME */
143 if (type == NAME && !ps->p_generators &&
144 len == 5 && str[0] == 'y' && strcmp(str, "yield") == 0)
145 PySys_WriteStderr(yield_msg,
146 err_ret->filename==NULL ?
147 "<string>" : err_ret->filename,
148 tok->lineno);
149
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000150 if ((err_ret->error =
Fred Drake85f36392000-07-11 17:53:00 +0000151 PyParser_AddToken(ps, (int)type, str, tok->lineno,
152 &(err_ret->expected))) != E_OK) {
Guido van Rossumff0ec521997-07-27 01:52:50 +0000153 if (err_ret->error != E_DONE)
154 PyMem_DEL(str);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000155 break;
Guido van Rossumff0ec521997-07-27 01:52:50 +0000156 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000157 }
158
159 if (err_ret->error == E_DONE) {
160 n = ps->p_tree;
161 ps->p_tree = NULL;
162 }
163 else
164 n = NULL;
165
Guido van Rossum86bea461997-04-29 21:03:06 +0000166 PyParser_Delete(ps);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000167
168 if (n == NULL) {
169 if (tok->lineno <= 1 && tok->done == E_EOF)
170 err_ret->error = E_EOF;
171 err_ret->lineno = tok->lineno;
172 err_ret->offset = tok->cur - tok->buf;
173 if (tok->buf != NULL) {
Guido van Rossum6da34342000-06-28 22:00:02 +0000174 size_t len = tok->inp - tok->buf;
Guido van Rossumb18618d2000-05-03 23:44:39 +0000175 err_ret->text = PyMem_NEW(char, len + 1);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000176 if (err_ret->text != NULL) {
Guido van Rossumec498271995-01-20 16:59:12 +0000177 if (len > 0)
178 strncpy(err_ret->text, tok->buf, len);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000179 err_ret->text[len] = '\0';
180 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000181 }
182 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000183
Guido van Rossum86bea461997-04-29 21:03:06 +0000184 PyTokenizer_Free(tok);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000185
186 return n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000187}