{-# LANGUAGE OverloadedStrings #-}

module Hydra.Sources.Tier4.Langs.Python.Python3 (python3Module) where

import Hydra.Kernel
import Hydra.Dsl.Grammars
import Hydra.Tools.GrammarToModule
import qualified Hydra.Dsl.Annotations as Ann
import qualified Hydra.Grammar as G

import qualified Data.List as L


python3Module :: Module
python3Module :: Module
python3Module = Namespace -> Grammar -> Maybe String -> Module
grammarToModule Namespace
ns Grammar
python3Grammar (Maybe String -> Module) -> Maybe String -> Module
forall a b. (a -> b) -> a -> b
$
    String -> Maybe String
forall a. a -> Maybe a
Just String
"A Python 3 syntax model, based on the BNF/PEG grammar at https://docs.python.org/3/reference/grammar.html as of 2023-04-03."
  where
    ns :: Namespace
ns = String -> Namespace
Namespace String
"hydra/langs/python/python3"

python3Grammar :: G.Grammar
python3Grammar :: Grammar
python3Grammar = [Production] -> Grammar
G.Grammar ([Production] -> Grammar) -> [Production] -> Grammar
forall a b. (a -> b) -> a -> b
$ [Production]
tokens [Production] -> [Production] -> [Production]
forall a. [a] -> [a] -> [a]
++ [Production]
productions

amp_ :: Pattern
amp_ = String -> Pattern
terminal String
"&"
assign_ :: Pattern
assign_ = String -> Pattern
terminal String
":="
star_ :: Pattern
star_ = String -> Pattern
terminal String
"*"
at_ :: Pattern
at_ = String -> Pattern
terminal String
"@"
close_curly_ :: Pattern
close_curly_ = String -> Pattern
terminal String
"}"
close_paren_ :: Pattern
close_paren_ = String -> Pattern
terminal String
")"
close_square_ :: Pattern
close_square_ = String -> Pattern
terminal String
"]"
colon_ :: Pattern
colon_ = String -> Pattern
terminal String
":"
comma_ :: Pattern
comma_ = String -> Pattern
terminal String
","
dot_ :: Pattern
dot_ = String -> Pattern
terminal String
"."
double_equal_ :: Pattern
double_equal_ = String -> Pattern
terminal String
"=="
double_gt_ :: Pattern
double_gt_ = String -> Pattern
terminal String
">>"
double_lt_ :: Pattern
double_lt_ = String -> Pattern
terminal String
"<<"
double_slash_ :: Pattern
double_slash_ = String -> Pattern
terminal String
"//"
double_star_ :: Pattern
double_star_ = String -> Pattern
terminal String
"**"
ellipsis_ :: Pattern
ellipsis_ = String -> Pattern
terminal String
"..."
endmarker_ :: Pattern
endmarker_ = String -> Pattern
terminal String
""
equal_ :: Pattern
equal_ = String -> Pattern
terminal String
"="
gt_ :: Pattern
gt_ = String -> Pattern
terminal String
">"
gte_ :: Pattern
gte_ = String -> Pattern
terminal String
">="
hat_ :: Pattern
hat_ = String -> Pattern
terminal String
"^"
lt_ :: Pattern
lt_ = String -> Pattern
terminal String
"<"
lte_ :: Pattern
lte_ = String -> Pattern
terminal String
"<="
minus_ :: Pattern
minus_ = String -> Pattern
terminal String
"-"
newline_ :: Pattern
newline_ = String -> Pattern
terminal String
"\n"
noteq_ :: Pattern
noteq_ = String -> Pattern
terminal String
"!="
open_curly_ :: Pattern
open_curly_ = String -> Pattern
terminal String
"{"
open_paren_ :: Pattern
open_paren_ = String -> Pattern
terminal String
"("
open_square_ :: Pattern
open_square_ = String -> Pattern
terminal String
"["
percent_ :: Pattern
percent_ = String -> Pattern
terminal String
"%"
pipe_ :: Pattern
pipe_ = String -> Pattern
terminal String
"|"
plus_ :: Pattern
plus_ = String -> Pattern
terminal String
"+"
right_arrow_ :: Pattern
right_arrow_ = String -> Pattern
terminal String
"->"
semi_ :: Pattern
semi_ = String -> Pattern
terminal String
";"
slash_ :: Pattern
slash_ = String -> Pattern
terminal String
"/"
tilde_ :: Pattern
tilde_ = String -> Pattern
terminal String
"~"
underscore_ :: Pattern
underscore_ = String -> Pattern
terminal String
"_"

tokens :: [G.Production]
tokens :: [Production]
tokens = [
  String -> [Pattern] -> Production
define String
"Async" [String -> Pattern
terminal String
"async"],                -- TODO: not specified in the BNF
  String -> [Pattern] -> Production
define String
"Await" [String -> Pattern
terminal String
"await"],                -- TODO: not specified in the BNF
  String -> [Pattern] -> Production
define String
"Dedent" [String -> Pattern
terminal String
"\n"],                  -- TODO: not specified in the BNF
  String -> [Pattern] -> Production
define String
"Indent" [String -> Pattern
terminal String
"\t"],                  -- TODO: not specified in the BNF
  String -> [Pattern] -> Production
define String
"Name" [String -> Pattern
regex String
"[A-Za-z0-9][A-Za-z0-9_]*"], -- TODO: not specified in the BNF
  String -> [Pattern] -> Production
define String
"Number" [String -> Pattern
regex String
"[0-9]+"],                 -- TODO: not specified in the BNF
  String -> [Pattern] -> Production
define String
"String" [String -> Pattern
regex String
"\"[^\"]*\""],              -- TODO: not specified in the BNF
  String -> [Pattern] -> Production
define String
"TypeComment" [String -> Pattern
terminal String
""]]               -- TODO: not specified in the BNF

productions :: [G.Production]
productions :: [Production]
productions = [
-- # STARTING RULES
-- # ==============

-- file: [statements] ENDMARKER
  String -> [Pattern] -> Production
define String
"File" [
    Pattern -> Pattern
star Pattern
"Statement"],

-- interactive: statement_newline
  String -> [Pattern] -> Production
define String
"Interactive" [
    Pattern
"StatementNewline"],

-- eval: expressions NEWLINE* ENDMARKER
  String -> [Pattern] -> Production
define String
"Eval" [
    [Pattern] -> Pattern
list[Pattern -> Pattern -> Pattern
sepp Pattern
comma_ Pattern
"Expression", Pattern -> Pattern
star Pattern
newline_]],

-- func_type: '(' [type_expressions] ')' '->' expression NEWLINE* ENDMARKER
  String -> [Pattern] -> Production
define String
"FuncType" [Pattern
open_paren_, Pattern -> Pattern
opt Pattern
"TypeExpressions", Pattern
close_paren_, Pattern
right_arrow_, Pattern -> Pattern
star Pattern
newline_, Pattern
endmarker_],

-- fstring: star_expressions
  String -> [Pattern] -> Production
define String
"Fstring" [
    Pattern -> Pattern -> Pattern
sepp Pattern
comma_ Pattern
"StarExpression"],

-- # GENERAL STATEMENTS
-- # ==================

-- statements: statement+

-- statement: compound_stmt  | simple_stmts
  String -> [Pattern] -> Production
define String
"Statement" [
    Pattern
"CompoundStmt",
    Pattern
"SimpleStmts"],

-- statement_newline:
--     | compound_stmt NEWLINE
--     | simple_stmts
--     | NEWLINE
--     | ENDMARKER
  String -> [Pattern] -> Production
define String
"StatementNewline" [
    [Pattern] -> Pattern
list[Pattern
"CompoundStmt", Pattern
newline_],
    Pattern
"SimpleStmts",
    Pattern
newline_,
    Pattern
endmarker_],

-- simple_stmts:
--     | simple_stmt !';' NEWLINE  # Not needed, there for speedup
--     | ';'.simple_stmt+ [';'] NEWLINE
  String -> [Pattern] -> Production
define String
"SimpleStmts" [
    [Pattern] -> Pattern
list [Pattern
"SimpleStmt", Pattern -> Pattern
star([Pattern] -> Pattern
list[Pattern
semi_, Pattern
dot_, Pattern
"SimpleStmt"]), Pattern
newline_]],

-- # NOTE: assignment MUST precede expression, else parsing a simple assignment
-- # will throw a SyntaxError.
-- simple_stmt:
--     | assignment
--     | star_expressions
--     | return_stmt
--     | import_stmt
--     | raise_stmt
--     | 'pass'
--     | del_stmt
--     | yield_stmt
--     | assert_stmt
--     | 'break'
--     | 'continue'
--     | global_stmt
--     | nonlocal_stmt
  String -> [Pattern] -> Production
define String
"SimpleStmt" [
    Pattern
"Assignment",
    Pattern -> Pattern -> Pattern
sepp Pattern
comma_ Pattern
"StarExpression",
    Pattern
"ReturnStmt",
    Pattern
"ImportStmt",
    Pattern
"RaiseStmt",
    String -> Pattern
terminal String
"pass",
    Pattern
"DelStmt",
    Pattern
"YieldStmt",
    Pattern
"AssertStmt",
    String -> Pattern
terminal String
"break",
    String -> Pattern
terminal String
"continue",
    Pattern
"GlobalStmt",
    Pattern
"NonlocalStmt"],

-- compound_stmt:
--     | function_def
--     | if_stmt
--     | class_def
--     | with_stmt
--     | for_stmt
--     | try_stmt
--     | while_stmt
--     | match_stmt
  String -> [Pattern] -> Production
define String
"CompoundStmt" [
    Pattern
"FunctionDef",
    Pattern
"IfStmt",
    Pattern
"ClassDef",
    Pattern
"WithStmt",
    Pattern
"ForStmt",
    Pattern
"TryStmt",
    Pattern
"WhileStmt",
    Pattern
"MatchStmt"],

-- # SIMPLE STATEMENTS
-- # =================

-- # 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_target augassign ~ (yield_expr | star_expressions)
  String -> [Pattern] -> Production
define String
"Assignment" [
    [Pattern] -> Pattern
list[Pattern
"Name", Pattern
colon_, Pattern
"Expression", Pattern -> Pattern
opt([Pattern] -> Pattern
list[Pattern
equal_, Pattern
"AnnotatedRhs"])],
    [Pattern] -> Pattern
list[[Pattern] -> Pattern
alts[[Pattern] -> Pattern
list[Pattern
open_paren_, Pattern
"SingleTarget", Pattern
close_paren_], Pattern
"SingleSubscriptAttributeTarget"], Pattern
colon_, Pattern
"Expression", Pattern -> Pattern
opt([Pattern] -> Pattern
list[Pattern
equal_, Pattern
"AnnotatedRhs"])],
    [Pattern] -> Pattern
list[Pattern -> Pattern
plus([Pattern] -> Pattern
list[Pattern -> Pattern -> Pattern
sepp Pattern
comma_ Pattern
"StarTarget", Pattern
equal_]), [Pattern] -> Pattern
alts[Pattern
"YieldExpr", Pattern -> Pattern -> Pattern
sepp Pattern
comma_ Pattern
"StarExpression"], Pattern -> Pattern
opt(Pattern
"TypeComment")],
    [Pattern] -> Pattern
list[Pattern
"SingleTarget", Pattern
"Augassign", Pattern
tilde_, [Pattern] -> Pattern
alts[Pattern
"YieldExpr", Pattern -> Pattern -> Pattern
sepp Pattern
comma_ Pattern
"StarExpression"]]],

-- annotated_rhs: yield_expr | star_expressions
  String -> [Pattern] -> Production
define String
"AnnotatedRhs" [
    Pattern
"YieldExpr",
    Pattern -> Pattern -> Pattern
sepp Pattern
comma_ Pattern
"StarExpression"],

-- augassign:
--     | '+='
--     | '-='
--     | '*='
--     | '@='
--     | '/='
--     | '%='
--     | '&='
--     | '|='
--     | '^='
--     | '<<='
--     | '>>='
--     | '**='
--     | '//='
  String -> [Pattern] -> Production
define String
"Augassign" [
    String -> Pattern
terminal String
"+=",
    String -> Pattern
terminal String
"-=",
    String -> Pattern
terminal String
"*=",
    String -> Pattern
terminal String
"@=",
    String -> Pattern
terminal String
"/=",
    String -> Pattern
terminal String
"%=",
    String -> Pattern
terminal String
"&=",
    String -> Pattern
terminal String
"|=",
    String -> Pattern
terminal String
"^=",
    String -> Pattern
terminal String
"<<=",
    String -> Pattern
terminal String
">>=",
    String -> Pattern
terminal String
"**=",
    String -> Pattern
terminal String
"//="],

-- return_stmt:
--     | 'return' [star_expressions]
  String -> [Pattern] -> Production
define String
"ReturnStmt" [
    [Pattern] -> Pattern
list [String -> Pattern
terminal String
"return", Pattern -> Pattern
opt(Pattern -> Pattern -> Pattern
sepp Pattern
comma_ Pattern
"StarExpression")]],

-- raise_stmt:
--     | 'raise' expression ['from' expression ]
--     | 'raise'
  String -> [Pattern] -> Production
define String
"RaiseStmt" [
    [Pattern] -> Pattern
list[String -> Pattern
terminal String
"raise", Pattern
"Expression", Pattern -> Pattern
opt([Pattern] -> Pattern
list[String -> Pattern
terminal String
"from", Pattern
"Expression"])],
    String -> Pattern
terminal String
"raise"],

-- global_stmt: 'global' ','.NAME+
  String -> [Pattern] -> Production
define String
"GlobalStmt" [
    [Pattern] -> Pattern
list[String -> Pattern
terminal String
"global", Pattern
comma_, Pattern
dot_, Pattern -> Pattern
plus([Pattern] -> Pattern
list[Pattern
dot_, Pattern
"Name"])]], -- Note: interpreting the above as (.NAME)+, not .(Name+)

-- nonlocal_stmt: 'nonlocal' ','.NAME+
  String -> [Pattern] -> Production
define String
"NonlocalStmt" [
    [Pattern] -> Pattern
list[String -> Pattern
terminal String
"nonlocal", Pattern
comma_, Pattern -> Pattern
plus([Pattern] -> Pattern
list[Pattern
dot_, Pattern
"Name"])]], -- Note: interpreting the above as (.NAME)+, not .(Name+)

-- del_stmt:
--     | 'del' del_targets &(';' | NEWLINE)
  String -> [Pattern] -> Production
define String
"DelStmt" [
    [Pattern] -> Pattern
list[String -> Pattern
terminal String
"del", Pattern
"DelTargets"]],

-- yield_stmt: yield_expr
  String -> [Pattern] -> Production
define String
"YieldStmt" [
    Pattern
"YieldExpr"],

-- assert_stmt: 'assert' expression [',' expression ]
  String -> [Pattern] -> Production
define String
"AssertStmt" [
    [Pattern] -> Pattern
list[String -> Pattern
terminal String
"assert", Pattern
"Expression", Pattern -> Pattern
opt([Pattern] -> Pattern
list[Pattern
comma_, Pattern
"Expression"])]],

-- import_stmt: import_name | import_from
  String -> [Pattern] -> Production
define String
"ImportStmt" [
    Pattern
"ImportName",
    Pattern
"ImportFrom"],

-- # Import statements
-- # -----------------

-- import_name: 'import' dotted_as_names
  String -> [Pattern] -> Production
define String
"ImportName" [
    [Pattern] -> Pattern
list[String -> Pattern
terminal String
"import", Pattern -> Pattern -> Pattern
sep Pattern
comma_ Pattern
"DottedAsName"]],

-- # note below: the ('.' | '...') is necessary because '...' is tokenized as ELLIPSIS
-- import_from:
--     | 'from' ('.' | '...')* dotted_name 'import' import_from_targets
--     | 'from' ('.' | '...')+ 'import' import_from_targets
  String -> [Pattern] -> Production
define String
"ImportFrom" [
    [Pattern] -> Pattern
list[String -> Pattern
terminal String
"from", Pattern -> Pattern
star([Pattern] -> Pattern
alts[Pattern
dot_, Pattern
ellipsis_]), Pattern
"DottedName", String -> Pattern
terminal String
"import", Pattern
"ImportFromTargets"],
    [Pattern] -> Pattern
list[String -> Pattern
terminal String
"from", Pattern -> Pattern
plus([Pattern] -> Pattern
alts[Pattern
dot_, Pattern
ellipsis_]), String -> Pattern
terminal String
"import", Pattern
"ImportFromTargets"]],

-- import_from_targets:
--     | '(' import_from_as_names [','] ')'
--     | import_from_as_names !','
--     | '*'
  String -> [Pattern] -> Production
define String
"ImportFromTargets" [
    [Pattern] -> Pattern
list[Pattern
open_paren_, Pattern
"ImportFromAsNames", Pattern -> Pattern
opt(Pattern
comma_), Pattern
close_paren_],
    Pattern
"ImportFromAsNames"],

-- import_from_as_names:
--     | ','.import_from_as_name+
  String -> [Pattern] -> Production
define String
"ImportFromAsNames" [
    [Pattern] -> Pattern
list[Pattern
comma_, Pattern -> Pattern
plus([Pattern] -> Pattern
list[Pattern
dot_, Pattern
"ImportFromAsName"])]], -- Note: interpreting the above as (.import_from_as_name)+, not .(import_from_as_name+)

-- import_from_as_name:
--     | NAME ['as' NAME ]
  String -> [Pattern] -> Production
define String
"ImportFromAsName" [
    [Pattern] -> Pattern
list[Pattern
"Name", Pattern -> Pattern
opt([Pattern] -> Pattern
list[String -> Pattern
terminal String
"as", Pattern
"Name"])]],

-- dotted_as_names:
--     | ','.dotted_as_name+
-- dotted_as_name:
--     | dotted_name ['as' NAME ]
  String -> [Pattern] -> Production
define String
"DottedAsName" [
    [Pattern] -> Pattern
list[Pattern
"DottedName", Pattern -> Pattern
opt([Pattern] -> Pattern
list[String -> Pattern
terminal String
"as", Pattern
"Name"])]],

-- dotted_name:
--     | dotted_name '.' NAME
--     | NAME
  String -> [Pattern] -> Production
define String
"DottedName" [
    Pattern -> Pattern -> Pattern
sep Pattern
dot_ Pattern
"Name"],

-- # COMPOUND STATEMENTS
-- # ===================

-- # Common elements
-- # ---------------

-- block:
--     | NEWLINE INDENT statements DEDENT
--     | simple_stmts
  String -> [Pattern] -> Production
define String
"Block" [
    [Pattern] -> Pattern
list[Pattern
newline_, Pattern
"Indent", Pattern -> Pattern
star Pattern
"Statement", Pattern
"Dedent"],
    Pattern
"SimpleStmts"],

-- decorators: ('@' named_expression NEWLINE )+
  String -> [Pattern] -> Production
define String
"Decorators" [
    Pattern -> Pattern
plus([Pattern] -> Pattern
list[Pattern
at_, Pattern
"NamedExpression", Pattern
newline_])],

-- # Class definitions
-- # -----------------

-- class_def:
--     | decorators class_def_raw
--     | class_def_raw
  String -> [Pattern] -> Production
define String
"ClassDef" [
    [Pattern] -> Pattern
list[Pattern
"Decorators", Pattern
"ClassDefRaw"],
    Pattern
"ClassDefRaw"],

-- class_def_raw:
--     | 'class' NAME ['(' [arguments] ')' ] ':' block
  String -> [Pattern] -> Production
define String
"ClassDefRaw" [
    [Pattern] -> Pattern
list[String -> Pattern
terminal String
"class", Pattern
"Name", Pattern -> Pattern
opt([Pattern] -> Pattern
list[Pattern
open_paren_, Pattern -> Pattern
opt(Pattern
"Arguments"), Pattern
close_paren_]), Pattern
colon_, Pattern
"Block"]],

-- # Function definitions
-- # --------------------

-- function_def:
--     | decorators function_def_raw
--     | function_def_raw
  String -> [Pattern] -> Production
define String
"FunctionDef" [
    [Pattern] -> Pattern
list[Pattern
"Decorators", Pattern
"FunctionDefRaw"],
    Pattern
"FunctionDefRaw"],

-- function_def_raw:
--     | 'def' NAME '(' [params] ')' ['->' expression ] ':' [func_type_comment] block
--     | ASYNC 'def' NAME '(' [params] ')' ['->' expression ] ':' [func_type_comment] block
  String -> [Pattern] -> Production
define String
"FunctionDefRaw" [
    [Pattern] -> Pattern
list[
      Pattern -> Pattern
opt([Pattern] -> Pattern
list[Pattern
"Async", String -> Pattern
terminal String
"def"]), Pattern
"Name",
      Pattern
open_paren_, Pattern -> Pattern
opt(Pattern
"Parameters"), Pattern
close_paren_,
      Pattern -> Pattern
opt([Pattern] -> Pattern
list[Pattern
right_arrow_, Pattern
"Expression"]),
      Pattern
colon_, Pattern -> Pattern
opt(Pattern
"FuncTypeComment"), Pattern
"Block"]],

-- # Function parameters
-- # -------------------

-- params:
--     | parameters

-- parameters:
--     | slash_no_default param_no_default* param_with_default* [star_etc]
--     | slash_with_default param_with_default* [star_etc]
--     | param_no_default+ param_with_default* [star_etc]
--     | param_with_default+ [star_etc]
--     | star_etc
  String -> [Pattern] -> Production
define String
"Parameters" [
    [Pattern] -> Pattern
list[Pattern
"SlashNoDefault", Pattern -> Pattern
star(Pattern
"ParamNoDefault"), Pattern -> Pattern
star(Pattern
"ParamWithDefault"), Pattern -> Pattern
opt(Pattern
"StarEtc")],
    [Pattern] -> Pattern
list[Pattern
"SlashWithDefault", Pattern -> Pattern
star(Pattern
"ParamWithDefault"), Pattern -> Pattern
opt(Pattern
"StarEtc")],
    [Pattern] -> Pattern
list[Pattern -> Pattern
plus(Pattern
"ParamNoDefault"), Pattern -> Pattern
star(Pattern
"ParamWithDefault"), Pattern -> Pattern
opt(Pattern
"StarEtc")],
    [Pattern] -> Pattern
list[Pattern -> Pattern
plus(Pattern
"ParamWithDefault"), Pattern -> Pattern
opt(Pattern
"StarEtc")],
    Pattern
"StarEtc"],

-- # 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+ '/' &')'
  String -> [Pattern] -> Production
define String
"SlashNoDefault" [
    [Pattern] -> Pattern
list[Pattern -> Pattern
plus(Pattern
"ParamNoDefault"), Pattern
slash_, Pattern -> Pattern
opt(Pattern
comma_)]],

-- slash_with_default:
--     | param_no_default* param_with_default+ '/' ','
--     | param_no_default* param_with_default+ '/' &')'
  String -> [Pattern] -> Production
define String
"SlashWithDefault" [
    [Pattern] -> Pattern
list[Pattern -> Pattern
star(Pattern
"ParamNoDefault"), Pattern -> Pattern
plus(Pattern
"ParamWithDefault"), Pattern
slash_, Pattern -> Pattern
opt(Pattern
comma_)]],

-- star_etc:
--     | '*' param_no_default param_maybe_default* [kwds]
--     | '*' param_no_default_star_annotation param_maybe_default* [kwds]
--     | '*' ',' param_maybe_default+ [kwds]
--     | kwds
  String -> [Pattern] -> Production
define String
"StarEtc" [
    [Pattern] -> Pattern
list[Pattern
star_, Pattern
"ParamNoDefault", Pattern -> Pattern
star(Pattern
"ParamMaybeDefault"), Pattern -> Pattern
opt(Pattern
"Kwds")],
    [Pattern] -> Pattern
list[Pattern
star_, Pattern
"ParamNoDefaultStarAnnotation", Pattern -> Pattern
star(Pattern
"ParamMaybeDefault"), Pattern -> Pattern
opt(Pattern
"Kwds")],
    [Pattern] -> Pattern
list[Pattern
star_, Pattern
comma_, Pattern -> Pattern
plus(Pattern
"ParamMaybeDefault"), Pattern -> Pattern
opt(Pattern
"Kwds")],
    Pattern
"Kwds"],

-- kwds:
--     | '**' param_no_default
  String -> [Pattern] -> Production
define String
"Kwds" [
    [Pattern] -> Pattern
list[Pattern
double_star_, Pattern
"ParamNoDefault"]],

-- # 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? &')'
  String -> [Pattern] -> Production
define String
"ParamNoDefault" [
    [Pattern] -> Pattern
list[Pattern
"Param", Pattern -> Pattern
opt(Pattern
comma_), Pattern -> Pattern
opt(Pattern
"TypeComment")]],

-- param_no_default_star_annotation::r
--     | param_star_annotation ',' TYPE_COMMENT?
--     | param_star_annotation TYPE_COMMENT? &')'
  String -> [Pattern] -> Production
define String
"ParamNoDefaultStarAnnotation" [
    [Pattern] -> Pattern
list[Pattern
"ParamStarAnnotation", Pattern -> Pattern
opt(Pattern
comma_), Pattern -> Pattern
opt(Pattern
"TypeComment")]],

-- param_with_default:
--     | param default ',' TYPE_COMMENT?
--     | param default TYPE_COMMENT? &')'
  String -> [Pattern] -> Production
define String
"ParamWithDefault" [
    [Pattern] -> Pattern
list[Pattern
"Param", Pattern
"Default", Pattern -> Pattern
opt(Pattern
comma_), Pattern -> Pattern
opt(Pattern
"TypeComment")]],

-- param_maybe_default:
--     | param default? ',' TYPE_COMMENT?
--     | param default? TYPE_COMMENT? &')'
  String -> [Pattern] -> Production
define String
"ParamMaybeDefault" [
    [Pattern] -> Pattern
list[Pattern
"Param", Pattern -> Pattern
opt(Pattern
"Default"), Pattern -> Pattern
opt(Pattern
comma_), Pattern -> Pattern
opt(Pattern
"TypeComment")]],

-- param: NAME annotation?
  String -> [Pattern] -> Production
define String
"Param" [
    [Pattern] -> Pattern
list[Pattern
"Name", Pattern -> Pattern
opt(Pattern
"Annotation")]],

-- param_star_annotation: NAME star_annotation
  String -> [Pattern] -> Production
define String
"ParamStarAnnotation" [
    [Pattern] -> Pattern
list[Pattern
"Name", Pattern
"StarAnnotation"]],

-- annotation: ':' expression
  String -> [Pattern] -> Production
define String
"Annotation" [
    [Pattern] -> Pattern
list[Pattern
colon_, Pattern
"Expression"]],

-- star_annotation: ':' star_expression
  String -> [Pattern] -> Production
define String
"StarAnnotation" [
    [Pattern] -> Pattern
list[Pattern
colon_, Pattern
"StarExpression"]],

-- default: '=' expression  | invalid_default
  String -> [Pattern] -> Production
define String
"Default" [
    [Pattern] -> Pattern
list[Pattern
equal_, Pattern
"Expression"]],
    -- "InvalidDefault"], -- TODO: invalid_default is referenced but not defined in the source grammar

-- # If statement
-- # ------------

-- if_stmt:
--     | 'if' named_expression ':' block elif_stmt
--     | 'if' named_expression ':' block [else_block]
  String -> [Pattern] -> Production
define String
"IfStmt" [
    [Pattern] -> Pattern
list[String -> Pattern
terminal String
"if", Pattern
"NamedExpression", Pattern
colon_, Pattern
"Block", [Pattern] -> Pattern
alts[Pattern
"ElifStmt", Pattern
"ElseBlock"]]],

-- elif_stmt:
--     | 'elif' named_expression ':' block elif_stmt
--     | 'elif' named_expression ':' block [else_block]
  String -> [Pattern] -> Production
define String
"ElifStmt" [
    [Pattern] -> Pattern
list[String -> Pattern
terminal String
"elif", Pattern
"NamedExpression", Pattern
colon_, Pattern
"Block", [Pattern] -> Pattern
alts[Pattern
"ElifStmt", Pattern
"ElseBlock"]]],

-- else_block:
--     | 'else' ':' block
  String -> [Pattern] -> Production
define String
"ElseBlock" [
    [Pattern] -> Pattern
list[String -> Pattern
terminal String
"else", Pattern
colon_, Pattern
"Block"]],

-- # While statement
-- # ---------------

-- while_stmt:
--     | 'while' named_expression ':' block [else_block]
  String -> [Pattern] -> Production
define String
"WhileStmt" [
    [Pattern] -> Pattern
list[String -> Pattern
terminal String
"while", Pattern
"NamedExpression", Pattern
colon_, Pattern
"Block", Pattern -> Pattern
opt(Pattern
"ElseBlock")]],

-- # For statement
-- # -------------

-- 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]
  String -> [Pattern] -> Production
define String
"ForStmt" [
    [Pattern] -> Pattern
list[Pattern -> Pattern
opt(Pattern
"Async"), String -> Pattern
terminal String
"for", Pattern -> Pattern -> Pattern
sepp Pattern
comma_ Pattern
"StarTarget", String -> Pattern
terminal String
"in", Pattern
tilde_, Pattern -> Pattern -> Pattern
sepp Pattern
comma_ Pattern
"StarExpression", Pattern
colon_, Pattern -> Pattern
opt(Pattern
"TypeComment"), Pattern
"Block", Pattern -> Pattern
opt(Pattern
"ElseBlock")]],

-- # With statement
-- # --------------

-- with_stmt:
--     | 'with' '(' ','.with_item+ ','? ')' ':' block
--     | 'with' ','.with_item+ ':' [TYPE_COMMENT] block
--     | ASYNC 'with' '(' ','.with_item+ ','? ')' ':' block
--     | ASYNC 'with' ','.with_item+ ':' [TYPE_COMMENT] block
  String -> [Pattern] -> Production
define String
"WithStmt" [
    [Pattern] -> Pattern
list[Pattern -> Pattern
opt(Pattern
"Async"), String -> Pattern
terminal String
"with", [Pattern] -> Pattern
alts[
      [Pattern] -> Pattern
list[Pattern
open_paren_, Pattern -> Pattern -> Pattern
sepp Pattern
comma_ Pattern
"WithItem", Pattern
close_paren_, Pattern
colon_],
      [Pattern] -> Pattern
list[Pattern -> Pattern -> Pattern
sepp Pattern
comma_ Pattern
"WithItem", Pattern
colon_, Pattern -> Pattern
opt(Pattern
"TypeComment")]], Pattern
"Block"]],

-- with_item:
--     | expression 'as' star_target &(',' | ')' | ':')
--     | expression
  String -> [Pattern] -> Production
define String
"WithItem" [
    [Pattern] -> Pattern
list[Pattern
"Expression", Pattern -> Pattern
opt([Pattern] -> Pattern
list[String -> Pattern
terminal String
"as", Pattern
"StarTarget"])]],

-- # Try statement
-- # -------------

-- try_stmt:
--     | 'try' ':' block finally_block
--     | 'try' ':' block except_block+ [else_block] [finally_block]
--     | 'try' ':' block except_star_block+ [else_block] [finally_block]
  String -> [Pattern] -> Production
define String
"TryStmt" [
    [Pattern] -> Pattern
list[String -> Pattern
terminal String
"try", Pattern
colon_, Pattern
"Block", [Pattern] -> Pattern
alts[
      Pattern
"FinallyBlock",
      [Pattern] -> Pattern
list[Pattern -> Pattern
plus(Pattern
"ExceptBlock"), Pattern -> Pattern
opt(Pattern
"ElseBlock"), Pattern -> Pattern
opt(Pattern
"FinallyBlock")],
      [Pattern] -> Pattern
list[Pattern -> Pattern
plus(Pattern
"ExceptStarBlock"), Pattern -> Pattern
opt(Pattern
"ElseBlock"), Pattern -> Pattern
opt(Pattern
"FinallyBlock")]]]],

-- # Except statement
-- # ----------------

-- except_block:
--     | 'except' expression ['as' NAME ] ':' block
--     | 'except' ':' block
  String -> [Pattern] -> Production
define String
"ExceptBlock" [
    [Pattern] -> Pattern
list[String -> Pattern
terminal String
"except", Pattern -> Pattern
opt([Pattern] -> Pattern
list[Pattern
"Expression", Pattern -> Pattern
opt([Pattern] -> Pattern
list[String -> Pattern
terminal String
"as", Pattern
"Name"])]), Pattern
colon_, Pattern
"Block"]],

-- except_star_block:
--     | 'except' '*' expression ['as' NAME ] ':' block
  String -> [Pattern] -> Production
define String
"ExceptStarBlock" [
    [Pattern] -> Pattern
list[String -> Pattern
terminal String
"except", Pattern
star_, Pattern
"Expression", Pattern -> Pattern
opt([Pattern] -> Pattern
list[String -> Pattern
terminal String
"as", Pattern
"Name"]), Pattern
colon_, Pattern
"Block"]],

-- finally_block:
--     | 'finally' ':' block
  String -> [Pattern] -> Production
define String
"FinallyBlock" [
    [Pattern] -> Pattern
list[String -> Pattern
terminal String
"finally", Pattern
colon_, Pattern
"Block"]],

-- # Match statement
-- # ---------------

-- match_stmt:
--     | "match" subject_expr ':' NEWLINE INDENT case_block+ DEDENT
  String -> [Pattern] -> Production
define String
"MatchStmt" [
    [Pattern] -> Pattern
list[String -> Pattern
terminal String
"match", Pattern
"SubjectExpr", Pattern
colon_, Pattern
newline_, Pattern
"Indent", Pattern -> Pattern
plus(Pattern
"CaseBlock"), Pattern
"Dedent"]],

-- subject_expr:
--     | star_named_expression ',' star_named_expressions?
--     | named_expression
  String -> [Pattern] -> Production
define String
"SubjectExpr" [
    [Pattern] -> Pattern
list[Pattern
"StarNamedExpression", Pattern
comma_, Pattern -> Pattern
opt(Pattern -> Pattern -> Pattern
sepp Pattern
comma_ Pattern
"StarNamedExpression")]],

-- case_block:
--     | "case" patterns guard? ':' block
  String -> [Pattern] -> Production
define String
"CaseBlock" [
    [Pattern] -> Pattern
list[String -> Pattern
terminal String
"case", Pattern
"Patterns", Pattern -> Pattern
opt(Pattern
"Guard"), Pattern
colon_, Pattern
"Block"]],

-- guard: 'if' named_expression
  String -> [Pattern] -> Production
define String
"Guard" [
    [Pattern] -> Pattern
list[String -> Pattern
terminal String
"if", Pattern
"NamedExpression"]],

-- patterns:
--     | open_sequence_pattern
--     | pattern
  String -> [Pattern] -> Production
define String
"Patterns" [
    Pattern
"OpenSequencePattern",
    Pattern
"Pattern"],

-- pattern:
--     | as_pattern
--     | or_pattern
  String -> [Pattern] -> Production
define String
"Pattern" [
    Pattern
"AsPattern",
    Pattern
"OrPattern"],

-- as_pattern:
--     | or_pattern 'as' pattern_capture_target
  String -> [Pattern] -> Production
define String
"AsPattern" [
    [Pattern] -> Pattern
list[Pattern
"OrPattern", String -> Pattern
terminal String
"as", Pattern
"PatternCaptureTarget"]],

-- or_pattern:
--     | '|'.closed_pattern+
  String -> [Pattern] -> Production
define String
"OrPattern" [
    [Pattern] -> Pattern
list[Pattern
pipe_, Pattern -> Pattern -> Pattern
sep Pattern
dot_ Pattern
"ClosedPattern"]],

-- closed_pattern:
--     | literal_pattern
--     | capture_pattern
--     | wildcard_pattern
--     | value_pattern
--     | group_pattern
--     | sequence_pattern
--     | mapping_pattern
--     | class_pattern
  String -> [Pattern] -> Production
define String
"ClosedPattern" [
    Pattern
"LiteralPattern",
    Pattern
"CapturePattern",
    Pattern
"WildcardPattern",
    Pattern
"ValuePattern",
    Pattern
"GroupPattern",
    Pattern
"SequencePattern",
    Pattern
"MappingPattern",
    Pattern
"ClassPattern"],

-- # Literal patterns are used for equality and identity constraints
-- literal_pattern:
--     | signed_number !('+' | '-')
--     | complex_number
--     | strings
--     | 'None'
--     | 'True'
--     | 'False'
  String -> [Pattern] -> Production
define String
"LiteralPattern" [
    Pattern
"SignedNumber",
    Pattern
"ComplexNumber",
    Pattern -> Pattern
plus(Pattern
"String"),
    String -> Pattern
terminal String
"None",
    String -> Pattern
terminal String
"True",
    String -> Pattern
terminal String
"False"],

-- # Literal expressions are used to restrict permitted mapping pattern keys
-- literal_expr:
--     | signed_number !('+' | '-')
--     | complex_number
--     | strings
--     | 'None'
--     | 'True'
--     | 'False'

-- complex_number:
--     | signed_real_number '+' imaginary_number
--     | signed_real_number '-' imaginary_number
  String -> [Pattern] -> Production
define String
"ComplexNumber" [
    [Pattern] -> Pattern
list[Pattern
"SignedRealNumber", [Pattern] -> Pattern
alts[Pattern
plus_, Pattern
minus_], Pattern
"ImaginaryNumber"]],

-- signed_number:
--     | NUMBER
--     | '-' NUMBER
  String -> [Pattern] -> Production
define String
"SignedNumber" [
    [Pattern] -> Pattern
list[Pattern -> Pattern
opt(Pattern
minus_), Pattern
"Number"]],

-- signed_real_number:
--     | real_number
--     | '-' real_number
  String -> [Pattern] -> Production
define String
"SignedRealNumber" [
    [Pattern] -> Pattern
list[Pattern -> Pattern
opt(Pattern
minus_), Pattern
"RealNumber"]],

-- real_number:
--     | NUMBER
  String -> [Pattern] -> Production
define String
"RealNumber" [
    Pattern
"Number"],

-- imaginary_number:
--     | NUMBER
  String -> [Pattern] -> Production
define String
"ImaginaryNumber" [
    Pattern
"Number"],

-- capture_pattern:
--     | pattern_capture_target
  String -> [Pattern] -> Production
define String
"CapturePattern" [
    Pattern
"PatternCaptureTarget"],

-- pattern_capture_target:
--     | !"_" NAME !('.' | '(' | '=')
  String -> [Pattern] -> Production
define String
"PatternCaptureTarget" [
    Pattern
"Name"],

-- wildcard_pattern:
--     | "_"
  String -> [Pattern] -> Production
define String
"WildcardPattern" [
    Pattern
underscore_],

-- value_pattern:
--     | attr !('.' | '(' | '=')
  String -> [Pattern] -> Production
define String
"ValuePattern" [
    Pattern
"Attr"],

-- attr:
--     | name_or_attr '.' NAME
  String -> [Pattern] -> Production
define String
"Attr" [
    [Pattern] -> Pattern
list[Pattern
"NameOrAttr", Pattern
dot_, Pattern
"Name"]],

-- name_or_attr:
--     | attr
--     | NAME
  String -> [Pattern] -> Production
define String
"NameOrAttr" [
    Pattern
"Attr",
    Pattern
"Name"],

-- group_pattern:
--     | '(' pattern ')'
  String -> [Pattern] -> Production
define String
"GroupPattern" [
    [Pattern] -> Pattern
list[Pattern
open_paren_, Pattern
"Pattern", Pattern
close_paren_]],

-- sequence_pattern:
--     | '[' maybe_sequence_pattern? ']'
--     | '(' open_sequence_pattern? ')'
  String -> [Pattern] -> Production
define String
"SequencePattern" [
    [Pattern] -> Pattern
list[Pattern
open_square_, Pattern -> Pattern
opt(Pattern
"MaybeSequencePattern"), Pattern
close_square_],
    [Pattern] -> Pattern
list[Pattern
open_paren_, Pattern -> Pattern
opt(Pattern
"MaybeSequencePattern"), Pattern
close_paren_]],

-- open_sequence_pattern:
--     | maybe_star_pattern ',' maybe_sequence_pattern?
  String -> [Pattern] -> Production
define String
"OpenSequencePattern" [
    [Pattern] -> Pattern
list[Pattern
"MaybeStarPattern", Pattern
comma_, Pattern -> Pattern
opt(Pattern
"MaybeSequencePattern")]],

-- maybe_sequence_pattern:
--     | ','.maybe_star_pattern+ ','?
  String -> [Pattern] -> Production
define String
"MaybeSequencePattern" [
    Pattern -> Pattern -> Pattern
forall a b. a -> b -> b
seq Pattern
comma_ Pattern
"MaybeStarPattern"],

-- maybe_star_pattern:
--     | star_pattern
--     | pattern
  String -> [Pattern] -> Production
define String
"MaybeStarPattern" [
    Pattern
"StarPattern",
    Pattern
"Pattern"],

-- star_pattern:
--     | '*' pattern_capture_target
--     | '*' wildcard_pattern
  String -> [Pattern] -> Production
define String
"StarPattern" [
    [Pattern] -> Pattern
list[Pattern
star_, [Pattern] -> Pattern
alts[Pattern
"PatternCaptureTarget", Pattern
"WildcardPattern"]]],

-- mapping_pattern:
--     | '{' '}'
--     | '{' double_star_pattern ','? '}'
--     | '{' items_pattern ',' double_star_pattern ','? '}'
--     | '{' items_pattern ','? '}'
  String -> [Pattern] -> Production
define String
"MappingPattern" [
    String
"empty"String -> Pattern -> Pattern
>: [Pattern] -> Pattern
list[Pattern
open_curly_, Pattern
close_curly_],
    [Pattern] -> Pattern
list[Pattern
open_curly_, Pattern
"DoubleStarPattern", Pattern -> Pattern
opt(Pattern
comma_), Pattern
close_curly_],
    [Pattern] -> Pattern
list[Pattern
open_curly_, Pattern
"ItemsPattern", Pattern
comma_, Pattern
"DoubleStarPattern", Pattern -> Pattern
opt(Pattern
comma_), Pattern
close_curly_],
    [Pattern] -> Pattern
list[Pattern
open_curly_, Pattern
"ItemsPattern", Pattern -> Pattern
opt(Pattern
comma_), Pattern
close_curly_]],

-- items_pattern:
--     | ','.key_value_pattern+
  String -> [Pattern] -> Production
define String
"ItemsPattern" [
    Pattern -> Pattern -> Pattern
sep Pattern
comma_ Pattern
"KeyValuePattern"],

-- key_value_pattern:
--     | (literal_expr | attr) ':' pattern
  String -> [Pattern] -> Production
define String
"KeyValuePattern" [
    [Pattern] -> Pattern
list[[Pattern] -> Pattern
alts[Pattern
"LiteralPattern", Pattern
"Attr"], Pattern
colon_, Pattern
"Pattern"]],

-- double_star_pattern:
--     | '**' pattern_capture_target
  String -> [Pattern] -> Production
define String
"DoubleStarPattern" [
    [Pattern] -> Pattern
list[Pattern
double_star_, Pattern
"PatternCaptureTarget"]],

-- class_pattern:
--     | name_or_attr '(' ')'
--     | name_or_attr '(' positional_patterns ','? ')'
--     | name_or_attr '(' keyword_patterns ','? ')'
--     | name_or_attr '(' positional_patterns ',' keyword_patterns ','? ')'
  String -> [Pattern] -> Production
define String
"ClassPattern" [
    [Pattern] -> Pattern
list[Pattern
"NameOrAttr", Pattern
open_paren_, [Pattern] -> Pattern
alts[
      Pattern
nil,
      [Pattern] -> Pattern
list[Pattern -> Pattern -> Pattern
forall a b. a -> b -> b
seq Pattern
comma_ Pattern
"Pattern", Pattern -> Pattern
opt(Pattern
comma_)],
      [Pattern] -> Pattern
list[Pattern -> Pattern -> Pattern
forall a b. a -> b -> b
seq Pattern
comma_ Pattern
"KeywordPattern", Pattern -> Pattern
opt(Pattern
comma_)],
      [Pattern] -> Pattern
list[Pattern -> Pattern -> Pattern
forall a b. a -> b -> b
seq Pattern
comma_ Pattern
"Pattern", Pattern
comma_, Pattern -> Pattern -> Pattern
forall a b. a -> b -> b
seq Pattern
comma_ Pattern
"KeywordPattern", Pattern -> Pattern
opt(Pattern
comma_)]
    ], Pattern
close_paren_]],

-- positional_patterns:
--     | ','.pattern+
-- keyword_patterns:
--     | ','.keyword_pattern+
-- keyword_pattern:
--     | NAME '=' pattern
  String -> [Pattern] -> Production
define String
"KeywordPattern" [
    [Pattern] -> Pattern
list[Pattern
"Name", Pattern
equal_, Pattern
"Pattern"]],
    
-- # EXPRESSIONS
-- # -----------

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

-- expression:
--     | disjunction 'if' disjunction 'else' expression
--     | disjunction
--     | lambdef
  String -> [Pattern] -> Production
define String
"Expression" [
    [Pattern] -> Pattern
list[Pattern
"Disjunction", String -> Pattern
terminal String
"if", Pattern
"Disjunction", String -> Pattern
terminal String
"else", Pattern
"Expression"],
    Pattern
"Disjunction",
    Pattern
"Lambdef"],
    
-- yield_expr:
--     | 'yield' 'from' expression
--     | 'yield' [star_expressions]
  String -> [Pattern] -> Production
define String
"YieldExpr" [
    [Pattern] -> Pattern
list[String -> Pattern
terminal String
"yield", [Pattern] -> Pattern
alts[[Pattern] -> Pattern
list[String -> Pattern
terminal String
"from", Pattern
"Expression"], Pattern -> Pattern
opt(Pattern -> Pattern -> Pattern
sepp Pattern
comma_ Pattern
"StarExpression")]]],
    
-- star_expressions:
--     | star_expression (',' star_expression )+ [',']
--     | star_expression ','
--     | star_expression

-- star_expression:
--     | '*' bitwise_or
--     | expression
  String -> [Pattern] -> Production
define String
"StarExpression" [
    [Pattern] -> Pattern
list[Pattern
star_, Pattern
"BitwiseOr"],
    Pattern
"Expression"],
    
-- star_named_expressions: ','.star_named_expression+ [',']
--
-- star_named_expression:
--     | '*' bitwise_or
--     | named_expression
  String -> [Pattern] -> Production
define String
"StarNamedExpression" [
    [Pattern] -> Pattern
list[Pattern
star_, Pattern
"BitwiseOr"],
    Pattern
"NamedExpression"],
    
-- assignment_expression:
--     | NAME ':=' ~ expression
  String -> [Pattern] -> Production
define String
"AssignmentExpression" [
    [Pattern] -> Pattern
list[Pattern
"Name", Pattern
assign_, Pattern
tilde_, Pattern
"Expression"]],
    
-- named_expression:
--     | assignment_expression
--     | expression !':='
  String -> [Pattern] -> Production
define String
"NamedExpression" [
    Pattern
"AssignmentExpression",
    Pattern
"Expression"],
    
-- disjunction:
--     | conjunction ('or' conjunction )+
--     | conjunction
  String -> [Pattern] -> Production
define String
"Disjunction" [
    Pattern -> Pattern -> Pattern
sep (String -> Pattern
terminal String
"or") Pattern
"Conjunction"],
 
-- conjunction:
--     | inversion ('and' inversion )+
--     | inversion
  String -> [Pattern] -> Production
define String
"Conjunction" [
    Pattern -> Pattern -> Pattern
sep (String -> Pattern
terminal String
"and") Pattern
"Inversion"],
    
-- inversion:
--     | 'not' inversion
--     | comparison
  String -> [Pattern] -> Production
define String
"Inversion" [
    [Pattern] -> Pattern
list[String -> Pattern
terminal String
"not", Pattern
"Inversion"],
    Pattern
"Comparison"],
    
-- # Comparison operators
-- # --------------------

-- comparison:
--     | bitwise_or compare_op_bitwise_or_pair+
--     | bitwise_or
  String -> [Pattern] -> Production
define String
"Comparison" [
    [Pattern] -> Pattern
list[Pattern
"BitwiseOr", Pattern -> Pattern
star(Pattern
"CompareOpBitwiseOrPair")]],
    
-- 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
  String -> [Pattern] -> Production
define String
"CompareOpBitwiseOrPair" [
    Pattern
"EqBitwiseOr",
    Pattern
"NoteqBitwiseOr",
    Pattern
"LteBitwiseOr",
    Pattern
"LtBitwiseOr",
    Pattern
"GteBitwiseOr",
    Pattern
"GtBitwiseOr",
    Pattern
"NotinBitwiseOr",
    Pattern
"InBitwiseOr",
    Pattern
"IsnotBitwiseOr",
    Pattern
"IsBitwiseOr"],
    
-- eq_bitwise_or: '==' bitwise_or
  String -> [Pattern] -> Production
define String
"EqBitwiseOr" [
    [Pattern] -> Pattern
list[Pattern
double_equal_, Pattern
"BitwiseOr"]],
    
-- noteq_bitwise_or:
--     | ('!=' ) bitwise_or
  String -> [Pattern] -> Production
define String
"NoteqBitwiseOr" [
    [Pattern] -> Pattern
list[Pattern
noteq_, Pattern
"BitwiseOr"]],

-- lte_bitwise_or: '<=' bitwise_or
  String -> [Pattern] -> Production
define String
"LteBitwiseOr" [
    [Pattern] -> Pattern
list[Pattern
lte_, Pattern
"BitwiseOr"]],

-- lt_bitwise_or: '<' bitwise_or
  String -> [Pattern] -> Production
define String
"LtBitwiseOr" [
    [Pattern] -> Pattern
list[Pattern
lt_, Pattern
"BitwiseOr"]],

-- gte_bitwise_or: '>=' bitwise_or
  String -> [Pattern] -> Production
define String
"GteBitwiseOr" [
    [Pattern] -> Pattern
list[Pattern
gte_, Pattern
"BitwiseOr"]],

-- gt_bitwise_or: '>' bitwise_or
  String -> [Pattern] -> Production
define String
"GtBitwiseOr" [
    [Pattern] -> Pattern
list[Pattern
gt_, Pattern
"BitwiseOr"]],

-- notin_bitwise_or: 'not' 'in' bitwise_or
  String -> [Pattern] -> Production
define String
"NotinBitwiseOr" [
    [Pattern] -> Pattern
list[String -> Pattern
terminal String
"not", String -> Pattern
terminal String
"in", Pattern
"BitwiseOr"]],

-- in_bitwise_or: 'in' bitwise_or
  String -> [Pattern] -> Production
define String
"InBitwiseOr" [
    [Pattern] -> Pattern
list[String -> Pattern
terminal String
"in", Pattern
"BitwiseOr"]],

-- isnot_bitwise_or: 'is' 'not' bitwise_or
  String -> [Pattern] -> Production
define String
"IsnotBitwiseOr" [
    [Pattern] -> Pattern
list[String -> Pattern
terminal String
"is", String -> Pattern
terminal String
"not", Pattern
"BitwiseOr"]],

-- is_bitwise_or: 'is' bitwise_or
  String -> [Pattern] -> Production
define String
"IsBitwiseOr" [
    [Pattern] -> Pattern
list[String -> Pattern
terminal String
"is", Pattern
"BitwiseOr"]],

-- # Bitwise operators
-- # -----------------

-- bitwise_or:
--     | bitwise_or '|' bitwise_xor
--     | bitwise_xor
  String -> [Pattern] -> Production
define String
"BitwiseOr" [
    [Pattern] -> Pattern
list[Pattern -> Pattern
opt([Pattern] -> Pattern
list[Pattern
"BitwiseOr", Pattern
pipe_]), Pattern
"BitwiseXor"]],

-- bitwise_xor:
--     | bitwise_xor '^' bitwise_and
--     | bitwise_and
  String -> [Pattern] -> Production
define String
"BitwiseXor" [
    [Pattern] -> Pattern
list[Pattern -> Pattern
opt([Pattern] -> Pattern
list[Pattern
"BitwiseXor", Pattern
hat_]), Pattern
"BitwiseAnd"]],
    
-- bitwise_and:
--     | bitwise_and '&' shift_expr
--     | shift_expr
  String -> [Pattern] -> Production
define String
"BitwiseAnd" [
    [Pattern] -> Pattern
list[Pattern -> Pattern
opt([Pattern] -> Pattern
list[Pattern
"BitwiseAnd", Pattern
amp_]), Pattern
"ShiftExpr"]],
    
-- shift_expr:
--     | shift_expr '<<' sum
--     | shift_expr '>>' sum
--     | sum
  String -> [Pattern] -> Production
define String
"ShiftExpr" [
    [Pattern] -> Pattern
list[
      Pattern -> Pattern
opt([Pattern] -> Pattern
list[Pattern
"ShiftExpr", [Pattern] -> Pattern
alts[Pattern
double_lt_, Pattern
double_gt_]]),
      Pattern
"Sum"]],
    
-- # Arithmetic operators
-- # --------------------

-- sum:
--     | sum '+' term
--     | sum '-' term
--     | term
  String -> [Pattern] -> Production
define String
"Sum" [
    [Pattern] -> Pattern
list[Pattern -> Pattern
opt([Pattern] -> Pattern
list[Pattern
"Sum", [Pattern] -> Pattern
alts[Pattern
plus_, Pattern
minus_]]), Pattern
"Term"]],
    
-- term:
--     | term '*' factor
--     | term '/' factor
--     | term '//' factor
--     | term '%' factor
--     | term '@' factor
--     | factor
  String -> [Pattern] -> Production
define String
"Term" [
    [Pattern] -> Pattern
list[Pattern -> Pattern
opt([Pattern] -> Pattern
list[Pattern
"Term", [Pattern] -> Pattern
alts[Pattern
star_, Pattern
slash_, Pattern
double_slash_, Pattern
percent_, Pattern
at_]]), Pattern
"Factor"]],
    
-- factor:
--     | '+' factor
--     | '-' factor
--     | '~' factor
--     | power
  String -> [Pattern] -> Production
define String
"Factor" [
    [Pattern] -> Pattern
list[[Pattern] -> Pattern
alts[Pattern
plus_, Pattern
minus_, Pattern
tilde_], Pattern
"Factor"],
    Pattern
"Power"],

-- power:
--     | await_primary '**' factor
--     | await_primary
  String -> [Pattern] -> Production
define String
"Power" [
    [Pattern] -> Pattern
list[Pattern
"AwaitPrimary", Pattern -> Pattern
opt([Pattern] -> Pattern
list[Pattern
double_star_, Pattern
"Factor"])]],

-- # Primary elements
-- # ----------------

-- # Primary elements are things like "obj.something.something", "obj[something]", "obj(something)", "obj" ...

-- await_primary:
--     | AWAIT primary
--     | primary
  String -> [Pattern] -> Production
define String
"AwaitPrimary" [
    [Pattern] -> Pattern
list[Pattern -> Pattern
opt(Pattern
"Await"), Pattern
"Primary"]],

-- primary:
--     | primary '.' NAME
--     | primary genexp
--     | primary '(' [arguments] ')'
--     | primary '[' slices ']'
--     | atom
  String -> [Pattern] -> Production
define String
"Primary" [
    [Pattern] -> Pattern
list[Pattern
"Primary", [Pattern] -> Pattern
alts[
      [Pattern] -> Pattern
list[Pattern
dot_, Pattern
"Name"],
      Pattern
"Genexp",
      [Pattern] -> Pattern
list[Pattern
open_paren_, Pattern -> Pattern
opt(Pattern
"Arguments"), Pattern
close_paren_],
      [Pattern] -> Pattern
list[Pattern
open_square_, Pattern
"Slices", Pattern
close_square_]]],
    Pattern
"Atom"],

-- slices:
--     | slice !','
--     | ','.(slice | starred_expression)+ [',']
  String -> [Pattern] -> Production
define String
"Slices" [
    Pattern
"Slice",
    Pattern -> Pattern -> Pattern
sepp Pattern
comma_ ([Pattern] -> Pattern
alts[Pattern
"Slice", Pattern
"StarredExpression"])],

-- slice:
--     | [expression] ':' [expression] [':' [expression] ]
--     | named_expression
  String -> [Pattern] -> Production
define String
"Slice" [
    [Pattern] -> Pattern
list[Pattern -> Pattern
opt(Pattern
"Expression"), Pattern
colon_, Pattern -> Pattern
opt(Pattern
"Expression"), Pattern -> Pattern
opt([Pattern] -> Pattern
list[Pattern
colon_, Pattern -> Pattern
opt(Pattern
"Expression")])],
    Pattern
"NamedExpression"],

-- atom:
--     | NAME
--     | 'True'
--     | 'False'
--     | 'None'
--     | strings
--     | NUMBER
--     | (tuple | group | genexp)
--     | (list | listcomp)
--     | (dict | set | dictcomp | setcomp)
--     | '...'
  String -> [Pattern] -> Production
define String
"Atom" [
    Pattern
"Name",
    String -> Pattern
terminal String
"True",
    String -> Pattern
terminal String
"False",
    String -> Pattern
terminal String
"None",
    Pattern -> Pattern
plus(Pattern
"String"),
    Pattern
"Number",
    Pattern
"Tuple",
    Pattern
"Group",
    Pattern
"Genexp",
    Pattern
"List",
    Pattern
"Listcomp",
    Pattern
"Dict",
    Pattern
"Set",
    Pattern
"Dictcomp",
    Pattern
"Setcomp",
    Pattern
ellipsis_],

-- group:
--     | '(' (yield_expr | named_expression) ')'
  String -> [Pattern] -> Production
define String
"Group" [
    [Pattern] -> Pattern
list[Pattern
open_paren_, [Pattern] -> Pattern
alts[Pattern
"YieldExpr", Pattern
"NamedExpression"], Pattern
close_paren_]],

-- # Lambda functions
-- # ----------------

-- lambdef:
--     | 'lambda' [lambda_params] ':' expression
  String -> [Pattern] -> Production
define String
"Lambdef" [
    [Pattern] -> Pattern
list[String -> Pattern
terminal String
"lambda", Pattern -> Pattern
opt(Pattern
"LambdaParameters"), Pattern
colon_, Pattern
"Expression"]],

-- lambda_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_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
  String -> [Pattern] -> Production
define String
"LambdaParameters" [
    [Pattern] -> Pattern
list[Pattern
"LambdaSlashNoDefault", Pattern -> Pattern
star(Pattern
"LambdaParamNoDefault"), Pattern -> Pattern
star(Pattern
"LambdaParamWithDefault"), Pattern -> Pattern
opt(Pattern
"LambdaStarEtc")],
    [Pattern] -> Pattern
list[Pattern
"LambdaSlashWithDefault", Pattern -> Pattern
star(Pattern
"LambdaParamWithDefault"), Pattern -> Pattern
opt(Pattern
"LambdaStarEtc")],
    [Pattern] -> Pattern
list[Pattern -> Pattern
plus(Pattern
"LambdaParamNoDefault"), Pattern -> Pattern
star(Pattern
"LambdaParamWithDefault"), Pattern -> Pattern
opt(Pattern
"LambdaStarEtc")],
    [Pattern] -> Pattern
list[Pattern -> Pattern
plus(Pattern
"LambdaParamWithDefault"), Pattern -> Pattern
opt(Pattern
"LambdaStarEtc")],
    Pattern
"LambdaStarEtc"],

-- lambda_slash_no_default:
--     | lambda_param_no_default+ '/' ','
--     | lambda_param_no_default+ '/' &':'
  String -> [Pattern] -> Production
define String
"LambdaSlashNoDefault" [
    [Pattern] -> Pattern
list[Pattern -> Pattern
plus(Pattern
"LambdaParamNoDefault"), Pattern
slash_, Pattern -> Pattern
opt(Pattern
comma_)]],

-- lambda_slash_with_default:
--     | lambda_param_no_default* lambda_param_with_default+ '/' ','
--     | lambda_param_no_default* lambda_param_with_default+ '/' &':'
  String -> [Pattern] -> Production
define String
"LambdaSlashWithDefault" [
    [Pattern] -> Pattern
list[Pattern -> Pattern
star(Pattern
"LambdaParamNoDefault"), Pattern -> Pattern
plus(Pattern
"LambdaParamWithDefault"), Pattern
slash_, Pattern -> Pattern
opt(Pattern
comma_)]],

-- lambda_star_etc:
--     | '*' lambda_param_no_default lambda_param_maybe_default* [lambda_kwds]
--     | '*' ',' lambda_param_maybe_default+ [lambda_kwds]
--     | lambda_kwds
  String -> [Pattern] -> Production
define String
"LambdaStarEtc" [
    [Pattern] -> Pattern
list[Pattern
star_, Pattern
"LambdaParamNoDefault", Pattern -> Pattern
star(Pattern
"LambdaParamMaybeDefault"), Pattern -> Pattern
opt(Pattern
"LambdaKwds")],
    [Pattern] -> Pattern
list[Pattern
star_, Pattern
comma_, Pattern -> Pattern
plus(Pattern
"LambdaParamMaybeDefault"), Pattern -> Pattern
opt(Pattern
"LambdaKwds")],
    Pattern
"LambdaKwds"],

-- lambda_kwds:
--     | '**' lambda_param_no_default
  String -> [Pattern] -> Production
define String
"LambdaKwds" [
    [Pattern] -> Pattern
list[Pattern
double_star_, Pattern
"LambdaParamNoDefault"]],

-- lambda_param_no_default:
--     | lambda_param ','
--     | lambda_param &':'
  String -> [Pattern] -> Production
define String
"LambdaParamNoDefault" [
    [Pattern] -> Pattern
list[Pattern
"LambdaParam", Pattern -> Pattern
opt(Pattern
comma_)]],

-- lambda_param_with_default:
--     | lambda_param default ','
--     | lambda_param default &':'
  String -> [Pattern] -> Production
define String
"LambdaParamWithDefault" [
    [Pattern] -> Pattern
list[Pattern
"LambdaParam", Pattern
"Default", Pattern -> Pattern
opt(Pattern
comma_)]],

-- lambda_param_maybe_default:
--     | lambda_param default? ','
--     | lambda_param default? &':'
  String -> [Pattern] -> Production
define String
"LambdaParamMaybeDefault" [
    [Pattern] -> Pattern
list[Pattern
"LambdaParam", Pattern -> Pattern
opt(Pattern
"Default"), Pattern -> Pattern
opt(Pattern
comma_)]],

-- lambda_param: NAME
  String -> [Pattern] -> Production
define String
"LambdaParam" [
    Pattern
"Name"],

-- # LITERALS
-- # ========

-- strings: STRING+

-- list:
--     | '[' [star_named_expressions] ']'
  String -> [Pattern] -> Production
define String
"List" [
    [Pattern] -> Pattern
list[Pattern
open_square_, Pattern -> Pattern -> Pattern
sepp Pattern
comma_ Pattern
"StarNamedExpression", Pattern
close_square_]],

-- tuple:
--     | '(' [star_named_expression ',' [star_named_expressions]  ] ')'
  String -> [Pattern] -> Production
define String
"Tuple" [
    [Pattern] -> Pattern
list[Pattern
open_paren_, Pattern -> Pattern
opt(Pattern -> Pattern -> Pattern
sepp Pattern
comma_ Pattern
"StarNamedExpression"), Pattern
close_paren_]],

-- set: '{' star_named_expressions '}'
  String -> [Pattern] -> Production
define String
"Set" [
    [Pattern] -> Pattern
list[Pattern
open_curly_, Pattern -> Pattern -> Pattern
sepp Pattern
comma_ Pattern
"StarNamedExpression", Pattern
close_curly_]],

-- # Dicts
-- # -----

-- dict:
--     | '{' [double_starred_kvpairs] '}'
  String -> [Pattern] -> Production
define String
"Dict" [
    [Pattern] -> Pattern
list[Pattern
open_curly_, Pattern -> Pattern
opt(Pattern -> Pattern -> Pattern
sepp Pattern
comma_ Pattern
"DoubleStarredKvpair"), Pattern
close_curly_]],

-- double_starred_kvpairs: ','.double_starred_kvpair+ [',']

-- double_starred_kvpair:
--     | '**' bitwise_or
--     | kvpair
  String -> [Pattern] -> Production
define String
"DoubleStarredKvpair" [
    [Pattern] -> Pattern
list[Pattern
double_star_, Pattern
"BitwiseOr"],
    Pattern
"Kvpair"],

-- kvpair: expression ':' expression
  String -> [Pattern] -> Production
define String
"Kvpair" [
    [Pattern] -> Pattern
list[Pattern
"Expression", Pattern
colon_, Pattern
"Expression"]],

-- # Comprehensions & Generators
-- # ---------------------------

-- for_if_clauses:
--     | for_if_clause+

-- for_if_clause:
--     | ASYNC 'for' star_targets 'in' ~ disjunction ('if' disjunction )*
--     | 'for' star_targets 'in' ~ disjunction ('if' disjunction )*
  String -> [Pattern] -> Production
define String
"ForIfClause" [
    [Pattern] -> Pattern
list[Pattern -> Pattern
opt(Pattern
"Async"), String -> Pattern
terminal String
"for", Pattern -> Pattern -> Pattern
sepp Pattern
comma_ Pattern
"StarTarget", String -> Pattern
terminal String
"in", Pattern
tilde_, Pattern
"Disjunction", Pattern -> Pattern
star([Pattern] -> Pattern
list[String -> Pattern
terminal String
"if", Pattern
"Disjunction"])]],

-- listcomp:
--     | '[' named_expression for_if_clauses ']'
  String -> [Pattern] -> Production
define String
"Listcomp" [
    [Pattern] -> Pattern
list[Pattern
open_square_, Pattern
"NamedExpression", Pattern -> Pattern
plus(Pattern
"ForIfClause"), Pattern
close_square_]],
    
-- setcomp:
--     | '{' named_expression for_if_clauses '}'
  String -> [Pattern] -> Production
define String
"Setcomp" [
    [Pattern] -> Pattern
list[Pattern
open_curly_, Pattern
"NamedExpression", Pattern -> Pattern
plus(Pattern
"ForIfClause"), Pattern
close_curly_]],
    
-- genexp:
--     | '(' ( assignment_expression | expression !':=') for_if_clauses ')'
  String -> [Pattern] -> Production
define String
"Genexp" [
    [Pattern] -> Pattern
list[Pattern
open_paren_, [Pattern] -> Pattern
alts[Pattern
"AssignmentExpression", Pattern
"Expression"], Pattern -> Pattern
plus(Pattern
"ForIfClause"), Pattern
close_paren_]],

-- dictcomp:
--     | '{' kvpair for_if_clauses '}'
  String -> [Pattern] -> Production
define String
"Dictcomp" [
    [Pattern] -> Pattern
list[Pattern
open_curly_, Pattern
"Kvpair", Pattern -> Pattern
plus(Pattern
"ForIfClause"), Pattern
close_curly_]],
    
-- # FUNCTION CALL ARGUMENTS
-- # =======================
--
-- arguments:
--     | args [','] &')'
  String -> [Pattern] -> Production
define String
"Arguments" [
    [Pattern] -> Pattern
list[Pattern
"Args", Pattern -> Pattern
opt(Pattern
comma_)]],

-- args:
--     | ','.(starred_expression | ( assignment_expression | expression !':=') !'=')+ [',' kwargs ]
--     | kwargs
  String -> [Pattern] -> Production
define String
"Args" [
    [Pattern] -> Pattern
list[Pattern -> Pattern -> Pattern
sep Pattern
comma_ ([Pattern] -> Pattern
alts[Pattern
"StarredExpression", Pattern
"AssignmentExpression", Pattern
"Expression"]), Pattern -> Pattern
opt([Pattern] -> Pattern
list[Pattern
comma_, Pattern
"Kwargs"])],
    Pattern
"Kwargs"],

-- kwargs:
--     | ','.kwarg_or_starred+ ',' ','.kwarg_or_double_starred+
--     | ','.kwarg_or_starred+
--     | ','.kwarg_or_double_starred+
  String -> [Pattern] -> Production
define String
"Kwargs" [
    [Pattern] -> Pattern
list[Pattern
comma_, [Pattern] -> Pattern
alts[
      [Pattern] -> Pattern
list[Pattern -> Pattern
plus([Pattern] -> Pattern
list[Pattern
dot_, Pattern
"KwargOrStarred"]), Pattern -> Pattern
opt([Pattern] -> Pattern
list[Pattern
comma_, Pattern
comma_, Pattern -> Pattern
plus([Pattern] -> Pattern
list[Pattern
dot_, Pattern
"KwargOrDoubleStarred"])])],
      Pattern -> Pattern
plus([Pattern] -> Pattern
list[Pattern
dot_, Pattern
"KwargOrDoubleStarred"])]]],

-- starred_expression:
--     | '*' expression
  String -> [Pattern] -> Production
define String
"StarredExpression" [
    [Pattern] -> Pattern
list[Pattern
star_, Pattern
"Expression"]],

-- kwarg_or_starred:
--     | NAME '=' expression
--     | starred_expression
  String -> [Pattern] -> Production
define String
"KwargOrStarred" [
    [Pattern] -> Pattern
list[Pattern
"Name", Pattern
equal_, Pattern
"Expression"],
    Pattern
"StarredExpression"],

-- kwarg_or_double_starred:
--     | NAME '=' expression
--     | '**' expression
  String -> [Pattern] -> Production
define String
"KwargOrDoubleStarred" [
    [Pattern] -> Pattern
list[Pattern
"Name", Pattern
equal_, Pattern
"Expression"],
    [Pattern] -> Pattern
list[Pattern
double_star_, Pattern
"Expression"]],

-- # ASSIGNMENT TARGETS
-- # ==================

-- # Generic targets
-- # ---------------

-- # NOTE: star_targets may contain *bitwise_or, targets may not.
-- star_targets:
--     | star_target !','
--     | star_target (',' star_target )* [',']

-- star_targets_list_seq: ','.star_target+ [',']
  String -> [Pattern] -> Production
define String
"StarTargetsListSeq" [
    Pattern -> Pattern -> Pattern
sepp Pattern
comma_ (Pattern -> Pattern
plus([Pattern] -> Pattern
list[Pattern
dot_, Pattern
"StarTarget"]))],

-- star_targets_tuple_seq:
--     | star_target (',' star_target )+ [',']
--     | star_target ','
  String -> [Pattern] -> Production
define String
"StarTargetsTupleSeq" [
    Pattern -> Pattern -> Pattern
sepp Pattern
comma_ (Pattern -> Pattern
plus(Pattern
"StarTarget"))],

-- star_target:
--     | '*' (!'*' star_target)
--     | target_with_star_atom
  String -> [Pattern] -> Production
define String
"StarTarget" [
    [Pattern] -> Pattern
list[Pattern
star_, Pattern
"StarTarget"],
    Pattern
"TargetWithStarAtom"],

-- target_with_star_atom:
--     | t_primary '.' NAME !t_lookahead
--     | t_primary '[' slices ']' !t_lookahead
--     | star_atom
  String -> [Pattern] -> Production
define String
"TargetWithStarAtom" [
    [Pattern] -> Pattern
list[Pattern
"TPrimary", Pattern
dot_, Pattern
"Name"],
    [Pattern] -> Pattern
list[Pattern
"TPrimary", Pattern
open_square_, Pattern
"Slices", Pattern
close_square_],
    Pattern
"StarAtom"],

-- star_atom:
--     | NAME
--     | '(' target_with_star_atom ')'
--     | '(' [star_targets_tuple_seq] ')'
--     | '[' [star_targets_list_seq] ']'
  String -> [Pattern] -> Production
define String
"StarAtom" [
    Pattern
"Name",
    [Pattern] -> Pattern
list[Pattern
open_paren_, Pattern
"TargetWithStarAtom", Pattern
close_paren_],
    [Pattern] -> Pattern
list[Pattern
open_paren_, Pattern
"StarTargetsTupleSeq", Pattern
close_paren_],
    [Pattern] -> Pattern
list[Pattern
open_square_, Pattern
"StarTargetsListSeq", Pattern
close_square_]],

-- single_target:
--     | single_subscript_attribute_target
--     | NAME
--     | '(' single_target ')'
  String -> [Pattern] -> Production
define String
"SingleTarget" [
    Pattern
"SingleSubscriptAttributeTarget",
    Pattern
"Name",
    [Pattern] -> Pattern
list[Pattern
open_paren_, Pattern
"SingleTarget", Pattern
close_paren_]],

-- single_subscript_attribute_target:
--     | t_primary '.' NAME !t_lookahead
--     | t_primary '[' slices ']' !t_lookahead
  String -> [Pattern] -> Production
define String
"SingleSubscriptAttributeTarget" [
    [Pattern] -> Pattern
list[Pattern
"TPrimary", Pattern
dot_, Pattern
"Name"],
    [Pattern] -> Pattern
list[Pattern
"TPrimary", Pattern
open_square_, Pattern
"Slices", Pattern
close_square_]],

-- 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
  String -> [Pattern] -> Production
define String
"TPrimary" [
    [Pattern] -> Pattern
list[Pattern
"TPrimary", Pattern
dot_, Pattern
"Name"],
    [Pattern] -> Pattern
list[Pattern
"TPrimary", Pattern
open_square_, Pattern
"Slices", Pattern
close_square_],
    [Pattern] -> Pattern
list[Pattern
"TPrimary", Pattern
"Genexp"],
    [Pattern] -> Pattern
list[Pattern
"TPrimary", Pattern
open_paren_, Pattern -> Pattern
opt(Pattern
"Arguments"), Pattern
close_paren_],
    Pattern
"Atom"],

-- t_lookahead: '(' | '[' | '.'
  String -> [Pattern] -> Production
define String
"TLookahead" [
    Pattern
open_paren_, Pattern
open_square_, Pattern
dot_],

-- # Targets for del statements
-- # --------------------------

-- del_targets: ','.del_target+ [',']
  String -> [Pattern] -> Production
define String
"DelTargets" [
    [Pattern] -> Pattern
list[Pattern
"TPrimary", Pattern
dot_, Pattern
"Name"],
    [Pattern] -> Pattern
list[Pattern
"TPrimary", Pattern
open_square_, Pattern
"Slices", Pattern
close_square_],
    Pattern
"DelTAtom"],

-- del_target:
--     | t_primary '.' NAME !t_lookahead
--     | t_primary '[' slices ']' !t_lookahead
--     | del_t_atom
  String -> [Pattern] -> Production
define String
"DelTarget" [
    [Pattern] -> Pattern
list[Pattern
"TPrimary", Pattern
dot_, Pattern
"Name"],
    [Pattern] -> Pattern
list[Pattern
"TPrimary", Pattern
open_square_, Pattern
"Slices", Pattern
close_square_],
    Pattern
"DelTAtom"],

-- del_t_atom:
--     | NAME
--     | '(' del_target ')'
--     | '(' [del_targets] ')'
--     | '[' [del_targets] ']'
  String -> [Pattern] -> Production
define String
"DelTAtom" [
    Pattern
"Name",
    [Pattern] -> Pattern
list[Pattern
open_paren_, Pattern
"DelTarget", Pattern
close_paren_],
    [Pattern] -> Pattern
list[Pattern
open_paren_, Pattern -> Pattern
opt(Pattern
"DelTargets"), Pattern
close_paren_],
    [Pattern] -> Pattern
list[Pattern
open_square_, Pattern -> Pattern
opt(Pattern
"DelTargets"), Pattern
close_square_]],

-- # TYPING ELEMENTS
-- # ---------------

-- # type_expressions allow */** but ignore them
-- type_expressions:
--     | ','.expression+ ',' '*' expression ',' '**' expression
--     | ','.expression+ ',' '*' expression
--     | ','.expression+ ',' '**' expression
--     | '*' expression ',' '**' expression
--     | '*' expression
--     | '**' expression
--     | ','.expression+
  String -> [Pattern] -> Production
define String
"TypeExpressions" [
    [Pattern] -> Pattern
list[Pattern -> Pattern -> Pattern
sepp Pattern
comma_ Pattern
"Expression", Pattern
star_, Pattern
"Expression", Pattern -> Pattern
opt([Pattern] -> Pattern
list[Pattern
comma_, Pattern
double_star_, Pattern
"Expression"])],
    [Pattern] -> Pattern
list[Pattern -> Pattern -> Pattern
sepp Pattern
comma_ Pattern
"Expression", Pattern
star_, Pattern
double_star_, Pattern
"Expression"],
    [Pattern] -> Pattern
list[Pattern
star_, Pattern
"Expression", Pattern -> Pattern
opt([Pattern] -> Pattern
list[Pattern
comma_, Pattern
double_star_, Pattern
"Expression"])],
    [Pattern] -> Pattern
list[Pattern
double_star_, Pattern
"Expression"],
    [Pattern] -> Pattern
list[Pattern -> Pattern -> Pattern
sepp Pattern
comma_ Pattern
"Expression"]],

-- func_type_comment:
--     | NEWLINE TYPE_COMMENT &(NEWLINE INDENT)   # Must be followed by indented block
--     | TYPE_COMMENT
  String -> [Pattern] -> Production
define String
"FuncTypeComment" [
    [Pattern] -> Pattern
list[Pattern -> Pattern
opt(Pattern
newline_), Pattern
"TypeComment"]]]