10. 完整的文法規格書¶
這是完整的 Python 文法,是直接從用來產生 CPython 剖析器的文法衍生出來的(請參閱 Grammar/python.gram)。這裡的版本省略了與程式碼產生和錯誤復原相關的細節。
這裡使用的標示法與前面文件相同,並在標示法部分中進行了說明。除有一個額外的複雜性:
~("cut"): commit to the current alternative; fail the rule if the alternative fails to parsePython 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:
| '[' ']'