This is the Full Grammar Specification of python taken from Chater 10
of a python manual. This chapter says it was derived directly from the
grammar used to generate the CPthon Parser. It is essentially an
extended BNF specification with a few modifications allowing it to be
a specification of a recursive descent parser. Some of these
modifications are as follows.

Alternatives are tested in the order in which they appear.
( e )  matches e
e*     matches zero or more occurrences of e
e+     matches one or more occurrences of e
[ e ]  matches zero or one occurrences of e
e?     matches zero or one occurrences of e
s.e+   matches a sequence of es seperated by ses

&e     is successful if e can be matched, but does not advance the input
!e     is successful if e cannot be matched, but does not advance the input
~      disallows backtracking at this point

********************* The Rules *****************************

statements: statement+

statement: compound_stmt | simple_stmts

statement_newline:
  | compound_stment NEWLINE
  | simple_stmts
  | NEWLINE
  | ENDMARKER

simple_stmts:
  | simple_stmt !';' NEWLINE
  | ';'.simple_stmt+ [';'] NEWLINE

simple_stmt:
  | assignment
  | type_alias
  | star_expressions
  | return_stmt
  | import_stmt
  | raise_stmt
  | 'pass'
  | del_stmt
  | yield_stmt
  | assert_stmt
  | 'break'
  | 'continue'
  | global_stmt
  | nonlocal_statement

assignment:
  | NAME ':' expression ['=' annotation_rhs']
  | ('(' single_target /)'
     | single_subscript_attribute_target) ':' expression ['=' annotated_rhs]
  | (start_targets '=' )+ (yield_expression | star_expressions) !'=' [TYPE_COMMENT]
  | single_target augassign ~ (yield_expr | star_expressions)

annotated_rhs: yield_expr | star_expressions

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

return_stmt:
| 'return' [star_expressions]

raise_stmt:
  | 'raise' expression ['from' expression ]
  | 'raise'

global_stmt:
  | 'global' ','.NAME+

nonlocal_stmt:
  | 'nonlocal' ','.NAME+

del_stmt:
  | 'del' del_targets &(';' | NEWLINE}

yield_stmt:
  | yield_expr

assert_stmt:
  | 'assert' expression [',' expression]

import_stmt:
  | import_name
  | import_from

import_name:
  | 'import' dotted_as_names

import_from:
  | 'from' ('.' | '...')* dotted_name 'import' import_from_targets
  | 'from' ('.' | '...')* 'import' import_from_targets

import_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:
  | ','.import_as_name+

dotted_as_name:
  | dotted_as_name ',' NAME
  | NAME

block:
  | NEWLINE INDENT statements DEDENT
  | simple_stmts

decorators:
  | ('@' named_expression NEWLINE)+

class_def:
  | decorators class_def_raw
  | class_def_raw

class_def_raw:
  | 'class' NAME [type_param] ['(' [arguments] ')'] ':' block

function_def:
  | decorators function_def_raw
  | function_def_raw

function_def_raw:
  | 'def' NAME [type_params] '(' [params] ')' ['->' expression] ':' [func_type_comment] block
  | 'async' 'def' NAME [type_params] '(' [params] ')' ['->' expression] ':' [func_type_comment] block

params:
  | parameters

parameters:
  | slash_no_default param_no_default* param_with_default* [star_etc]
  | slash_with_default param_with_default* [star_etc]
  | slash_no_default+ param_with_default* [star_etc]
  | param_with_default+ [star_etc]
  | star_etc

slash_no_default:
  | param_no_default+ '/' ','
  | param_no_default+ '/' &')'

slah_with_default:
  | param_no_default+ param_with_default+ '/' ','
  | param_no_default+ param_with_default+ '/' &')'

star_etc:
  | '*' param_no_default param_with_default* [kwds]
  | '*' param_no_default_star_annotation param_maybe_default* [kwds]
  | '*' ',' param_maybe_default* [kwds]
  | kwds

kwds:
  | '**' param_nodefault

param_nodefault:
  | param ',' TYPE_COMMENT?
  | param TYPE_COMMENR? &')'

param_no_default_star_annotation:
  | param_star_annotation ',' TYPE_COMMENT?
  | param_star_annotation TYPE_COMMENT? &')'

param_with_default:
  | param default ',' TYPE_COMMENT?
  | param default TYPE_COMMENR? &')'

param_maybe_default:
  | param default? ',' TYPE_COMMENT?
  | param default? TYPE_COMMENR? &')'

param:
  | NAME annotation?

param_star_annotation:
  | NAME startannotation

annotation:
  | ':' expression

star_annotation:
  | ':' start_expression

default:
  | '=' expression
  | invalid_default

if_stmt:
  | 'if' named_expression ':' block elif_stmt
  | 'if' named_expression ':' [block [else_block]

elif_stmt:
  | 'elif' named_expression ':' block elif_stmt
  | 'elif' named_expression ':' block [else_block]
  
else_block:
  | 'else' ';' block

while_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+ ','? ')' ':' [TYPE_COMMENT] block
  | 'with' ','.with_item+ ':' [TYPE_COMMENT] block
  | 'async' 'with' '(' ','.with_item+ ','? ')' ':' block 
  | 'async' 'with' ','.with_item+ ':' [TYPE_COMMENT] block 

with_item:
  | expression 'as' star_star_target &(',' | ')' | ':')
  | expression

try_stmt:
  | 'try' ':' block finally_block
  | 'try' ':' block except_block+ [else_block] [finally_block]
  | 'try' ':' block except_star_block+ [else_block] [finally_block]

except_block:
  | 'except' expression ['as' NAME] ':' block
  | 'except' ':' block

except_star_block:
  | 'except' '*' expression ['as' NAME] ':' block

finally_block:
  | 'finally' ':' block

match_stmt:
  | "match" subject_expr ':' NEWLINE INDENT case_block+ DEDENT

subject_expr:
  | star_named_expression ',' start_named_expressions?
  | named_expression

case_block:
  | "case" patterns guard? : block

guard:
  | 'f' named-expression

patterns:
  | open_sequence_pattern
  | pattern

pattern:
  | as_pattern
  | or_pattern

as_pattern:
  | or_pattern 'as' pattern_capture_target

or_pattern:
  | '|'.closed_pattern+

closed_pattern:
  | literal_pattern
  | capture_pattern
  | whildcard_pattern
  | value_pattern
  | group_pattern
  | sequence_pattern
  | mapping_pattern
  | class_pattern

literal_pattern:
  | signed_number !('+' | '-')
  | complex_number
  | strings
  | 'None'
  | 'True'
  | 'False'

literal_expr:
  | signed_number !('+' | '-')
  | complex_number
  | strings
  | 'None'
  | 'True'
  | 'False'

complex_number:
  | signed_real_number '+' imaginary_number
  | signed_real_number '-' imaginary_number

signed_number:
  | NUMBER
  | '-' NUMBER

real_number:
  | NUMBER

imaginary_number:
  | NUMBER

capture_pattern:
  | pattern_capture_target

pattern_capture_target:
  | !'_' NAME !(',' | '(' | '=')

whildcard_pattern:
  | '_'

value_pattern:
  | attr !('.' | ' (' | '=')

attr:
  | name_or_attr '.'NAME

name_or_attr:
  | attr
  | NAME

group_pattern:
  | '(' pattern ')'

sequence_pattern:
  | '[' maybe_sequence_pattern? ']'
  | '[' open_sequence_pattern? ']'

open_sequence_pattern:
  | maybe_star_pattern ',; maybe_sequence_pattern?

maybe_sequence_pattern:
  | ','.maybe_star_pattern+ ','?

maybe_star_pattern:
  | star_pattern
  | pattern

star_pattern:
  | '*' pattern_capture_target
  | '*' wildcard_pattern

mapping_pattern:
  | '{' '}'
  | '{' double_star_pattern ','? '}'
  | '{' items_pattern ',; double_star_pattern ','? '}'
  | '{' items_pattern ','? '}'

items_pattern:
  | ','.key_value_pattern+

key_value_pattern:
  | (literal_expr | attr) ':' pattern

double_star_pattern:
  | '**' pattern_capture_target

class_pattern:
  | name_or_attr '(' ')'
  | name_or_attr '(' positional_patterns ','? ')'
  | name_or_attr '(' keyword_patterns ','? ')'
  | name_or_attr '(' positional_patterns ','keyword_patterns ','? ')'

positional_patterns:
  | ','.pattern+

keyword_patterns:
  | ','.keyword_pattern+

keyword_pattern:
  | NAME '=' pattern

type_alias:
  | "type" NAME [type_params] '=' expression

type_params:
  | invalid-type_params
  | '[' type_params_seq ']'

type_param-seq:
  | ','.type_para+ [',']

type_param:
  | NAME [type_param_bound] [type_param_default]
  | '*' NAME [type_param_starred_default]
  | '**' NAME [type param_default]

type_param_bound:
  | ':' expression

type_param_default:
  | '=' expression

type_param_starred_default:
  | '=' star_expression

expressions:
  | expression (',' expression)+ [',']
  | expression ','
  | expression

expression:
  | disjunction 'if' disjunction 'else' expression
  | disjunction
  | lambdef

yield_expr:
  | 'yield' 'from' expression
  | 'yield' [star_expression]

star_expressions:
  | star_expression (',' start_expression )+ [',']
  | star_expression ','
  | star_expression

star_expression:
  | '*' bitwise_or
  | expression

star_named_expressions:
  | ','.star_named_expression+ [',']

star_named_expression:
  | '*' bitwise_or
  | name_expression

assignment_expression:
  | NAME ':=' ~ expression

named_expression:
  | assignment_expression
  | expression !':='

disjuction:
  | conjunction ('or' conjunction)+
  | conjunction

conjunction:
  | inversion ('and' inversion)+
  | inversion

inversion:
  | 'not' inversion
  | comparison

comparison:
  | bitwise_or compare_op_bitwase_or_pair+
  | bitwise_or

compare_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_or

eq_bitwise_or:
  | '==' bitwise_or

noteq_bitwise_or:
  | ( '!=' ) bitwise_or

lte_bitwise_or:
  | '<=' bitwise_or

lt_bitwise_or:
  | '<' bitwise_or

gte_bitwise_or:
  | '>=' bitwise_or

gt_bitwise_or:
  | '>' bitwise_or

notin_bitwise_or:
  | 'not' 'in' bitwise_or

in_bitwise_or:
  | 'in' bitwise_or

isnot_bitwise_or:
  | 'is' 'not' bitwise_or

is_bitwise_or:
  | 'is' bitwise_or

bitwise_or:
  | bitwise_or '|' bitwise_xor
  | bitwise_xor

bitwise_xor:
  | bitwise_xor '^' bitwise_and
  | bitwise_and

bitwise_and:
  | bitwise_and '^' shift_expr
  | shift_expr

shift_expr:
  | shift_expr '<<' sum
  | shift_expr '>>' sum
  | sum

sum:
  | sum '+' term
  | sum '-' term
  | term

term:
  | term '*' factor
  | term '/' factor
  | term '//' factor
  | term '%' factor
  | term '@' factor
  | factor

factor:
  | '+' factor
  | '-' factor
  | '~' factor
  | power

power:
  | await_primary '**' factor
  | await_primary

await_primary:
  | 'await' primary
  | priamry

primary:
  | primary '.' NAME
  | primary '(' [arguments] ')'
  | primary '[' slices ']'
  | atom

slices:
  | slice !','
  | ','.(slices | starred_expression)+ [',']

slice:
  | [expression] ':' [expression] [':' [expression] ]
  | named_expression

atom:
  | NAME
  | 'True'
  | 'False'
  | 'None'
  | strings
  | NUMBER
  | (tuple | group | genexp)
  | (list | listcomp)
  | (dict | set | dictcomp | setcomp)
  | '...'

group:
  | '(' (yield_expr | named_expression) ')'

lambdef:
| 'lambda' [lambda_params] ':' expression

lambda_params:
  | lambda_parameters

lambda_parameters:
  | lambda_slash_no_default lambda_param_no default* lambda_param_with_default* [lambda_star_etc]
  | lambda_slash_with_default lambda_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_etc  

lambda_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_default lambda_param_maybe_default* [lambda_kwds]
  | '*' ',' lambda_param_maybe_default+ [lambda_kwds]
  | lambda_kwds

lambda_kwds:
  | '**' lambda_param_no_default

lambda_param_no_default:
  | lambda_param ','
  | lambda_param &':'

lambda_param_with_default:
  | lambda_param default ','
  | lambda_param default &':'

lambd_param_maybe_default:
  | lambda_param default? ','
  | lambda_param default? &':'

lambda_param:
  | NAME
  
  
fstring_middle:
  | fstring_replacement_field
  | FSTRING_MIDDLE

fstring_replacement_field:
  | '(' annotated_rhs '=' [fstring_conversion] [fstring_full_format_spec] '}'

fstring_conversion:
  | ':' NAME

fstring_full_format_spec:
  | ':' fstring_format_spec:

fstring_format_spec:
  | FSTRING_MIDDLE
  | fstring_replacement_field

fstring:
  | FSTRING_START fstring_middle* FSTRING_END

string:
  | STRING

strings:
  | (fstring | string)+

list:
  | '[' [star_named_expression] ']'



tuple:
  | '(' [star_named_expression ',' [star_named_expressions] ] ')'

set:
  | '{' star_named_expressions '}'

dict:
  | '{' [double_starred_kvpairs] '}'

double_starred-kvpair:
  | '**' bitwise_or
  | kvpair

kvpair:
  | expression ':' expression

for_if_clauses:
  | for_if_clause+

for_if_clause:
  | 'async' 'for' star_targets 'in' ~ disjunction ('if' disjuntion)*
  | 'for' star_targets 'in' ~ disjunction ('if' disjuntion)*

listcomp:
  | '[' named_expression for_if_clauses ']'

setcomp:
  | '{' named_expression for_if_clauses '}'
  s '}'

genexp:
  | '(' ( assignment_expression | expression !':=') for_if_clauses ')'

dictcomp:
  | '{' kvpair for_if_clauses '}'

arguments:
  | args [','] &')'

args:
  | ','.(starred_expression | ( assignment_expression | expression !':=') !'=')+ [',' kwargs]
  | kwargs

kwargs:
  | ',' kwarg_or starred+ ',' ','.kwarg_or_double_starred+
  | ','.kwarg_or_starred+
  | ','.kwarg_or_double_starred+

starred_expression_:
  | '*' expression

kwarg_or_starred:
  | NAME '=' expression
  | starred_expression

kwarg_or_double_starred:
  | NAME '=' expression
  | '**' expression

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_atom

target_with_star_atom:
  | t_primary ',' NAME !t_lookahead
  | t_primary '[' slices ']' !t_lookahead
  | star_atom

star_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_lookahead

t_primary:
  | t_primary ',' NAME &t_lookahead
  | t_primary '[' slices ']' &!t_lookahead
  | t_primary genexp &!t_lookahead
  | t_primary '(' [arguments] ')' &!t_lookahead
  | atom &!t_lookahead

t_lookahead:
  | '('
  | '['
  | '{'

del_targets:
  | ','.deltarget+ [',']

del_target:
  | t_primary ',' NAME !t_lookahead
  | t_primary '[' slices ']' !t_lookahead
  | del_atom

del_atom:
  | NAME
  | '(' del_target ')'
  | '(' [del_targets] ')'
  | '[' [del_targets] ']'

type_expression:
  | ','.expression+ ',' '*' expression ',' '**' expression
  | ','.expression+ ',' '*' expression
  | ','.expression+ ',' '**' expression
  | '*' expression ',' '**' expression
  | '*' expression
  | '**' expression
  | ','.expression+

func_type_comment:
  | NEWLINE TYPE_COMMENT &(NEWLINE INDENT)
  | TYPE_COMMENT
  
