10.Full Grammar specification

This is the full Python grammar, derived directly from the grammarused to generate the CPython parser (seeGrammar/python.gram).The version here omits details related to code generation anderror recovery.

The notation is a mixture ofEBNFandPEG.In particular,& followed by a symbol, token or parenthesizedgroup indicates a positive lookahead (i.e., is required to match butnot consumed), while! indicates a negative lookahead (i.e., isrequired _not_ to match). We use the| separator to mean PEG’s“ordered choice” (written as/ in traditional PEG grammars).

# PEG grammar for Pythonfile:[statements] ENDMARKERinteractive:statement_newlineeval:expressions NEWLINE* ENDMARKERfunc_type: '('[type_expressions] ')' '->'expression NEWLINE* ENDMARKERfstring:star_expressions# type_expressions allow */** but ignore themtype_expressions:| ','.expression+ ',' '*'expression ',' '**'expression| ','.expression+ ',' '*'expression| ','.expression+ ',' '**'expression| '*'expression ',' '**'expression| '*'expression| '**'expression| ','.expression+statements:statement+statement:compound_stmt|simple_stmtstatement_newline:|compound_stmt NEWLINE|simple_stmt| NEWLINE| ENDMARKERsimple_stmt:|small_stmt !';' NEWLINE# Not needed, there for speedup| ';'.small_stmt+[';'] NEWLINE# NOTE: assignment MUST precede expression, else parsing a simple assignment# will throw a SyntaxError.small_stmt:|assignment|star_expressions|return_stmt|import_stmt|raise_stmt|'pass'|del_stmt|yield_stmt|assert_stmt|'break'|'continue'|global_stmt|nonlocal_stmtcompound_stmt:|function_def|if_stmt|class_def|with_stmt|for_stmt|try_stmt|while_stmt# NOTE: annotated_rhs may start with 'yield'; yield_expr must start with 'yield'assignment:| NAME ':'expression['='annotated_rhs]|('('single_target ')'|single_subscript_attribute_target) ':'expression['='annotated_rhs]|(star_targets '=')+(yield_expr|star_expressions) !'='[TYPE_COMMENT]|single_targetaugassign ~(yield_expr|star_expressions)augassign:| '+='| '-='| '*='| '@='| '/='| '%='| '&='| '|='| '^='| '<<='| '>>='| '**='| '//='global_stmt:'global' ','.NAME+nonlocal_stmt:'nonlocal' ','.NAME+yield_stmt:yield_exprassert_stmt:'assert'expression[','expression]del_stmt:|'del'del_targets &(';'| NEWLINE)import_stmt:import_name|import_fromimport_name:'import'dotted_as_names# note below: the ('.' | '...') is necessary because '...' is tokenized as ELLIPSISimport_from:|'from'('.'| '...')*dotted_name'import'import_from_targets|'from'('.'| '...')+'import'import_from_targetsimport_from_targets:| '('import_from_as_names[','] ')'|import_from_as_names !','| '*'import_from_as_names:| ','.import_from_as_name+import_from_as_name:| NAME['as' NAME]dotted_as_names:| ','.dotted_as_name+dotted_as_name:|dotted_name['as' NAME]dotted_name:|dotted_name '.' NAME| NAMEif_stmt:|'if'named_expression ':'blockelif_stmt|'if'named_expression ':'block[else_block]elif_stmt:|'elif'named_expression ':'blockelif_stmt|'elif'named_expression ':'block[else_block]else_block:'else' ':'blockwhile_stmt:|'while'named_expression ':'block[else_block]for_stmt:|'for'star_targets'in' ~star_expressions ':'[TYPE_COMMENT]block[else_block]| ASYNC'for'star_targets'in' ~star_expressions ':'[TYPE_COMMENT]block[else_block]with_stmt:|'with' '(' ','.with_item+ ','? ')' ':'block|'with' ','.with_item+ ':'[TYPE_COMMENT]block| ASYNC'with' '(' ','.with_item+ ','? ')' ':'block| ASYNC'with' ','.with_item+ ':'[TYPE_COMMENT]blockwith_item:|expression'as'star_target &(','| ')'| ':')|expressiontry_stmt:|'try' ':'blockfinally_block|'try' ':'blockexcept_block+[else_block][finally_block]except_block:|'except'expression['as' NAME] ':'block|'except' ':'blockfinally_block:'finally' ':'blockreturn_stmt:|'return'[star_expressions]raise_stmt:|'raise'expression['from'expression]|'raise'function_def:|decoratorsfunction_def_raw|function_def_rawfunction_def_raw:|'def' NAME '('[params] ')'['->'expression] ':'[func_type_comment]block| ASYNC'def' NAME '('[params] ')'['->'expression] ':'[func_type_comment]blockfunc_type_comment:| NEWLINE TYPE_COMMENT &(NEWLINE INDENT)# Must be followed by indented block| TYPE_COMMENTparams:|parametersparameters:|slash_no_defaultparam_no_default*param_with_default*[star_etc]|slash_with_defaultparam_with_default*[star_etc]|param_no_default+param_with_default*[star_etc]|param_with_default+[star_etc]|star_etc# Some duplication here because we can't write (',' | &')'),# which is because we don't support empty alternatives (yet).#slash_no_default:|param_no_default+ '/' ','|param_no_default+ '/' &')'slash_with_default:|param_no_default*param_with_default+ '/' ','|param_no_default*param_with_default+ '/' &')'star_etc:| '*'param_no_defaultparam_maybe_default*[kwds]| '*' ','param_maybe_default+[kwds]|kwdskwds: '**'param_no_default# One parameter.  This *includes* a following comma and type comment.## There are three styles:# - No default# - With default# - Maybe with default## There are two alternative forms of each, to deal with type comments:# - Ends in a comma followed by an optional type comment# - No comma, optional type comment, must be followed by close paren# The latter form is for a final parameter without trailing comma.#param_no_default:|param ',' TYPE_COMMENT?|param TYPE_COMMENT? &')'param_with_default:|paramdefault ',' TYPE_COMMENT?|paramdefault TYPE_COMMENT? &')'param_maybe_default:|paramdefault? ',' TYPE_COMMENT?|paramdefault? TYPE_COMMENT? &')'param: NAMEannotation?annotation: ':'expressiondefault: '='expressiondecorators:('@'named_expression NEWLINE)+class_def:|decoratorsclass_def_raw|class_def_rawclass_def_raw:|'class' NAME['('[arguments] ')'] ':'blockblock:| NEWLINE INDENTstatements DEDENT|simple_stmtstar_expressions:|star_expression(','star_expression)+[',']|star_expression ','|star_expressionstar_expression:| '*'bitwise_or|expressionstar_named_expressions: ','.star_named_expression+[',']star_named_expression:| '*'bitwise_or|named_expressionnamed_expression:| NAME ':=' ~expression|expression !':='annotated_rhs:yield_expr|star_expressionsexpressions:|expression(','expression)+[',']|expression ','|expressionexpression:|disjunction'if'disjunction'else'expression|disjunction|lambdeflambdef:|'lambda'[lambda_params] ':'expressionlambda_params:|lambda_parameters# lambda_parameters etc. duplicates parameters but without annotations# or type comments, and if there's no comma after a parameter, we expect# a colon, not a close parenthesis.  (For more, see parameters above.)#lambda_parameters:|lambda_slash_no_defaultlambda_param_no_default*lambda_param_with_default*[lambda_star_etc]|lambda_slash_with_defaultlambda_param_with_default*[lambda_star_etc]|lambda_param_no_default+lambda_param_with_default*[lambda_star_etc]|lambda_param_with_default+[lambda_star_etc]|lambda_star_etclambda_slash_no_default:|lambda_param_no_default+ '/' ','|lambda_param_no_default+ '/' &':'lambda_slash_with_default:|lambda_param_no_default*lambda_param_with_default+ '/' ','|lambda_param_no_default*lambda_param_with_default+ '/' &':'lambda_star_etc:| '*'lambda_param_no_defaultlambda_param_maybe_default*[lambda_kwds]| '*' ','lambda_param_maybe_default+[lambda_kwds]|lambda_kwdslambda_kwds: '**'lambda_param_no_defaultlambda_param_no_default:|lambda_param ','|lambda_param &':'lambda_param_with_default:|lambda_paramdefault ','|lambda_paramdefault &':'lambda_param_maybe_default:|lambda_paramdefault? ','|lambda_paramdefault? &':'lambda_param: NAMEdisjunction:|conjunction('or'conjunction)+|conjunctionconjunction:|inversion('and'inversion)+|inversioninversion:|'not'inversion|comparisoncomparison:|bitwise_orcompare_op_bitwise_or_pair+|bitwise_orcompare_op_bitwise_or_pair:|eq_bitwise_or|noteq_bitwise_or|lte_bitwise_or|lt_bitwise_or|gte_bitwise_or|gt_bitwise_or|notin_bitwise_or|in_bitwise_or|isnot_bitwise_or|is_bitwise_oreq_bitwise_or: '=='bitwise_ornoteq_bitwise_or:|('!=')bitwise_orlte_bitwise_or: '<='bitwise_orlt_bitwise_or: '<'bitwise_orgte_bitwise_or: '>='bitwise_orgt_bitwise_or: '>'bitwise_ornotin_bitwise_or:'not''in'bitwise_orin_bitwise_or:'in'bitwise_orisnot_bitwise_or:'is''not'bitwise_oris_bitwise_or:'is'bitwise_orbitwise_or:|bitwise_or '|'bitwise_xor|bitwise_xorbitwise_xor:|bitwise_xor '^'bitwise_and|bitwise_andbitwise_and:|bitwise_and '&'shift_expr|shift_exprshift_expr:|shift_expr '<<'sum|shift_expr '>>'sum|sumsum:|sum '+'term|sum '-'term|termterm:|term '*'factor|term '/'factor|term '//'factor|term '%'factor|term '@'factor|factorfactor:| '+'factor| '-'factor| '~'factor|powerpower:|await_primary '**'factor|await_primaryawait_primary:| AWAITprimary|primaryprimary:|primary '.' NAME|primarygenexp|primary '('[arguments] ')'|primary '['slices ']'|atomslices:|slice !','| ','.slice+[',']slice:|[expression] ':'[expression][':'[expression]]|expressionatom:| NAME|'True'|'False'|'None'|'__peg_parser__'|strings| NUMBER|(tuple|group|genexp)|(list|listcomp)|(dict|set|dictcomp|setcomp)| '...'strings: STRING+list:| '['[star_named_expressions] ']'listcomp:| '['named_expression ~for_if_clauses ']'tuple:| '('[star_named_expression ','[star_named_expressions]] ')'group:| '('(yield_expr|named_expression) ')'genexp:| '('named_expression ~for_if_clauses ')'set: '{'star_named_expressions '}'setcomp:| '{'named_expression ~for_if_clauses '}'dict:| '{'[double_starred_kvpairs] '}'dictcomp:| '{'kvpairfor_if_clauses '}'double_starred_kvpairs: ','.double_starred_kvpair+[',']double_starred_kvpair:| '**'bitwise_or|kvpairkvpair:expression ':'expressionfor_if_clauses:|for_if_clause+for_if_clause:| ASYNC'for'star_targets'in' ~disjunction('if'disjunction)*|'for'star_targets'in' ~disjunction('if'disjunction)*yield_expr:|'yield''from'expression|'yield'[star_expressions]arguments:|args[','] &')'args:| ','.(starred_expression|named_expression !'=')+[','kwargs]|kwargskwargs:| ','.kwarg_or_starred+ ',' ','.kwarg_or_double_starred+| ','.kwarg_or_starred+| ','.kwarg_or_double_starred+starred_expression:| '*'expressionkwarg_or_starred:| NAME '='expression|starred_expressionkwarg_or_double_starred:| NAME '='expression| '**'expression# NOTE: star_targets may contain *bitwise_or, targets may not.star_targets:|star_target !','|star_target(','star_target)*[',']star_targets_list_seq: ','.star_target+[',']star_targets_tuple_seq:|star_target(','star_target)+[',']|star_target ','star_target:| '*'(!'*'star_target)|target_with_star_atomtarget_with_star_atom:|t_primary '.' NAME !t_lookahead|t_primary '['slices ']' !t_lookahead|star_atomstar_atom:| NAME| '('target_with_star_atom ')'| '('[star_targets_tuple_seq] ')'| '['[star_targets_list_seq] ']'single_target:|single_subscript_attribute_target| NAME| '('single_target ')'single_subscript_attribute_target:|t_primary '.' NAME !t_lookahead|t_primary '['slices ']' !t_lookaheaddel_targets: ','.del_target+[',']del_target:|t_primary '.' NAME !t_lookahead|t_primary '['slices ']' !t_lookahead|del_t_atomdel_t_atom:| NAME| '('del_target ')'| '('[del_targets] ')'| '['[del_targets] ']'t_primary:|t_primary '.' NAME &t_lookahead|t_primary '['slices ']' &t_lookahead|t_primarygenexp &t_lookahead|t_primary '('[arguments] ')' &t_lookahead|atom &t_lookaheadt_lookahead: '('| '['| '.'