summaryrefslogtreecommitdiffstats
path: root/Grammar/Grammar
blob: cb4bc2718e890b98f575424ce658a769b0f5e224 (plain)
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
# Grammar for Python

# Change log:

# 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;
#	expr_input is the input for the input() function;
#	eval_input is the input for the eval() function.

# NB: compound_stmt in single_input is followed by extra NEWLINE!
single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
file_input: (NEWLINE | stmt)* ENDMARKER
expr_input: testlist NEWLINE
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
expr_stmt: (exprlist '=')* exprlist
# 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!

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 '`' | NAME | NUMBER | STRING
trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME
subscript: test | [test] ':' [test]
exprlist: expr (',' expr)* [',']
testlist: test (',' test)* [',']
dictmaker: test ':' test (',' test ':' test)* [',']

classdef: class NAME ['(' testlist ')'] ':' suite