# Grammar for Python 2.6

# 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 ':' suite

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

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

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 | exec_stmt | assert_stmt)

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

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

# For normal assignments, additional restrictions enforced by the interpreter
print_stmt ::=
             'print' ( [ test (',' test)* [','] ] 
                         | '>>' test [ (',' test)+ [','] ] )

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 [',' test [',' test]]]

import_stmt ::=
             import_name | import_from

import_name ::=
             'import' dotted_as_names

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)*

exec_stmt ::=
             'exec' expr ['in' test [',' test]]

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' | ',') test]]

suite ::=
             simple_stmt | NEWLINE INDENT stmt+ DEDENT

# Backward compatibility cruft to support:
# [ x for x in lambda : True, lambda : False if x() ]
# even while also allowing: 
# lambda x : 5 if x else 2
# (But not a mix of the two)
testlist_safe ::=
             old_test [(',' old_test)+ [',']]

old_test ::=
             or_test | old_lambdef

old_lambdef ::=
             'lambda' [varargslist] ':' old_test

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

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

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

atom ::=
             ('(' [yield_expr|testlist_gexp] ')'
                 | '[' [listmaker] ']'
                 | '{' [dictmaker] '}' 
                 | '`' testlist1 '`'
                 | NAME | NUMBER | STRING+)

listmaker ::=
             test ( list_for | (',' test)* [','] )

testlist_gexp ::=
             test ( gen_for | (',' test)* [','] )

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

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

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

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

sliceop ::=
             ':' [test]

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

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

dictmaker ::=
             test ':' test (',' test ':' test)* [',']
              
classdef ::=
             'class' NAME ['(' [testlist] ')'] ':' suite

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

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

list_iter ::=
             list_for | list_if

list_for ::=
             'for' exprlist 'in' testlist_safe [list_iter]

list_if ::=
             'if' old_test [list_iter]

gen_iter ::=
             gen_for | gen_if

gen_for ::=
             'for' exprlist 'in' or_test [gen_iter]

gen_if ::=
             'if' old_test [gen_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]