// Based on https://docs.python.org/2.7/reference/grammar.html // with some modifications. token Lt='<' Gt='>' Eq='=' At='@' And='&' Dot='.' LPar='(' RPar=')' Star='*' Plus='+' Semi=';' Lt2='<<' Eq2='==' Gt2='>>' Pipe='|' Comma=',' Minus='-' Slash='/' Colon=':' LtEq='<=' LtGt='<>' GtEq='>=' LBrak='[' RBrak=']' Caret='^' BTick='`' Tilde='~' AndEq='&=' Star2='**' LBrace='{' RBrace='}' ExclEq='!=' Percent='%' StarEq='*=' PlusEq='+=' Slash2='//' Lt2Eq='<<=' Gt2Eq='>>=' PipeEq='|=' MinusEq='-=' SlashEq='/=' CaretEq='^=' Star2Eq='**=' PercentEq='%=' Slash2Eq='//='; token As='as' If='if' In='in' Is='is' Or='or' AndKw='and' Def='def' Del='del' For='for' Not='not' Try='try' Else='else' Exec='exec' From='from' Pass='pass' Elif='elif' With='with' Break='break' Class='class' Print='print' Raise='raise' While='while' Assert='assert' Except='except' Global='global' Import='import' Lambda='lambda' Return='return' Finally='finally' Continue='continue' Yield='yield'; token Newline Name Dedent Indent Int Float Imaginary String; token Whitespace Comment; skip Whitespace Comment; right '**'; start file_input; part single_input eval_input; /// a module or sequence of commands read from an input file file_input: (Newline | stmt)*; /// a single interactive statement single_input: Newline | simple_stmts | compound_stmt Newline; /// the input for the eval() and input() functions eval_input: testlist Newline*; decorator: '@' dotted_name [ '(' [arglist] ')' ] Newline; decorators: decorator+; decorated: decorators (classdef | funcdef); funcdef: 'def' Name parameters ':' suite; parameters: '(' [varargslist] ')'; varargslist: fpdef ['=' test] (?1 ',' fpdef ['=' test])* [',' ['*' Name [',' '**' Name] | '**' Name]] | '*' Name [',' '**' Name] | '**' Name ; fpdef: Name | '(' fplist ')'; fplist: fpdef (?1 ',' fpdef)* [',']; stmt^: simple_stmts | compound_stmt; simple_stmts: small_stmt (?1 ';' 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) @aug_assign_stmt | ('=' (yield_expr | testlist))* @assign_stmt ) ; augassign^: '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=' | '**=' | '//=' ; print_stmt: 'print' ( [ test (?1 ',' test)* [','] ] | '>>' test [ (?1 ',' 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] | 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 (?1 ',' 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' with_item (',' with_item)* ':' suite; with_item: test ['as' expr]; except_clause: 'except' [test [('as' | ',') test]]; suite: simple_stmts | Newline Indent stmt+ Dedent; testlist_safe: old_test [(?1 ',' old_test)+ [',']]; old_test: or_test | old_lambdef; old_lambdef: 'lambda' [varargslist] ':' old_test; test^: or_test ['if' or_test 'else' test >if_expr] | lambda_expr; or_test: 'not' or_test @unary_expr | or_test 'and' or_test @bool_expr | or_test 'or' or_test @bool_expr | ^ <1 expr [(comp_op expr)+ 1>compare_expr] ; comp_op^: '<' | '>' | '==' | '>=' | '<=' | '<>' | '!=' | 'in' | 'not' 'in' | 'is' ['not']; expr: expr '**' expr @binary_expr | expr '(' [arglist] ')' @call_expr | expr '[' subscriptlist ']' @subscript_expr | expr '.' Name @field_expr | ('+'|'-'|'~') expr @unary_expr | expr ('*' | '/' | '%' | '//') expr @binary_expr | expr ('+' | '-') expr @binary_expr | expr ('<<' | '>>') expr @binary_expr | expr '&' expr @binary_expr | expr '^' expr @binary_expr | expr '|' expr @binary_expr | '(' [yield_expr | testlist_comp] ')' @tuple_expr | '[' [listmaker] ']' @list_expr | '{' [dictorsetmaker] '}' @dict_expr | '`' testlist1 '`' @repr_expr | Name @name_expr | Int @int_expr | Float @float_expr | Imaginary @imaginary_expr | String+ @string_expr ; listmaker: test (list_for | (?1 ',' test)* [',']); testlist_comp: test (comp_for | (?1 ',' test)* [',']); lambda_expr: 'lambda' [varargslist] ':' test; subscriptlist: subscript (?1 ',' subscript)* [',']; subscript: '.' '.' '.' | test [':' [test] [sliceop]] | ':' [test] [sliceop] ; sliceop: ':' [test]; exprlist: expr (?1 ',' expr)* [',']; testlist: test (?1 ',' test)* [',']; dictorsetmaker: test ( ':' test (comp_for | (?1 ',' test ':' test)* [',']) | (comp_for | (?1 ',' test)* [',']) ) ; classdef: 'class' Name ['(' [testlist] ')'] ':' suite; arglist: argument (?1 ',' argument)* [ ',' [ '*' test (?2 ',' argument)* [',' '**' test] | '**' test ] ] | '*' test (?2 ',' argument)* [',' '**' test] | '**' test ; argument: test [comp_for | '=' test]; list_iter: list_for | list_if; list_for: 'for' exprlist 'in' testlist_safe [list_iter]; list_if: 'if' old_test [list_iter]; comp_iter: comp_for | comp_if; comp_for: 'for' exprlist 'in' or_test [comp_iter]; comp_if: 'if' old_test [comp_iter]; testlist1: test (',' test)*; yield_expr: 'yield' [testlist];