10. 完整的文法規格書 — Python 3.14.3 說明文件
這是完整的 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: | '[' ']'