identifier :  ( letter  | "_" )  ( letter  | digit  | "_" )(s?)

letter : lowercase  | uppercase

lowercase : /[a-z]/

uppercase : /[A-Z]/

digit : /[0-9]/

stringliteral :  ( stringprefix )(?)  ( shortstring  | longstring ) 

stringprefix : "r"  | "u"  | "ur"  | "R"  | "U"  | "UR"  | "Ur"  | "uR"

shortstring : "'" shortstringitem(s?) "'"  | '"' shortstringitem(s?) '"'

longstring : "'''" longstringitem(s?) "'''"  | '"""' longstringitem(s?) '"""'

shortstringitem : shortstringchar  | escapeseq

longstringitem : longstringchar  | escapeseq

shortstringchar : # <any ASCII character except "\" or newline or the quote>

longstringchar : # <any ASCII character except "\">

escapeseq : "\" # <any ASCII character>

longinteger : integer  ( "l"  | "L" ) 

integer : decimalinteger  | octinteger  | hexinteger

decimalinteger : nonzerodigit digit(s?)  | "0"

octinteger : "0" octdigit(s)

hexinteger : "0"  ( "x"  | "X" ) hexdigit(s)

nonzerodigit : /[1-9]/

octdigit : /[0-7]/

hexdigit : digit  | /[a-"f"]/  | /[A-F]/ # Required hand-editing.

floatnumber : pointfloat  | exponentfloat

pointfloat :  ( intpart )(?) fraction  | intpart "."

exponentfloat :  ( intpart  | pointfloat ) exponent

intpart : digit(s)

fraction : "." digit(s)

exponent :  ( "e"  | "E" )  ( "+"  | "-" )(?) digit(s)

imagnumber :  ( floatnumber  | intpart )  ( "j"  | "J" ) 

atom : identifier  | literal  | enclosure

enclosure : parenth_form  | list_display  | dict_display  | string_conversion

literal : stringliteral  | integer  | longinteger  | floatnumber  | imagnumber

parenth_form : "("  ( expression_list )(?) ")"

list_display : "["  ( listmaker )(?) "]"

listmaker : expression  ( list_for  |  ( "," expression )(s?) ( "," )(?)  ) 

list_iter : list_for  | list_if

list_for : "for" expression_list "in" testlist  ( list_iter )(?) 

list_if : "if" test  ( list_iter )(?) 

dict_display : "\{"  ( key_datum_list )(?) "\}"

key_datum_list : key_datum ( "," key_datum )(s?) ( "," )(?) 

key_datum : expression ":" expression

string_conversion : "`" expression_list "`"

primary : atom  | attributeref  | subscription  | slicing  | call

attributeref : primary "." identifier

subscription : primary "[" expression_list "]"

slicing : simple_slicing  | extended_slicing

simple_slicing : primary "[" short_slice "]"

extended_slicing : primary "[" slice_list "]"

slice_list : slice_item  ( "," slice_item )(s?) ( "," )(?) 

slice_item : expression  | proper_slice  | ellipsis

proper_slice : short_slice  | long_slice

short_slice :  ( lower_bound )(?) ":"  ( upper_bound )(?) 

long_slice : short_slice ":"  ( stride )(?) 

lower_bound : expression

upper_bound : expression

stride : expression

ellipsis : "..."

call : primary "("  ( argument_list  ( "," )(?)  )(?) ")"

argument_list : positional_arguments
		( "," keyword_arguments ( "," "*" expression
					  ( "," "**" expression )(?)
				        )(?)
		)(?)
		| keyword_arguments
		  ( "," "*" expression  ( "," "**" expression )(?)  )(?)
		| "*" expression  ( "," "**" expression )(?)
		| "**" expression

positional_arguments : expression  ( "," expression )(s?)

keyword_arguments : keyword_item  ( "," keyword_item )(s?)

keyword_item : identifier "=" expression

power : primary  ( "**" u_expr )(?) 

u_expr : power  | "-" u_expr  | "+" u_expr  | "\~" u_expr

m_expr	: u_expr
 	| m_expr "*" u_expr
	| m_expr "/" u_expr
	| m_expr "\%" u_expr

a_expr	: m_expr
	| aexpr "+" m_expr
	| aexpr "-" m_expr # Fixed bug in Python grammar

shift_expr	: a_expr
		| shift_expr  ( "<<"  | ">>" ) a_expr
and_expr: shift_expr | and_expr "\;SPMamp;" shift_expr

xor_expr: and_expr
	| xor_expr "\textasciicircum" and_expr

or_expr	: xor_expr
	| or_expr "|" xor_expr

comparison : or_expr ( comp_operator or_expr )(s?)

comp_operator	: "<"  | ">"  | "=="  | ">="  | "<="  | "<>"
		| "!="  | "is"  ( "not" )(?)  |  ( "not" )(?) "in"

expression : or_test  | lambda_form

or_test : and_test  | or_test "or" and_test

and_test : not_test  | and_test "and" not_test

not_test : comparison  | "not" not_test

lambda_form : "lambda"  ( parameter_list )(?) expression

expression_list : expression  ( "," expression ) (s?) ( "," )(?) 

simple_stmt	: expression_stmt  | assert_stmt  | assignment_stmt
		| augmented_assignment_stmt  | pass_stmt  | del_stmt
		| print_stmt  | return_stmt  | yield_stmt  | raise_stmt
		| break_stmt  | continue_stmt  | import_stmt  | global_stmt
		| exec_stmt

expression_stmt : expression_list

assert_statement : "assert" expression  ( "," expression )(?) 

assignment_stmt : ( target_list "=" )(s) expression_list

target_list : target ( "," target )(s?) ( "," )(?) 

target	: identifier
	| "(" target_list ")"
	| "[" target_list "]"
	| attributeref
	| subscription
	| slicing

augmented_assignment_stmt : target augop expression_list

augop	: "+="  | "-="  | "*="  | "/="  | "\%="  | "**="  | ">>="
	| "<<="  | "\&="  | "\textasciicircum="  | "|="

pass_stmt : "pass"

del_stmt : "del" target_list

print_stmt	: "print"
		( \optionalexpression  ( "," expression ) (s?)
		  \optional ","  | ">\code>" expression \optional
		  ( "," expression ) (s)\optional ","
		) 

return_stmt : "return"  ( expression_list )(?) 

yield_stmt : "yield" expression_list

raise_stmt : "raise" ( expression
		       ( "," expression ( "," expression )(?) )(?)
		     )(?) 

break_stmt : "break"

continue_stmt : "continue"

import_stmt	: "import" module
		  ( "as" name )(?)  ( "," module  ( "as" name )(?)  ) (s?)
		| "from" module "import" identifier
		  ( "as" name )(?)  ( "," identifier  ( "as" name )(?)  ) (s?)
		| "from" module "import" "*"

module :  ( identifier "." ) (s?)identifier

global_stmt : "global" identifier  ( "," identifier ) (s?)

exec_stmt : "exec" expression  ( "in" expression  ( "," expression )(?)  )(?) 

compound_stmt	: if_stmt  | while_stmt  | for_stmt  | try_stmt
		| funcdef  | classdef

suite : stmt_list NEWLINE  | NEWLINE INDENT statement(s) DEDENT

statement : stmt_list NEWLINE  | compound_stmt

stmt_list : simple_stmt  ( ";" simple_stmt ) (s?) ( ";" )(?) 

if_stmt : "if" expression ":" suite
	  ( "elif" expression ":" suite ) (s?) ( "else" ":" suite )(?) 

while_stmt : "while" expression ":" suite  ( "else" ":" suite )(?) 

for_stmt : "for" target_list "in" expression_list ":" suite
	   ( "else" ":" suite )(?) 

try_stmt : try_exc_stmt  | try_fin_stmt

try_exc_stmt : "try" ":" suite
	       ( "except"  ( expression  ( "," target )(?)  )(?) ":" suite ) (s)
	       ( "else" ":" suite )(?) 

try_fin_stmt : "try" ":" suite "finally" ":" suite

funcdef : "def" funcname "("  ( parameter_list )(?) ")" ":" suite

parameter_list :  ( defparameter "," )(s?)
		  ( "*" identifier
		    ( "," "**" identifier )(?)
		    | "**" identifier
		    | defparameter  ( "," )(?)
		  ) 

defparameter : parameter  ( "=" expression )(?) 

sublist : parameter  ( "," parameter )(s?) ( "," )(?) 

parameter : identifier  | "(" sublist ")"

funcname : identifier

classdef : "class" classname  ( inheritance )(?) ":" suite

inheritance : "("  ( expression_list )(?) ")"

classname : identifier

file_input :  ( NEWLINE  | statement )(s?)

interactive_input :  ( stmt_list )(?) NEWLINE  | compound_stmt NEWLINE

eval_input : expression_list NEWLINE(s?)

input_input : expression_list NEWLINE

