# 10. 完整的文法規格書

這是完整的 Python 文法，是直接從用來產生 CPython 剖析器的文法衍生出來的（請參閱 Grammar/python.gram）。這裡的版本省略了與程式碼產生和錯誤復原相關的細節。

這裡使用的標示法與前面文件相同，並在標示法部分中進行了說明。除有一個額外的複雜性：

- `~`（「切斷」）：提交至目前的替代方案；無法剖析會使規則失敗。

  Python 主要使用切斷來進行最佳化或改善錯誤訊息。它們在下面的列表中常看起來沒用。

  切斷目前不會出現在括號、方括號、預查和類似的地方。它們在這些情境中的行為是故意未指定的。

    # Python 的 PEG 文法

    # ========================= 文法的開始 =========================

    # 通用文法結構與規則
    #
    # * 雙引號（"）字串表示軟關鍵字 (SOFT KEYWORDS)
    # * 單引號（'）字串表示關鍵字 (KEYWORDS)
    # * 大寫名稱 (NAME) 表示 Grammar/Tokens 檔案中的語彙符號 (token)
    # * 以 "invalid_" 開頭的規則名稱用於專門的語法錯誤
    #     - 這些規則不會在剖析器的第一遍剖析中使用。
    #     - 只有當第一遍剖析失敗時，才會執行包含無效規則的第二遍。
    #     - 如果剖析器在第二階段因泛用語法錯誤而失敗，
    #       則會使用第一遍泛用失敗的位置（這可避免因無效規則
    #       而報告錯誤的位置）。
    #     - 涉及無效規則的替代方案的順序很重要
    #       （就像 PEG 中的任何規則一樣）。
    #
    # 文法語法（更多資訊請參閱 PEP 617）：
    #
    # rule_name: expression
    #   在規則名稱後面可以選擇性地包含型別，用來指定對應此規則的
    #   C 或 Python 函式的回傳型別：
    # rule_name[return_type]: expression
    #   如果省略回傳型別，則在 C 中回傳 void *，並在 Python 中回傳 Any。
    # e1 e2
    #   匹配 e1，然後匹配 e2。
    # e1 | e2
    #   匹配 e1 或 e2。
    #   為了格式化目的，第一個替代選項也可以出現在規則名稱後的下一行。
    #   在這種情況下，必須在第一個替代選項之前使用 |，如下所示：
    #       rule_name[return_type]:
    #            | first_alt
    #            | second_alt
    # ( e )
    #   匹配 e（也允許在群組中使用其他運算子，如 '(e)*'）
    # [ e ] or e?
    #   可選地匹配 e。
    # e*
    #   匹配零個或多個 e。
    # e+
    #   匹配一個或多個 e。
    # s.e+
    #   匹配一個或多個 e，以 s 分隔。產生的剖析樹不包含分隔符號。
    #   這在其他方面與 (e (s e)*) 相同。
    # &e
    #   如果可以剖析 e 則成功，但不消耗任何輸入。
    # !e
    #   如果可以剖析 e 則失敗，但不消耗任何輸入。
    # ~
    #   提交到目前的替代選項，即使剖析失敗。
    # &&e
    #   急切剖析 e。如果無法剖析 e，剖析器將不會回溯 (backtrack)，並會立即
    #   引發 SyntaxError 失敗。
    #

    # 起始規則
    # =======

    file: [statements] ENDMARKER
    interactive: statement_newline
    eval: expressions NEWLINE* ENDMARKER
    func_type: '(' [type_expressions] ')' '->' expression NEWLINE* ENDMARKER

    # 一般陳述式
    # =========

    statements: statement+

    statement:
        | compound_stmt
        | simple_stmts

    single_compound_stmt:
        | compound_stmt

    statement_newline:
        | single_compound_stmt NEWLINE
        | simple_stmts
        | NEWLINE
        | ENDMARKER

    simple_stmts:
        | simple_stmt !';' NEWLINE  # Not needed, there for speedup
        | ';'.simple_stmt+ [';'] NEWLINE

    # 註：賦值必須在運算式之前，否則剖析簡單賦值時會引發 SyntaxError。
    simple_stmt:
        | assignment
        | type_alias
        | star_expressions
        | return_stmt
        | import_stmt
        | raise_stmt
        | pass_stmt
        | del_stmt
        | yield_stmt
        | assert_stmt
        | break_stmt
        | continue_stmt
        | global_stmt
        | nonlocal_stmt

    compound_stmt:
        | function_def
        | if_stmt
        | class_def
        | with_stmt
        | for_stmt
        | try_stmt
        | while_stmt
        | match_stmt

    # 簡單陳述式
    # =========

    # 註：annotated_rhs 可以用 'yield' 開頭；yield_expr 必須以 'yield' 開頭
    assignment:
        | NAME ':' expression ['=' annotated_rhs ]
        | ('(' single_target ')'
             | single_subscript_attribute_target) ':' expression ['=' annotated_rhs ]
        | (star_targets '=' )+ annotated_rhs !'=' [TYPE_COMMENT]
        | single_target augassign ~ annotated_rhs

    annotated_rhs: yield_expr | star_expressions

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

    return_stmt:
        | 'return' [star_expressions]

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

    pass_stmt:
        | 'pass'

    break_stmt:
        | 'break'

    continue_stmt:
        | 'continue'

    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 陳述式
    # ------------

    import_name: 'import' dotted_as_names
    # 注意以下部分：('.' | '...') 是必須的，因為 '...' 是被 tokenize 為 ELLIPSIS
    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:
        | ','.dotted_as_name+
    dotted_as_name:
        | dotted_name ['as' NAME ]

    dotted_name:
        | dotted_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_params] ['(' [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]
        | param_no_default+ param_with_default* [star_etc]
        | param_with_default+ [star_etc]
        | star_etc

    # 這裡有些重複，因為我們不能寫 (',' | &')')，
    # 這是因為我們（尚）不支援空替代方案。

    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_default param_maybe_default* [kwds]
        | '*' param_no_default_star_annotation param_maybe_default* [kwds]
        | '*' ',' param_maybe_default+ [kwds]
        | kwds

    kwds:
        | '**' param_no_default

    # 一個參數。這 *包含* 後面的逗號和型別註解。
    #
    # 有三種風格：
    # - 沒有預設值
    # - 有預設值
    # - 可能有預設值
    #
    # 每種都有兩種替代形式，用以處理型別註解：
    # - 以逗號結尾，後面接可選的型別註解
    # - 沒有逗號，可選的型別註解，後面必須接右括號
    # 後者是用於沒有尾隨逗號的最後一個參數。
    #

    param_no_default:
        | param ',' TYPE_COMMENT?
        | param TYPE_COMMENT? &')'
    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_COMMENT? &')'
    param_maybe_default:
        | param default? ',' TYPE_COMMENT?
        | param default? TYPE_COMMENT? &')'
    param: NAME annotation?
    param_star_annotation: NAME star_annotation
    annotation: ':' expression
    star_annotation: ':' star_expression
    default: '=' expression  | invalid_default

    # If 陳述式
    # --------

    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 陳述式
    # -----------

    while_stmt:
        | 'while' named_expression ':' block [else_block]

    # For 陳述式
    # ---------

    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 陳述式
    # ----------

    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_target &(',' | ')' | ':')
        | expression

    # Try 陳述式
    # ---------

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

    # Except 陳述式
    # ------------

    except_block:
        | 'except' expression ':' block
        | 'except' expression 'as' NAME ':' block
        | 'except' expressions ':' block
        | 'except' ':' block
    except_star_block:
        | 'except' '*' expression ':' block
        | 'except' '*' expression 'as' NAME ':' block
        | 'except' '*' expressions ':' block
    finally_block:
        | 'finally' ':' block

    # Match 陳述式
    # -----------

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

    subject_expr:
        | star_named_expression ',' star_named_expressions?
        | named_expression

    case_block:
        | "case" patterns guard? ':' block

    guard: 'if' 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
        | wildcard_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

    signed_real_number:
        | real_number
        | '-' real_number

    real_number:
        | NUMBER

    imaginary_number:
        | NUMBER

    capture_pattern:
        | pattern_capture_target

    pattern_capture_target:
        | !"_" NAME !('.' | '(' | '=')

    wildcard_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 陳述式
    # ----------

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

    # Type 參數宣告
    # ------------

    type_params:
        | '[' type_param_seq ']'

    type_param_seq: ','.type_param+ [',']

    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_expressions]

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

    star_expression:
        | '*' bitwise_or
        | expression

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

    star_named_expression:
        | '*' bitwise_or
        | named_expression

    assignment_expression:
        | NAME ':=' ~ expression

    named_expression:
        | assignment_expression
        | expression !':='

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

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

    inversion:
        | 'not' inversion
        | comparison

    # 比較運算子
    # --------

    comparison:
        | bitwise_or compare_op_bitwise_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

    # 主要元素
    # -------

    # 主要元素是像 "obj.something.something", "obj[something]", "obj(something)", "obj" ... 這樣的東西

    await_primary:
        | 'await' primary
        | primary

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

    slices:
        | slice !','
        | ','.(slice | 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) ')'

    # Lambda 函式
    # ----------

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

    lambda_params:
        | lambda_parameters

    # 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 &':'
    lambda_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

    tstring_format_spec_replacement_field:
        | '{' annotated_rhs '='? [fstring_conversion] [tstring_full_format_spec] '}'
    tstring_format_spec:
        | TSTRING_MIDDLE
        | tstring_format_spec_replacement_field
    tstring_full_format_spec:
        | ':' tstring_format_spec*
    tstring_replacement_field:
        | '{' annotated_rhs '='? [fstring_conversion] [tstring_full_format_spec] '}'
    tstring_middle:
        | tstring_replacement_field
        | TSTRING_MIDDLE
    tstring:
        | TSTRING_START tstring_middle* TSTRING_END

    string: STRING
    strings:
        | (fstring|string)+
        | tstring+

    list:
        | '[' [star_named_expressions] ']'

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

    set: '{' star_named_expressions '}'

    # 字典
    # ----

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

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

    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' disjunction )*
        | 'for' star_targets 'in' ~ disjunction ('if' disjunction )*

    listcomp:
        | '[' named_expression for_if_clauses ']'

    setcomp:
        | '{' named_expression for_if_clauses '}'

    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 可能包含 *bitwise_or，targets 則不可以。
    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 陳述式的目標
    # --------------

    del_targets: ','.del_target+ [',']

    del_target:
        | t_primary '.' NAME !t_lookahead
        | t_primary '[' slices ']' !t_lookahead
        | del_t_atom

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

    # 型別元素
    # -------

    # type_expressions 允許 */** 但會忽略他們
    type_expressions:
        | ','.expression+ ',' '*' expression ',' '**' expression
        | ','.expression+ ',' '*' expression
        | ','.expression+ ',' '**' expression
        | '*' expression ',' '**' expression
        | '*' expression
        | '**' expression
        | ','.expression+

    func_type_comment:
        | NEWLINE TYPE_COMMENT &(NEWLINE INDENT)   # 後面必須接縮排區塊
        | TYPE_COMMENT

    # ========================= 文法結束 ===========================

    # ========================= 無效規則開始 =======================

    # 從這裡開始是用於無效語法的規則，具有專門的錯誤訊息
    invalid_arguments:
        | ((','.(starred_expression | ( assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' ','.(starred_expression !'=')+
        | expression for_if_clauses ',' [args | expression for_if_clauses]
        | NAME '=' expression for_if_clauses
        | (args ',')? NAME '=' &(',' | ')')
        | args for_if_clauses
        | args ',' expression for_if_clauses
        | args ',' args
    invalid_kwarg:
        | ('True'|'False'|'None') '='
        | NAME '=' expression for_if_clauses
        | !(NAME '=') expression '='
        | '**' expression '=' expression

    # 重要：請注意 "_without_invalid" 後綴會導致該規則不呼叫其下的無效規則
    expression_without_invalid:
        | disjunction 'if' disjunction 'else' expression
        | disjunction
        | lambdef
    invalid_legacy_expression:
        | NAME !'(' star_expressions

    invalid_type_param:
        | '*' NAME ':' expression
        | '**' NAME ':' expression

    invalid_expression:
       |  STRING (!STRING expression_without_invalid)+ STRING
        # !(NAME STRING) 不匹配所以我們不會去顯示有著像是 kf"dsfsdf" 無效字串前綴的錯誤
        # 軟關鍵字也需要被忽略，因為它們可以被剖析為 NAME NAME
       | !(NAME STRING | SOFT_KEYWORD) disjunction expression_without_invalid
       | disjunction 'if' disjunction !('else'|':')
       | disjunction 'if' disjunction 'else' !expression
       | (pass_stmt|break_stmt|continue_stmt) 'if' disjunction 'else' simple_stmt
       | 'lambda' [lambda_params] ':' &FSTRING_MIDDLE
       | 'lambda' [lambda_params] ':' &TSTRING_MIDDLE

    invalid_named_expression:
        | expression ':=' expression
        | NAME '=' bitwise_or !('='|':=')
        | !(list|tuple|genexp|'True'|'None'|'False') bitwise_or '=' bitwise_or !('='|':=')

    invalid_assignment:
            RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
                a,
                "only single target (not %s) can be annotated",
                _PyPegen_get_expr_name(a)
            )}
        | star_named_expression ',' star_named_expressions* ':' expression
        | expression ':' expression
        | (star_targets '=')* star_expressions '='
        | (star_targets '=')* yield_expr '='
        | star_expressions augassign annotated_rhs
    invalid_ann_assign_target:
        | list
        | tuple
    invalid_del_stmt:
        | 'del' star_expressions
    invalid_block:
        | NEWLINE !INDENT
    invalid_comprehension:
        | ('[' | '(' | '{') starred_expression for_if_clauses
        | ('[' | '{') star_named_expression ',' star_named_expressions for_if_clauses
        | ('[' | '{') star_named_expression ',' for_if_clauses
    invalid_dict_comprehension:
        | '{' '**' bitwise_or for_if_clauses '}'
    invalid_parameters:
        | "/" ','
        | (slash_no_default | slash_with_default) param_maybe_default* '/'
            RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "parameter without a default follows parameter with a default") }
        | param_no_default* '(' param_no_default+ ','? ')'
        | (slash_no_default | slash_with_default)? param_maybe_default* '*' (',' | param_no_default) param_maybe_default* '/'
        | param_maybe_default+ '/' '*'
    invalid_default:
        | '=' &(')'|',')
    invalid_star_etc:
        | '*' (')' | ',' (')' | '**'))
        | '*' ',' TYPE_COMMENT
        | '*' param '='
        | '*' (param_no_default | ',') param_maybe_default* '*' (param_no_default | ',')
    invalid_kwds:
        | '**' param '='
        | '**' param ',' param
        | '**' param ',' ('*'|'**'|'/')
    invalid_parameters_helper: # 這是為了避免型別錯誤而存在的規則
        | slash_with_default
        | param_with_default+
    invalid_lambda_parameters:
        | "/" ','
        | (lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* '/'
            RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "parameter without a default follows parameter with a default") }
        | lambda_param_no_default* '(' ','.lambda_param+ ','? ')'
        | (lambda_slash_no_default | lambda_slash_with_default)? lambda_param_maybe_default* '*' (',' | lambda_param_no_default) lambda_param_maybe_default* '/'
        | lambda_param_maybe_default+ '/' '*'
    invalid_lambda_parameters_helper:
        | lambda_slash_with_default
        | lambda_param_with_default+
    invalid_lambda_star_etc:
        | '*' (':' | ',' (':' | '**'))
        | '*' lambda_param '='
        | '*' (lambda_param_no_default | ',') lambda_param_maybe_default* '*' (lambda_param_no_default | ',')
    invalid_lambda_kwds:
        | '**' lambda_param '='
        | '**' lambda_param ',' lambda_param
        | '**' lambda_param ',' ('*'|'**'|'/')
    invalid_double_type_comments:
        | TYPE_COMMENT NEWLINE TYPE_COMMENT NEWLINE INDENT
    invalid_with_item:
        | expression 'as' expression &(',' | ')' | ':')

    invalid_for_if_clause:
        | 'async'? 'for' (bitwise_or (',' bitwise_or)* [',']) !'in'

    invalid_for_target:
        | 'async'? 'for' star_expressions

    invalid_group:
        | '(' starred_expression ')'
        | '(' '**' expression ')'
    invalid_import:
        | 'import' ','.dotted_name+ 'from' dotted_name
        | 'import' NEWLINE
    invalid_dotted_as_name:
        | dotted_name 'as' !(NAME (',' | ')' | ';' | NEWLINE)) expression
    invalid_import_from_as_name:
        | NAME 'as' !(NAME (',' | ')' | ';' | NEWLINE)) expression

    invalid_import_from_targets:
        | import_from_as_names ',' NEWLINE
        | NEWLINE

    invalid_with_stmt:
        | ['async'] 'with' ','.(expression ['as' star_target])+ NEWLINE
        | ['async'] 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE
    invalid_with_stmt_indent:
        | ['async'] 'with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT
        | ['async'] 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT

    invalid_try_stmt:
        | 'try' ':' NEWLINE !INDENT
        | 'try' ':' block !('except' | 'finally')
        | 'try' ':' block* except_block+ 'except' '*' expression ['as' NAME] ':'
        | 'try' ':' block* except_star_block+ 'except' [expression ['as' NAME]] ':'
    invalid_except_stmt:
        | 'except' expression ',' expressions 'as' NAME  ':'
        | 'except' expression ['as' NAME ] NEWLINE
        | 'except' NEWLINE
        | 'except' expression 'as' expression ':' block
    invalid_except_star_stmt:
        | 'except' '*' expression ',' expressions 'as' NAME  ':'
        | 'except' '*' expression ['as' NAME ] NEWLINE
        | 'except' '*' (NEWLINE | ':')
        | 'except' '*' expression 'as' expression ':' block
    invalid_finally_stmt:
        | 'finally' ':' NEWLINE !INDENT
    invalid_except_stmt_indent:
        | 'except' expression ['as' NAME ] ':' NEWLINE !INDENT
        | 'except' ':' NEWLINE !INDENT
    invalid_except_star_stmt_indent:
        | 'except' '*' expression ['as' NAME ] ':' NEWLINE !INDENT
    invalid_match_stmt:
        | "match" subject_expr NEWLINE
        | "match" subject_expr ':' NEWLINE !INDENT
    invalid_case_block:
        | "case" patterns guard? NEWLINE
        | "case" patterns guard? ':' NEWLINE !INDENT
    invalid_as_pattern:
        | or_pattern 'as' "_"
        | or_pattern 'as' expression
    invalid_class_pattern:
            PyPegen_first_item(a, pattern_ty),
            PyPegen_last_item(a, pattern_ty),
            "positional patterns follow keyword patterns") }
    invalid_class_argument_pattern:
        | [positional_patterns ','] keyword_patterns ',' positional_patterns
    invalid_if_stmt:
        | 'if' named_expression NEWLINE
        | 'if' named_expression ':' NEWLINE !INDENT
    invalid_elif_stmt:
        | 'elif' named_expression NEWLINE
        | 'elif' named_expression ':' NEWLINE !INDENT
    invalid_else_stmt:
        | 'else' ':' NEWLINE !INDENT
        | 'else' ':' block 'elif'
    invalid_while_stmt:
        | 'while' named_expression NEWLINE
        | 'while' named_expression ':' NEWLINE !INDENT
    invalid_for_stmt:
        | ['async'] 'for' star_targets 'in' star_expressions NEWLINE
        | ['async'] 'for' star_targets 'in' star_expressions ':' NEWLINE !INDENT
    invalid_def_raw:
        | ['async'] 'def' NAME [type_params] '(' [params] ')' ['->' expression] ':' NEWLINE !INDENT
        | ['async'] 'def' NAME [type_params] '(' [params] ')' ['->' expression] ':' [func_type_comment] block
    invalid_class_def_raw:
        | 'class' NAME [type_params] ['(' [arguments] ')'] NEWLINE
        | 'class' NAME [type_params] ['(' [arguments] ')'] ':' NEWLINE !INDENT

    invalid_double_starred_kvpairs:
        | expression ':' '*' bitwise_or
        | expression ':' &('}'|',')
    invalid_kvpair:
        | expression !(':')
        | expression ':' '*' bitwise_or
        | expression ':' &('}'|',')
    invalid_starred_expression_unpacking:
        | '*' expression '=' expression
    invalid_starred_expression:
        | '*'

    invalid_fstring_replacement_field:
        | '{' '='
        | '{' '!'
        | '{' ':'
        | '{' '}' '") }
        | '
        | '{' annotated_rhs !('=' | '!' | ':' | '}') '") }
        | '') '") }
        | '') '") }
        | '' ', or format specs") }
        | '{' annotated_rhs '='? ['!' NAME] !'}' '") }

    invalid_fstring_conversion_character:
        | '!' &(':' | '}')
        | '!' !NAME

    invalid_tstring_replacement_field:
        | '{' '='
        | '{' '!'
        | '{' ':'
        | '{' '}' '") }
        | '
        | '{' annotated_rhs !('=' | '!' | ':' | '}') '") }
        | '') '") }
        | '') '") }
        | '' ', or format specs") }
        | '{' annotated_rhs '='? ['!' NAME] !'}' '") }

    invalid_tstring_conversion_character:
        | '!' &(':' | '}')
        | '!' !NAME

    invalid_string_tstring_concat:
        | (fstring|string)+ tstring
        | tstring+ (fstring|string)

    invalid_arithmetic:
        | sum ('+'|'-'|'*'|'/'|'%'|'//'|'@') 'not' inversion
    invalid_factor:
        | ('+' | '-' | '~') 'not' factor

    invalid_type_params:
        | '[' ']'