blob: 6017e5f7f8621a689a0d853a75cee4fdf6f91a11 [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 Rossumbd0389d1994-08-29 12:25:45 +000095static node *
Tim Petersfe2127d2001-07-16 05:37:24 +000096parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret,
97 int flags)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000098{
99 parser_state *ps;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000100 node *n;
Guido van Rossumd8b1d371992-03-04 16:40:44 +0000101 int started = 0;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000102
Guido van Rossum86bea461997-04-29 21:03:06 +0000103 if ((ps = PyParser_New(g, start)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000104 fprintf(stderr, "no mem for new parser\n");
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000105 err_ret->error = E_NOMEM;
106 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000107 }
Tim Petersfe2127d2001-07-16 05:37:24 +0000108 if (flags & PyPARSE_YIELD_IS_KEYWORD)
109 ps->p_generators = 1;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000110
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000111 for (;;) {
112 char *a, *b;
113 int type;
Guido van Rossum6da34342000-06-28 22:00:02 +0000114 size_t len;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000115 char *str;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000116
Guido van Rossum86bea461997-04-29 21:03:06 +0000117 type = PyTokenizer_Get(tok, &a, &b);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000118 if (type == ERRORTOKEN) {
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000119 err_ret->error = tok->done;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000120 break;
121 }
Guido van Rossumd8b1d371992-03-04 16:40:44 +0000122 if (type == ENDMARKER && started) {
123 type = NEWLINE; /* Add an extra newline */
124 started = 0;
125 }
126 else
127 started = 1;
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000128 len = b - a; /* XXX this may compute NULL - NULL */
Guido van Rossum86bea461997-04-29 21:03:06 +0000129 str = PyMem_NEW(char, len + 1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000130 if (str == NULL) {
131 fprintf(stderr, "no mem for next token\n");
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000132 err_ret->error = E_NOMEM;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000133 break;
134 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000135 if (len > 0)
136 strncpy(str, a, len);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000137 str[len] = '\0';
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000138 if ((err_ret->error =
Fred Drake85f36392000-07-11 17:53:00 +0000139 PyParser_AddToken(ps, (int)type, str, tok->lineno,
140 &(err_ret->expected))) != E_OK) {
Guido van Rossumff0ec521997-07-27 01:52:50 +0000141 if (err_ret->error != E_DONE)
142 PyMem_DEL(str);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000143 break;
Guido van Rossumff0ec521997-07-27 01:52:50 +0000144 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000145 }
146
147 if (err_ret->error == E_DONE) {
148 n = ps->p_tree;
149 ps->p_tree = NULL;
150 }
151 else
152 n = NULL;
153
Guido van Rossum86bea461997-04-29 21:03:06 +0000154 PyParser_Delete(ps);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000155
156 if (n == NULL) {
157 if (tok->lineno <= 1 && tok->done == E_EOF)
158 err_ret->error = E_EOF;
159 err_ret->lineno = tok->lineno;
160 err_ret->offset = tok->cur - tok->buf;
161 if (tok->buf != NULL) {
Guido van Rossum6da34342000-06-28 22:00:02 +0000162 size_t len = tok->inp - tok->buf;
Guido van Rossumb18618d2000-05-03 23:44:39 +0000163 err_ret->text = PyMem_NEW(char, len + 1);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000164 if (err_ret->text != NULL) {
Guido van Rossumec498271995-01-20 16:59:12 +0000165 if (len > 0)
166 strncpy(err_ret->text, tok->buf, len);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000167 err_ret->text[len] = '\0';
168 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000169 }
170 }
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000171
Guido van Rossum86bea461997-04-29 21:03:06 +0000172 PyTokenizer_Free(tok);
Guido van Rossumbd0389d1994-08-29 12:25:45 +0000173
174 return n;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000175}