1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
# Grammar for Python
# Change log:
# 30-Nov-93:
# Removed lambda_input, added lambdef
# 25-Oct-93:
# Added lambda_input
# 18-Oct-93:
# Use testlist instead of exprlist in expr_stmt
# Add exec statement
# 19-May-93:
# Add access statement
# 18-May-93:
# Abolish old class header syntax
# 06-Apr-92:
# Use only '*' for varargs list
# 31-Mar-92:
# Tighten syntax for try statements
# 27-Feb-92:
# Allow NEWLINE* after eval input
# 16-Jan-92:
# Added '*' as alternative for '+' in varargs syntax
# (Not sure which alternative is better yet.)
# 11-Jan-92:
# Variable length argument list syntax added: def f(a, b, +rest): ...
# 8-Jan-92:
# Allow only '==' for equality testing
# Changes since version 8:
# Trailing commas in formal parameter lists are allowed
# Changes since version 7:
# New syntax to specify base classes (but old syntax retained for now)
# 'global' statement (valid only in functions but not enforced here)
# Changes since version 6:
# Add logical operators '|', '^', '&' and '~'
# Add shift operators '<<' and '>>'
# Changes since version 5:
# Comparison operators '<=' '>' '<>' are now 1 token
# Also support '!=' and '==' as alternatives for '<>' and '='
# Changes compared to version 4:
# Blank lines and lines only containing a comment are now eaten
# by the lexer, so the NEWLINE* things in suite are gone
# (but the 2nd NEWLINE terminating single_input stays!)
# Semicolons can separate small statements
# 'continue' statement
# Dictionary constructors: {key:value, key:value, ...}
# More tests instead of exprs
# Changes compared to version 3:
# Removed 'dir' statement.
# Function call argument is a testlist instead of exprlist.
# Changes compared to version 2:
# The syntax of Boolean operations is changed to use more
# conventional priorities: or < and < not.
# Changes compared to version 1:
# modules and scripts are unified;
# 'quit' is gone (use ^D);
# empty_stmt is gone, replaced by explicit NEWLINE where appropriate;
# 'import' and 'def' aren't special any more;
# added 'from' NAME option on import clause, and '*' to import all;
# added class definition.
# Start symbols for the grammar:
# single_input is a single interactive statement;
# file_input is a module or sequence of commands read from an input file;
# eval_input is the input for the eval() and input() functions.
# NB: compound_stmt in single_input is followed by extra NEWLINE!
single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
file_input: (NEWLINE | stmt)* ENDMARKER
eval_input: testlist NEWLINE* ENDMARKER
funcdef: 'def' NAME parameters ':' suite
parameters: '(' [varargslist] ')'
varargslist: (fpdef ',')* '*' NAME | fpdef (',' fpdef)* [',']
fpdef: NAME | '(' fplist ')'
fplist: fpdef (',' fpdef)* [',']
stmt: simple_stmt | compound_stmt
simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
small_stmt: expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt | import_stmt | global_stmt | access_stmt | exec_stmt
expr_stmt: (testlist '=')* testlist
# For assignments, additional restrictions enforced by the interpreter
print_stmt: 'print' (test ',')* [test]
del_stmt: 'del' exprlist
pass_stmt: 'pass'
flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt
break_stmt: 'break'
continue_stmt: 'continue'
return_stmt: 'return' [testlist]
raise_stmt: 'raise' test [',' test]
import_stmt: 'import' NAME (',' NAME)* | 'from' NAME 'import' ('*' | NAME (',' NAME)*)
global_stmt: 'global' NAME (',' NAME)*
access_stmt: 'access' ('*' | NAME (',' NAME)*) ':' accesstype (',' accesstype)*
accesstype: NAME+
# accesstype should be ('public' | 'protected' | 'private') ['read'] ['write']
# but can't be because that would create undesirable reserved words!
exec_stmt: 'exec' expr ['in' test [',' test]]
compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
while_stmt: 'while' test ':' suite ['else' ':' suite]
for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]
try_stmt: 'try' ':' suite (except_clause ':' suite)+ | 'try' ':' suite 'finally' ':' suite
# NB compile.c makes sure that the default except clause is last
except_clause: 'except' [test [',' test]]
suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
test: and_test ('or' and_test)*
and_test: not_test ('and' not_test)*
not_test: 'not' not_test | comparison
comparison: expr (comp_op expr)*
comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
expr: xor_expr ('|' xor_expr)*
xor_expr: and_expr ('^' and_expr)*
and_expr: shift_expr ('&' shift_expr)*
shift_expr: arith_expr (('<<'|'>>') arith_expr)*
arith_expr: term (('+'|'-') term)*
term: factor (('*'|'/'|'%') factor)*
factor: ('+'|'-'|'~') factor | atom trailer*
atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictmaker] '}' | '`' testlist '`' | lambdef | NAME | NUMBER | STRING
# Note ambiguity in grammar: "lambda x: x[1]" could mean "(lambda x: x)[1]"
# but the parser is eager so interprets it as "lambda x: (x[1])"...
lambdef: 'lambda' [varargslist] ':' test
trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME
subscript: test | [test] ':' [test]
exprlist: expr (',' expr)* [',']
testlist: test (',' test)* [',']
dictmaker: test ':' test (',' test ':' test)* [',']
classdef: class NAME ['(' testlist ')'] ':' suite
|