2 /* Parser-tokenizer link implementation */
4 #include "pgenheaders.h"
17 static node
*parsetok(struct tok_state
*, grammar
*, int, perrdetail
*, int);
18 static void initerr(perrdetail
*err_ret
, const char* filename
);
20 /* Parse input coming from a string. Return error code, print some errors. */
22 PyParser_ParseString(const char *s
, grammar
*g
, int start
, perrdetail
*err_ret
)
24 return PyParser_ParseStringFlags(s
, g
, start
, err_ret
, 0);
28 PyParser_ParseStringFlags(const char *s
, grammar
*g
, int start
,
29 perrdetail
*err_ret
, int flags
)
31 return PyParser_ParseStringFlagsFilename(s
, NULL
,
32 g
, start
, err_ret
, 0);
36 PyParser_ParseStringFlagsFilename(const char *s
, const char *filename
,
37 grammar
*g
, int start
,
38 perrdetail
*err_ret
, int flags
)
40 struct tok_state
*tok
;
42 initerr(err_ret
, filename
);
44 if ((tok
= PyTokenizer_FromString(s
)) == NULL
) {
45 err_ret
->error
= E_NOMEM
;
49 tok
->filename
= filename
? filename
: "<string>";
50 if (Py_TabcheckFlag
|| Py_VerboseFlag
) {
51 tok
->altwarning
= (tok
->filename
!= NULL
);
52 if (Py_TabcheckFlag
>= 2)
56 return parsetok(tok
, g
, start
, err_ret
, flags
);
60 /* Parse input coming from a file. Return error code, print some errors. */
63 PyParser_ParseFile(FILE *fp
, const char *filename
, grammar
*g
, int start
,
64 char *ps1
, char *ps2
, perrdetail
*err_ret
)
66 return PyParser_ParseFileFlags(fp
, filename
, g
, start
, ps1
, ps2
,
71 PyParser_ParseFileFlags(FILE *fp
, const char *filename
, grammar
*g
, int start
,
72 char *ps1
, char *ps2
, perrdetail
*err_ret
, int flags
)
74 struct tok_state
*tok
;
76 initerr(err_ret
, filename
);
78 if ((tok
= PyTokenizer_FromFile(fp
, ps1
, ps2
)) == NULL
) {
79 err_ret
->error
= E_NOMEM
;
82 tok
->filename
= filename
;
83 if (Py_TabcheckFlag
|| Py_VerboseFlag
) {
84 tok
->altwarning
= (filename
!= NULL
);
85 if (Py_TabcheckFlag
>= 2)
90 return parsetok(tok
, g
, start
, err_ret
, flags
);
93 /* Parse input coming from the given tokenizer structure.
96 #if 0 /* future keyword */
97 static char yield_msg
[] =
98 "%s:%d: Warning: 'yield' will become a reserved keyword in the future\n";
102 parsetok(struct tok_state
*tok
, grammar
*g
, int start
, perrdetail
*err_ret
,
109 if ((ps
= PyParser_New(g
, start
)) == NULL
) {
110 fprintf(stderr
, "no mem for new parser\n");
111 err_ret
->error
= E_NOMEM
;
114 #if 0 /* future keyword */
115 if (flags
& PyPARSE_YIELD_IS_KEYWORD
)
116 ps
->p_generators
= 1;
125 type
= PyTokenizer_Get(tok
, &a
, &b
);
126 if (type
== ERRORTOKEN
) {
127 err_ret
->error
= tok
->done
;
130 if (type
== ENDMARKER
&& started
) {
131 type
= NEWLINE
; /* Add an extra newline */
133 /* Add the right number of dedent tokens,
134 except if a certain flag is given --
135 codeop.py uses this. */
137 !(flags
& PyPARSE_DONT_IMPLY_DEDENT
))
139 tok
->pendin
= -tok
->indent
;
145 len
= b
- a
; /* XXX this may compute NULL - NULL */
146 str
= (char *) PyObject_MALLOC(len
+ 1);
148 fprintf(stderr
, "no mem for next token\n");
149 err_ret
->error
= E_NOMEM
;
153 strncpy(str
, a
, len
);
156 #if 0 /* future keyword */
157 /* Warn about yield as NAME */
158 if (type
== NAME
&& !ps
->p_generators
&&
159 len
== 5 && str
[0] == 'y' && strcmp(str
, "yield") == 0)
160 PySys_WriteStderr(yield_msg
,
161 err_ret
->filename
==NULL
?
162 "<string>" : err_ret
->filename
,
166 if ((err_ret
->error
=
167 PyParser_AddToken(ps
, (int)type
, str
, tok
->lineno
,
168 &(err_ret
->expected
))) != E_OK
) {
169 if (err_ret
->error
!= E_DONE
)
175 if (err_ret
->error
== E_DONE
) {
185 if (tok
->lineno
<= 1 && tok
->done
== E_EOF
)
186 err_ret
->error
= E_EOF
;
187 err_ret
->lineno
= tok
->lineno
;
188 err_ret
->offset
= tok
->cur
- tok
->buf
;
189 if (tok
->buf
!= NULL
) {
190 size_t len
= tok
->inp
- tok
->buf
;
191 err_ret
->text
= (char *) PyObject_MALLOC(len
+ 1);
192 if (err_ret
->text
!= NULL
) {
194 strncpy(err_ret
->text
, tok
->buf
, len
);
195 err_ret
->text
[len
] = '\0';
198 } else if (tok
->encoding
!= NULL
) {
199 node
* r
= PyNode_New(encoding_decl
);
200 r
->n_str
= tok
->encoding
;
203 tok
->encoding
= NULL
;
207 PyTokenizer_Free(tok
);
213 initerr(perrdetail
*err_ret
, const char* filename
)
215 err_ret
->error
= E_OK
;
216 err_ret
->filename
= filename
;
219 err_ret
->text
= NULL
;
221 err_ret
->expected
= -1;