2 /* Parser-tokenizer link implementation */
4 #include "pgenheaders.h"
16 static node
*parsetok(struct tok_state
*, grammar
*, int, perrdetail
*, int);
17 static void initerr(perrdetail
*err_ret
, char* filename
);
19 /* Parse input coming from a string. Return error code, print some errors. */
21 PyParser_ParseString(char *s
, grammar
*g
, int start
, perrdetail
*err_ret
)
23 return PyParser_ParseStringFlags(s
, g
, start
, err_ret
, 0);
27 PyParser_ParseStringFlags(char *s
, grammar
*g
, int start
,
28 perrdetail
*err_ret
, int flags
)
30 struct tok_state
*tok
;
32 initerr(err_ret
, NULL
);
34 if ((tok
= PyTokenizer_FromString(s
)) == NULL
) {
35 err_ret
->error
= E_NOMEM
;
39 if (Py_TabcheckFlag
|| Py_VerboseFlag
) {
40 tok
->filename
= "<string>";
41 tok
->altwarning
= (tok
->filename
!= NULL
);
42 if (Py_TabcheckFlag
>= 2)
46 return parsetok(tok
, g
, start
, err_ret
, flags
);
50 /* Parse input coming from a file. Return error code, print some errors. */
53 PyParser_ParseFile(FILE *fp
, char *filename
, grammar
*g
, int start
,
54 char *ps1
, char *ps2
, perrdetail
*err_ret
)
56 return PyParser_ParseFileFlags(fp
, filename
, g
, start
, ps1
, ps2
,
61 PyParser_ParseFileFlags(FILE *fp
, char *filename
, grammar
*g
, int start
,
62 char *ps1
, char *ps2
, perrdetail
*err_ret
, int flags
)
64 struct tok_state
*tok
;
66 initerr(err_ret
, filename
);
68 if ((tok
= PyTokenizer_FromFile(fp
, ps1
, ps2
)) == NULL
) {
69 err_ret
->error
= E_NOMEM
;
72 if (Py_TabcheckFlag
|| Py_VerboseFlag
) {
73 tok
->filename
= filename
;
74 tok
->altwarning
= (filename
!= NULL
);
75 if (Py_TabcheckFlag
>= 2)
80 return parsetok(tok
, g
, start
, err_ret
, flags
);
83 /* Parse input coming from the given tokenizer structure.
86 static char yield_msg
[] =
87 "%s:%d: Warning: 'yield' will become a reserved keyword in the future\n";
90 parsetok(struct tok_state
*tok
, grammar
*g
, int start
, perrdetail
*err_ret
,
97 if ((ps
= PyParser_New(g
, start
)) == NULL
) {
98 fprintf(stderr
, "no mem for new parser\n");
99 err_ret
->error
= E_NOMEM
;
102 if (flags
& PyPARSE_YIELD_IS_KEYWORD
)
103 ps
->p_generators
= 1;
111 type
= PyTokenizer_Get(tok
, &a
, &b
);
112 if (type
== ERRORTOKEN
) {
113 err_ret
->error
= tok
->done
;
116 if (type
== ENDMARKER
&& started
) {
117 type
= NEWLINE
; /* Add an extra newline */
122 len
= b
- a
; /* XXX this may compute NULL - NULL */
123 str
= PyMem_NEW(char, len
+ 1);
125 fprintf(stderr
, "no mem for next token\n");
126 err_ret
->error
= E_NOMEM
;
130 strncpy(str
, a
, len
);
133 /* Warn about yield as NAME */
134 if (type
== NAME
&& !ps
->p_generators
&&
135 len
== 5 && str
[0] == 'y' && strcmp(str
, "yield") == 0)
136 PySys_WriteStderr(yield_msg
,
137 err_ret
->filename
==NULL
?
138 "<string>" : err_ret
->filename
,
141 if ((err_ret
->error
=
142 PyParser_AddToken(ps
, (int)type
, str
, tok
->lineno
,
143 &(err_ret
->expected
))) != E_OK
) {
144 if (err_ret
->error
!= E_DONE
)
150 if (err_ret
->error
== E_DONE
) {
160 if (tok
->lineno
<= 1 && tok
->done
== E_EOF
)
161 err_ret
->error
= E_EOF
;
162 err_ret
->lineno
= tok
->lineno
;
163 err_ret
->offset
= tok
->cur
- tok
->buf
;
164 if (tok
->buf
!= NULL
) {
165 size_t len
= tok
->inp
- tok
->buf
;
166 err_ret
->text
= PyMem_NEW(char, len
+ 1);
167 if (err_ret
->text
!= NULL
) {
169 strncpy(err_ret
->text
, tok
->buf
, len
);
170 err_ret
->text
[len
] = '\0';
175 PyTokenizer_Free(tok
);
181 initerr(perrdetail
*err_ret
, char* filename
)
183 err_ret
->error
= E_OK
;
184 err_ret
->filename
= filename
;
187 err_ret
->text
= NULL
;
189 err_ret
->expected
= -1;