10. 完整的文法規格書

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

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

  • ~ ("cut"): commit to the current alternative; fail the rule if the alternative fails to parse

    Python mainly uses cuts for optimizations or improved error messages. They often appear to be useless in the listing below.

    Cuts currently don't appear inside parentheses, brackets, lookaheads and similar. Their behavior in these contexts is deliberately left unspecified.

# 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:
    | '[' ']'