# Grammar for Python 3.0rc1

# Note:  Changing the grammar specified in this file will most likely
#        require corresponding changes in the parser module
#        (../Modules/parsermodule.c).  If you can't make the changes to
#        that module yourself, please co-ordinate the required changes
#        with someone who can; ask around on python-dev for help.  Fred
#        Drake <fdrake@acm.org> will probably be listening there.

# NOTE WELL: You should also follow all the steps listed in PEP 306,
# "How to Change Python's Grammar"

# 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

decorator ::=
             '@' dotted_name [ '(' [arglist] ')' ] NEWLINE

decorators ::=
             decorator+

decorated ::=
             decorators (classdef | funcdef)

funcdef ::=
             'def' NAME parameters ['->' test] ':' suite

parameters ::=
             '(' [typedargslist] ')'

typedargslist ::=
             ((tfpdef ['=' test] ',')* ('*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' tfpdef)
                | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])

tfpdef ::=
             NAME [':' test]

varargslist ::=
             ((vfpdef ['=' test] ',')* ('*' [vfpdef] (',' vfpdef ['=' test])*  [',' '**' vfpdef] | '**' vfpdef)
                | vfpdef ['=' test] (',' vfpdef ['=' test])* [','])

vfpdef ::=
             NAME

stmt ::=
             simple_stmt | compound_stmt

simple_stmt ::=
             small_stmt (';' small_stmt)* [';'] NEWLINE

small_stmt ::=
             (expr_stmt | del_stmt | pass_stmt | flow_stmt
                | import_stmt | global_stmt | nonlocal_stmt | assert_stmt)

expr_stmt ::=
             testlist (augassign (yield_expr|testlist) | ('=' (yield_expr|testlist))*)

augassign ::=
             ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' 
                | '<<=' | '>>=' | '**=' | '//=')

# For normal assignments, additional restrictions enforced by the interpreter
del_stmt ::=
             'del' exprlist

pass_stmt ::=
             'pass'

flow_stmt ::=
             break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt

break_stmt ::=
             'break'

continue_stmt ::=
             'continue'

return_stmt ::=
             'return' [testlist]

yield_stmt ::=
             yield_expr

raise_stmt ::=
             'raise' [test ['from' test]]

import_stmt ::=
             import_name | import_from

import_name ::=
             'import' dotted_as_names

# note below: the ('.' | '...') is necessary because '...' is tokenized as ELLIPSIS
import_from ::=
             ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
              'import' ('*' | '(' import_as_names ')' | import_as_names))

import_as_name ::=
             NAME ['as' NAME]

dotted_as_name ::=
             dotted_name ['as' NAME]

import_as_names ::=
             import_as_name (',' import_as_name)* [',']

dotted_as_names ::=
             dotted_as_name (',' dotted_as_name)*

dotted_name ::=
             NAME ('.' NAME)*

global_stmt ::=
             'global' NAME (',' NAME)*

nonlocal_stmt ::=
             'nonlocal' NAME (',' NAME)*

assert_stmt ::=
             'assert' test [',' test]

compound_stmt ::=
             if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated

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)+
              ['else' ':' suite]
              ['finally' ':' suite] | 'finally' ':' suite))

with_stmt ::=
             'with' test [ with_var ] ':' suite

with_var ::=
             'as' expr

# NB compile.c makes sure that the default except clause is last
except_clause ::=
             'except' [test ['as' NAME]]

suite ::=
             simple_stmt | NEWLINE INDENT stmt+ DEDENT

test ::=
             or_test ['if' or_test 'else' test] | lambdef

test_nocond ::=
             or_test | lambdef_nocond

lambdef ::=
             'lambda' [varargslist] ':' test

lambdef_nocond ::=
             'lambda' [varargslist] ':' test_nocond

or_test ::=
             and_test ('or' and_test)*

and_test ::=
             not_test ('and' not_test)*

not_test ::=
             'not' not_test | comparison

comparison ::=
             star_expr (comp_op star_expr)*

comp_op ::=
             '<'|'>'|'=='|'>='|'<='|'!='|'in'|'not' 'in'|'is'|'is' 'not'

star_expr ::=
             ['*'] expr

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 | power

power ::=
             atom trailer* ['**' factor]

atom ::=
             ('(' [yield_expr|testlist_comp] ')' 
                | '[' [testlist_comp] ']'
                | '{' [dictorsetmaker] '}'
                | NAME | NUMBER | STRING+ | '...' | 'None' | 'True' | 'False')

testlist_comp ::=
             test ( comp_for | (',' test)* [','] )

trailer ::=
             '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME

subscriptlist ::=
             subscript (',' subscript)* [',']

subscript ::=
             test | [test] ':' [test] [sliceop]

sliceop ::=
             ':' [test]

exprlist ::=
             star_expr (',' star_expr)* [',']

testlist ::=
             test (',' test)* [',']

dictorsetmaker ::=
             ( (test ':' test (comp_for | (',' test ':' test)* [',']))
                | (test (comp_for | (',' test)* [','])) )

classdef ::=
             'class' NAME ['(' [arglist] ')'] ':' suite

arglist ::=
             (argument ',')* (argument [',']
                |'*' test (',' argument)* [',' '**' test] 
                |'**' test)

# Really [keyword '='] test
argument ::=
             test [comp_for] | test '=' test 

comp_iter ::=
             comp_for | comp_if

comp_for ::=
             'for' exprlist 'in' or_test [comp_iter]

comp_if ::=
             'if' test_nocond [comp_iter]

testlist1 ::=
             test (',' test)*

# not used in grammar, but may appear in "node" passed from Parser to Compiler
encoding_decl ::=
             NAME

yield_expr ::=
             'yield' [testlist]