8000 Python 3.4 parser · go-python/gpython@41a1540 · GitHub
[go: up one dir, main page]

Skip to content

Commit 41a1540

Browse files
committed
Python 3.4 parser
1 parent bcab40c commit 41a1540

File tree

1 file changed

+308
-0
lines changed

1 file changed

+308
-0
lines changed

parser/grammar.y

Lines changed: 308 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,308 @@
1+
%{
2+
3+
package parser
4+
5+
// Grammar for Python
6+
7+
import (
8+
"github.com/ncw/gpython/py"
9+
)
10+
11+
%}
12+
13+
%union {
14+
str string
15+
obj py.Object
16+
}
17+
18+
%token NEWLINE
19+
%token ENDMARKER
20+
%token <str> NAME
21+
%token INDENT
22+
%token DEDENT
23+
%token <str> STRING
24+
%token <str> NUMBER
25+
26+
%token PLINGEQ // !=
27+
%token PERCEQ // %=
28+
%token ANDEQ // &=
29+
%token STARSTAR // **
30+
%token STARSTAREQ // **=
31+
%token STAREQ // *=
32+
%token PLUSEQ // +=
33+
%token MINUSEQ // -=
34+
%token MINUSGT // ->
35+
%token ELIPSIS // ...
36+
%token DIVDIV // //
37+
%token DIVDIVEQ // //=
38+
%token DIVEQ // /=
39+
%token LTLT // <<
40+
%token LTLTEQ // <<=
41+
%token LTEQ // <=
42+
%token LTGT // <>
43+
%token EQEQ // ==
44+
%token GTEQ // >=
45+
%token GTGT // >>
46+
%token GTGTEQ // >>=
47+
%token HATEQ // ^=
48+
%token PIPEEQ // |=
49+
50+
%token FALSE // False
51+
%token NONE // None
52+
%token TRUE // True
53+
%token AND // and
54+
%token AS // as
55+
%token ASSERT // assert
56+
%token BREAK // break
57+
%token CLASS // class
58+
%token CONTINUE // continue
59+
%token DEF // def
60+
%token DEL // del
61+
%token ELIF // elif
62+
%token ELSE // else
63+
%token EXCEPT // except
64+
%token FINALLY // finally
65+
%token FOR // for
66+
%token FROM // from
67+
%token GLOBAL // global
68+
%token IF // if
69+
%token IMPORT // import
70+
%token IN // in
71+
%token IS // is
72+
%token LAMBDA // lambda
73+
%token 8000 NONLOCAL // nonlocal
74+
%token NOT // not
75+
%token OR // or
76+
%token PASS // pass
77+
%token RAISE // raise
78+
%token RETURN // return
79+
%token TRY // try
80+
%token WHILE // while
81+
%token WITH // with
82+
%token YIELD // yield
83+
84+
%token '(' ')' '[' ']' ':' ',' ';' '+' '-' '*' '/' '|' '&' '<' '>' '=' '.' '%' '{' '}' '^' '~' '@'
85+
86+
// Note: Changing the grammar specified in this file will most likely
87+
// require corresponding changes in the parser module
88+
// (../Modules/parsermodule.c). If you can't make the changes to
89+
// that module yourself, please co-ordinate the required changes
90+
// with someone who can; ask around on python-dev for help. Fred
91+
// Drake <fdrake@acm.org> will probably be listening there.
92+
93+
// NOTE WELL: You should also follow all the steps listed in PEP 306,
94+
// "How to Change Python's Grammar"
95+
96+
// Start symbols for the grammar:
97+
// single_input is a single interactive statement;
98+
// file_input is a module or sequence of commands read from an input file;
99+
// eval_input is the input for the eval() functions.
100+
// NB: compound_stmt in single_input is followed by extra NEWLINE!
101+
102+
%%
103+
104+
// FIXME figure out how to tell the parser to start from a given node
105+
// inputs: single_input | file_input | eval_input
106+
// In the mean time just do file_input
107+
// inputs: single_input | file_input | eval_input
108+
inputs: file_input
109+
110+
single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
111+
112+
// (NEWLINE | stmt)*
113+
nl_or_stmt: | nl_or_stmt NEWLINE | nl_or_stmt stmt
114+
115+
//file_input: (NEWLINE | stmt)* ENDMARKER
116+
file_input: nl_or_stmt ENDMARKER
117+
118+
// NEWLINE*
119+
nls: | nls NEWLINE
120+
121+
//eval_input: testlist NEWLINE* ENDMARKER
122+
eval_input: testlist nls ENDMARKER
123+
124+
optional_arglist: | arglist
125+
optional_arglist_call: | '(' optional_arglist ')'
126+
decorator: '@' dotted_name optional_arglist_call NEWLINE
127+
decorators: decorator | decorators decorator
128+
classdef_or_funcdef: classdef | funcdef
129+
decorated: decorators classdef_or_funcdef
130+
optional_return_type: | MINUSGT test
131+
funcdef: DEF NAME parameters optional_return_type ':' suite
132+
parameters: '(' optional_typedargslist ')'
133+
optional_typedargslist: | typedargslist
134+
// (',' tfpdef ['=' test])*
135+
tfpdeftest: tfpdef | tfpdef '=' test
136+
tfpdeftests: | tfpdeftests ',' tfpdeftest
137+
optional_tfpdef: | tfpdef
138+
139+
typedargslist:
140+
tfpdeftest tfpdeftests
141+
| tfpdeftest tfpdeftests ','
142+
| tfpdeftest tfpdeftests ',' '*' optional_tfpdef tfpdeftests
143+
| tfpdeftest tfpdeftests ',' '*' optional_tfpdef tfpdeftests ',' STARSTAR tfpdef
144+
| tfpdeftest tfpdeftests ',' STARSTAR tfpdef
145+
| '*' optional_tfpdef tfpdeftests
146+
| '*' optional_tfpdef tfpdeftests ',' STARSTAR tfpdef
147+
| STARSTAR tfpdef
148+
149+
tfpdef: NAME
150+
| NAME ':' test
151+
152+
vfpdeftest: vfpdef | vfpdef '=' test
153+
vfpdeftests: | vfpdeftests ',' vfpdeftest
154+
optional_vfpdef: | vfpdef
155+
varargslist: vfpdeftest vfpdeftests
156+
| vfpdeftest vfpdeftests ','
157+
| vfpdeftest vfpdeftests ',' '*' optional_vfpdef vfpdeftests
158+
| vfpdeftest vfpdeftests ',' '*' optional_vfpdef vfpdeftests ',' STARSTAR vfpdef
159+
| vfpdeftest vfpdeftests ',' STARSTAR vfpdef
160+
| '*' optional_vfpdef vfpdeftests
161+
| '*' optional_vfpdef vfpdeftests ',' 8000 ; STARSTAR vfpdef
162+
| STARSTAR vfpdef
163+
164+
vfpdef: NAME
165+
166+
stmt: simple_stmt | compound_stmt
167+
optional_semicolon: | ';'
168+
small_stmts: small_stmt | small_stmts ';' small_stmt
169+
simple_stmt: small_stmts optional_semicolon NEWLINE
170+
small_stmt: expr_stmt | del_stmt | pass_stmt | flow_stmt |
171+
import_stmt | global_stmt | nonlocal_stmt | assert_stmt
172+
yield_expr_or_testlist: yield_expr|testlist
173+
yield_expr_or_testlist_star_expr: yield_expr|testlist_star_expr
174+
equals_yield_expr_or_testlist_star_expr: | equals_yield_expr_or_testlist_star_expr '=' yield_expr_or_testlist_star_expr
175+
expr_stmt: testlist_star_expr augassign yield_expr_or_testlist |
176+
testlist_star_expr equals_yield_expr_or_testlist_star_expr
177+
// FIXME this is making a reduce/reduce error for some reason :-(
178+
test_or_star_expr: test | star_expr
179+
test_or_star_exprs: test_or_star_expr | test_or_star_exprs ',' test_or_star_expr
180+
optional_comma: | ','
181+
testlist_star_expr: test_or_star_exprs optional_comma
182+
augassign: PLUSEQ | MINUSEQ | STAREQ | DIVEQ | PERCEQ | ANDEQ | PIPEEQ | HATEQ |
183+
LTLTEQ | GTGTEQ | STARSTAREQ | DIVDIVEQ
184+
// For normal assignments, additional restrictions enforced by the interpreter
185+
del_stmt: DEL exprlist
186+
pass_stmt: PASS
187+
flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt
188+
break_stmt: BREAK
189+
continue_stmt: CONTINUE
190+
return_stmt: RETURN | RETURN testlist
191+
yield_stmt: yield_expr
192+
raise_stmt: RAISE | RAISE test | RAISE test FROM test
193+
import_stmt: import_name | import_from
194+
import_name: IMPORT dotted_as_names
195+
// note below: the ('.' | '...') is necessary because '...' is tokenized as ELLIPSIS
196+
import_dots: | import_dots '.' | import_dots ELIPSIS
197+
import_dots_plus: '.' | ELIPSIS | import_dots
198+
from_arg: import_dots dotted_name | import_dots_plus
199+
import_from_arg: '*' | '(' import_as_names ')' | import_as_names
200+
import_from: FROM from_arg IMPORT import_from_arg
201+
import_as_name: NAME | NAME AS NAME
202+
dotted_as_name: dotted_name | dotted_name AS NAME
203+
import_as_names: import_as_name optional_comma | import_as_name ',' import_as_names
204+
dotted_as_names: dotted_as_name | dotted_as_names ',' dotted_as_name
205+
dotted_name: NAME | dotted_name '.' NAME
206+
names: NAME | names ',' NAME
207+
global_stmt: GLOBAL names
208+
nonlocal_stmt: NONLOCAL names
209+
tests: test | tests ',' test
210+
assert_stmt: ASSERT tests
211+
212+
compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated
213+
elifs: | elifs ELIF test ':' suite
214+
optional_else: | ELSE ':' suite
215+
if_stmt: IF test ':' suite elifs optional_else
216+
while_stmt: WHILE test ':' suite optional_else
217+
for_stmt: FOR exprlist IN testlist ':' suite optional_else
218+
except_clauses: | except_clauses except_clause ':' suite
219+
try_stmt: TRY ':' suite except_clauses optional_else
220+
| TRY ':' suite except_clauses optional_else FINALLY ':' suite
221+
| TRY ':' suite FINALLY ':' suite
222+
with_items: with_item | with_items ',' with_item
223+
with_stmt: WITH with_items ':' suite
224+
with_item: test | test AS expr
225+
// NB compile.c makes sure that the default except clause is last
226+
except_clause: EXCEPT | EXCEPT test | EXCEPT test AS NAME
227+
stmts: stmt | stmts stmt
228+
suite: simple_stmt | NEWLINE INDENT stmts DEDENT
229+
230+
test: or_test | or_test IF or_test ELSE test | lambdef
231+
test_nocond: or_test | lambdef_nocond
232+
lambdef: LAMBDA ':' test | LAMBDA varargslist ':' test
233+
lambdef_nocond: LAMBDA ':' test_nocond | LAMBDA varargslist ':' test_nocond
234+
or_test: and_test | or_test OR and_test
235+
and_test: not_test | and_test AND not_test
236+
not_test: NOT not_test | comparison
237+
comparison: expr | comparison comp_op expr
238+
// <> LTGT isn't actually a valid comparison operator in Python. It's here for the
239+
// sake of a __future__ import described in PEP 401
240+
comp_op: '<'|'>'|EQEQ|GTEQ|LTEQ|LTGT|PLINGEQ|IN|NOT IN|IS|IS NOT
241+
star_expr: '*' expr
242+
expr: xor_expr | expr '|' xor_expr
243+
xor_expr: and_expr | xor_expr '^' and_expr
244+
and_expr: shift_expr | and_expr '&' shift_expr
245+
shift_expr: arith_expr | shift_expr LTLT arith_expr| shift_expr GTGT arith_expr
246+
arith_expr: term | arith_expr '+' term | arith_expr '-' term
247+
term: factor | term '*' factor| term '/' factor| term '%' factor| term DIVDIV factor
248+
factor: '+' factor | '-' factor | '~' factor | power
249+
trailers: | trailers trailer
250+
power: atom trailers | atom trailers STARSTAR factor
251+
strings: STRING | strings STRING
252+
atom: '(' ')' |
253+
'(' yield_expr ')' |
254+
'(' testlist_comp ')' |
255+
'[' ']' |
256+
'[' testlist_comp ']' |
257+
'{' '}' |
258+
'{' dictorsetmaker '}' |
259+
NAME | NUMBER | strings | ELIPSIS | NONE | TRUE | FALSE
260+
testlist_comp: test_or_star_expr comp_for | test_or_star_expr test_or_star_exprs optional_comma
261+
trailer: '(' ')' | '(' arglist ')' | '[' subscriptlist ']' | '.' NAME
262+
subscripts: subscript | subscripts ',' subscript
263+
subscriptlist: subscripts optional_comma
264+
subscript: test
265+
| ':'
266+
| ':' sliceop
267+
| ':' test
268+
| ':' test sliceop
269+
| test ':'
270+
| test ':' sliceop
271+
| test ':' test
272+
| test ':' test sliceop
273+
sliceop: ':' | ':' test
274+
expr_or_star_expr: expr|star_expr
275+
expr_or_star_exprs: expr_or_star_expr | expr_or_star_exprs ',' expr_or_star_expr
276+
exprlist: expr_or_star_exprs optional_comma
277+
testlist: tests optional_comma
278+
// (',' test ':' test)*
279+
test_colon_tests: test ':' test | test_colon_tests ',' test ':' test
280+
dictorsetmaker: test_colon_tests optional_comma
281+
| test ':' test comp_for
282+
| test testlist
283+
| test comp_for
284+
285+
classdef: CLASS NAME optional_arglist_call ':' suite
286+
287+
comma_arguments: | comma_arguments ',' argument
288+
arglist: comma_arguments argument optional_comma
289+
| comma_arguments '*' test comma_arguments
290+
| comma_arguments '*' test comma_arguments ',' STARSTAR test
291+
| comma_arguments STARSTAR test
292+
// The reason that keywords are test nodes instead of NAME is that using NAME
293+
// results in an ambiguity. ast.c makes sure it's a NAME.
294+
argument: test
295+
| test comp_for
296+
| test '=' test // Really [keyword '='] test
297+
comp_iter: comp_for | comp_if
298+
comp_for: FOR exprlist IN or_test
299+
| FOR exprlist IN or_test comp_iter
300+
comp_if: IF test_nocond
301+
| IF test_nocond comp_iter
302+
303+
// not used in grammar, but may appear in "node" passed from Parser to Compiler
304+
// encoding_decl: NAME
305+
306+
yield_expr: YIELD
307+
| YIELD yield_arg
308+
yield_arg: FROM test | testlist

0 commit comments

Comments
 (0)
0