Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/Grammar/python.gram b/Grammar/python.gram
- index a5ab769910b..08827832789 100644
- --- a/Grammar/python.gram
- +++ b/Grammar/python.gram
- @@ -120,26 +120,26 @@ simple_stmt[stmt_ty] (memo):
- | assignment
- | &"type" type_alias
- | e=star_expressions { _PyAST_Expr(e, EXTRA) }
- - | &'return' return_stmt
- - | &('import' | 'from') import_stmt
- - | &'raise' raise_stmt
- - | &'pass' pass_stmt
- - | &'del' del_stmt
- - | &'yield' yield_stmt
- - | &'assert' assert_stmt
- - | &'break' break_stmt
- - | &'continue' continue_stmt
- - | &'global' global_stmt
- - | &'nonlocal' nonlocal_stmt
- + | &('return' | '回') return_stmt
- + | &('import' | 'from' | '載' | '從') import_stmt
- + | &('raise' | '示') raise_stmt
- + | &('pass' | '過') pass_stmt
- + | &('del' | '刪') del_stmt
- + | &('yield' | '讓') yield_stmt
- + | &('assert' | '宣') assert_stmt
- + | &('break' | '斷') break_stmt
- + | &('continue' | '續') continue_stmt
- + | &('global' | '寰') global_stmt
- + | &('nonlocal' | '異') nonlocal_stmt
- compound_stmt[stmt_ty]:
- - | &('def' | '@' | 'async') function_def
- - | &'if' if_stmt
- - | &('class' | '@') class_def
- - | &('with' | 'async') with_stmt
- - | &('for' | 'async') for_stmt
- - | &'try' try_stmt
- - | &'while' while_stmt
- + | &('def' | '函' | '@' | 'async' | '離') function_def
- + | &('if' | '如') if_stmt
- + | &('class' | '類' | '@') class_def
- + | &('with' | '用' | 'async' | '離') with_stmt
- + | &('for' | '為' | 'async' | '離') for_stmt
- + | &('try' | '試') try_stmt
- + | &('while' | '當') while_stmt
- | match_stmt
- # SIMPLE STATEMENTS
- @@ -181,35 +181,49 @@ augassign[AugOperator*]:
- | '//=' { _PyPegen_augoperator(p, FloorDiv) }
- return_stmt[stmt_ty]:
- + | '回' a=[star_expressions] { _PyAST_Return(a, EXTRA) }
- | 'return' a=[star_expressions] { _PyAST_Return(a, EXTRA) }
- raise_stmt[stmt_ty]:
- | invalid_raise_stmt
- + | '示' a=expression b=['從' z=expression { z }] { _PyAST_Raise(a, b, EXTRA) }
- | 'raise' a=expression b=['from' z=expression { z }] { _PyAST_Raise(a, b, EXTRA) }
- + | '示' { _PyAST_Raise(NULL, NULL, EXTRA) }
- | 'raise' { _PyAST_Raise(NULL, NULL, EXTRA) }
- pass_stmt[stmt_ty]:
- + | '過' { _PyAST_Pass(EXTRA) }
- | 'pass' { _PyAST_Pass(EXTRA) }
- break_stmt[stmt_ty]:
- + | '斷' { _PyAST_Break(EXTRA) }
- | 'break' { _PyAST_Break(EXTRA) }
- continue_stmt[stmt_ty]:
- + | '續' { _PyAST_Continue(EXTRA) }
- | 'continue' { _PyAST_Continue(EXTRA) }
- -global_stmt[stmt_ty]: 'global' a[asdl_expr_seq*]=','.NAME+ {
- - _PyAST_Global(CHECK(asdl_identifier_seq*, _PyPegen_map_names_to_ids(p, a)), EXTRA) }
- -
- -nonlocal_stmt[stmt_ty]: 'nonlocal' a[asdl_expr_seq*]=','.NAME+ {
- +global_stmt[stmt_ty]:
- + | '寰' a[asdl_expr_seq*]=','.NAME+ {
- + _PyAST_Global(CHECK(asdl_identifier_seq*, _PyPegen_map_names_to_ids(p, a)), EXTRA) }
- + | 'global' a[asdl_expr_seq*]=','.NAME+ {
- + _PyAST_Global(CHECK(asdl_identifier_seq*, _PyPegen_map_names_to_ids(p, a)), EXTRA) }
- +nonlocal_stmt[stmt_ty]:
- + | '異' a[asdl_expr_seq*]=','.NAME+ {
- + _PyAST_Nonlocal(CHECK(asdl_identifier_seq*, _PyPegen_map_names_to_ids(p, a)), EXTRA) }
- + | 'nonlocal' a[asdl_expr_seq*]=','.NAME+ {
- _PyAST_Nonlocal(CHECK(asdl_identifier_seq*, _PyPegen_map_names_to_ids(p, a)), EXTRA) }
- del_stmt[stmt_ty]:
- + | '刪' a=del_targets &(';' | NEWLINE) { _PyAST_Delete(a, EXTRA) }
- | 'del' a=del_targets &(';' | NEWLINE) { _PyAST_Delete(a, EXTRA) }
- | invalid_del_stmt
- yield_stmt[stmt_ty]: y=yield_expr { _PyAST_Expr(y, EXTRA) }
- -assert_stmt[stmt_ty]: 'assert' a=expression b=[',' z=expression { z }] { _PyAST_Assert(a, b, EXTRA) }
- +assert_stmt[stmt_ty]:
- + | '宣' a=expression b=[',' z=expression { z }] { _PyAST_Assert(a, b, EXTRA) }
- + | 'assert' a=expression b=[',' z=expression { z }] { _PyAST_Assert(a, b, EXTRA) }
- import_stmt[stmt_ty]:
- | invalid_import
- @@ -219,11 +233,17 @@ import_stmt[stmt_ty]:
- # Import statements
- # -----------------
- -import_name[stmt_ty]: 'import' a=dotted_as_names { _PyAST_Import(a, EXTRA) }
- +import_name[stmt_ty]:
- + | '載' a=dotted_as_names { _PyAST_Import(a, EXTRA) }
- + | 'import' a=dotted_as_names { _PyAST_Import(a, EXTRA) }
- # note below: the ('.' | '...') is necessary because '...' is tokenized as ELLIPSIS
- import_from[stmt_ty]:
- + | '從' a=('.' | '...')* b=dotted_name '載' c=import_from_targets {
- + _PyPegen_checked_future_import(p, b->v.Name.id, c, _PyPegen_seq_count_dots(a), EXTRA) }
- | 'from' a=('.' | '...')* b=dotted_name 'import' c=import_from_targets {
- _PyPegen_checked_future_import(p, b->v.Name.id, c, _PyPegen_seq_count_dots(a), EXTRA) }
- + | '從' a=('.' | '...')+ '載' b=import_from_targets {
- + _PyAST_ImportFrom(NULL, b, _PyPegen_seq_count_dots(a), EXTRA) }
- | 'from' a=('.' | '...')+ 'import' b=import_from_targets {
- _PyAST_ImportFrom(NULL, b, _PyPegen_seq_count_dots(a), EXTRA) }
- import_from_targets[asdl_alias_seq*]:
- @@ -235,14 +255,14 @@ import_from_as_names[asdl_alias_seq*]:
- | a[asdl_alias_seq*]=','.import_from_as_name+ { a }
- import_from_as_name[alias_ty]:
- | invalid_import_from_as_name
- - | a=NAME b=['as' z=NAME { z }] { _PyAST_alias(
- + | a=NAME b=[('as'|'若') z=NAME { z }] { _PyAST_alias(
- a->v.Name.id, (b) ? ((expr_ty) b)->v.Name.id : NULL, EXTRA) }
- dotted_as_names[asdl_alias_seq*]:
- | a[asdl_alias_seq*]=','.dotted_as_name+ { a }
- dotted_as_name[alias_ty]:
- | invalid_dotted_as_name
- - | a=dotted_name b=['as' z=NAME { z }] { _PyAST_alias(
- + | a=dotted_name b=[('as'|'若') z=NAME { z }] { _PyAST_alias(
- a->v.Name.id, (b) ? ((expr_ty) b)->v.Name.id : NULL, EXTRA) }
- dotted_name[expr_ty]:
- @@ -271,6 +291,11 @@ class_def[stmt_ty]:
- class_def_raw[stmt_ty]:
- | invalid_class_def_raw
- + | '類' a=NAME t=[type_params] b=['(' z=[arguments] ')' { z }] ':' c=block {
- + _PyAST_ClassDef(a->v.Name.id,
- + (b) ? ((expr_ty) b)->v.Call.args : NULL,
- + (b) ? ((expr_ty) b)->v.Call.keywords : NULL,
- + c, NULL, t, EXTRA) }
- | 'class' a=NAME t=[type_params] b=['(' z=[arguments] ')' { z }] ':' c=block {
- _PyAST_ClassDef(a->v.Name.id,
- (b) ? ((expr_ty) b)->v.Call.args : NULL,
- @@ -286,10 +311,32 @@ function_def[stmt_ty]:
- function_def_raw[stmt_ty]:
- | invalid_def_raw
- + | '函' n=NAME t=[type_params] '(' params=[params] ')' a=['->' z=expression { z }] ':' tc=[func_type_comment] b=block {
- + _PyAST_FunctionDef(n->v.Name.id,
- + (params) ? params : CHECK(arguments_ty, _PyPegen_empty_arguments(p)),
- + b, NULL, a, NEW_TYPE_COMMENT(p, tc), t, EXTRA) }
- | 'def' n=NAME t=[type_params] '(' params=[params] ')' a=['->' z=expression { z }] ':' tc=[func_type_comment] b=block {
- _PyAST_FunctionDef(n->v.Name.id,
- (params) ? params : CHECK(arguments_ty, _PyPegen_empty_arguments(p)),
- b, NULL, a, NEW_TYPE_COMMENT(p, tc), t, EXTRA) }
- + | '離函' n=NAME t=[type_params] '(' params=[params] ')' a=['->' z=expression { z }] ':' tc=[func_type_comment] b=block {
- + CHECK_VERSION(
- + stmt_ty,
- + 5,
- + "Async functions are",
- + _PyAST_AsyncFunctionDef(n->v.Name.id,
- + (params) ? params : CHECK(arguments_ty, _PyPegen_empty_arguments(p)),
- + b, NULL, a, NEW_TYPE_COMMENT(p, tc), t, EXTRA)
- + ) }
- + | '離' '函' n=NAME t=[type_params] '(' params=[params] ')' a=['->' z=expression { z }] ':' tc=[func_type_comment] b=block {
- + CHECK_VERSION(
- + stmt_ty,
- + 5,
- + "Async functions are",
- + _PyAST_AsyncFunctionDef(n->v.Name.id,
- + (params) ? params : CHECK(arguments_ty, _PyPegen_empty_arguments(p)),
- + b, NULL, a, NEW_TYPE_COMMENT(p, tc), t, EXTRA)
- + ) }
- | 'async' 'def' n=NAME t=[type_params] '(' params=[params] ')' a=['->' z=expression { z }] ':' tc=[func_type_comment] b=block {
- CHECK_VERSION(
- stmt_ty,
- @@ -377,16 +424,23 @@ default[expr_ty]: '=' a=expression { a } | invalid_default
- if_stmt[stmt_ty]:
- | invalid_if_stmt
- + | '如' a=named_expression ':' b=block c=elif_stmt {
- + _PyAST_If(a, b, CHECK(asdl_stmt_seq*, _PyPegen_singleton_seq(p, c)), EXTRA) }
- | 'if' a=named_expression ':' b=block c=elif_stmt {
- _PyAST_If(a, b, CHECK(asdl_stmt_seq*, _PyPegen_singleton_seq(p, c)), EXTRA) }
- + | '如' a=named_expression ':' b=block c=[else_block] { _PyAST_If(a, b, c, EXTRA) }
- | 'if' a=named_expression ':' b=block c=[else_block] { _PyAST_If(a, b, c, EXTRA) }
- elif_stmt[stmt_ty]:
- | invalid_elif_stmt
- + | '然' a=named_expression ':' b=block c=elif_stmt {
- + _PyAST_If(a, b, CHECK(asdl_stmt_seq*, _PyPegen_singleton_seq(p, c)), EXTRA) }
- | 'elif' a=named_expression ':' b=block c=elif_stmt {
- _PyAST_If(a, b, CHECK(asdl_stmt_seq*, _PyPegen_singleton_seq(p, c)), EXTRA) }
- + | '然' a=named_expression ':' b=block c=[else_block] { _PyAST_If(a, b, c, EXTRA) }
- | 'elif' a=named_expression ':' b=block c=[else_block] { _PyAST_If(a, b, c, EXTRA) }
- else_block[asdl_stmt_seq*]:
- | invalid_else_stmt
- + | '另' &&':' b=block { b }
- | 'else' &&':' b=block { b }
- # While statement
- @@ -394,6 +448,7 @@ else_block[asdl_stmt_seq*]:
- while_stmt[stmt_ty]:
- | invalid_while_stmt
- + | '當' a=named_expression ':' b=block c=[else_block] { _PyAST_While(a, b, c, EXTRA) }
- | 'while' a=named_expression ':' b=block c=[else_block] { _PyAST_While(a, b, c, EXTRA) }
- # For statement
- @@ -401,8 +456,14 @@ while_stmt[stmt_ty]:
- for_stmt[stmt_ty]:
- | invalid_for_stmt
- + | '為' t=star_targets '在' ~ ex=star_expressions ':' tc=[TYPE_COMMENT] b=block el=[else_block] {
- + _PyAST_For(t, ex, b, el, NEW_TYPE_COMMENT(p, tc), EXTRA) }
- | 'for' t=star_targets 'in' ~ ex=star_expressions ':' tc=[TYPE_COMMENT] b=block el=[else_block] {
- _PyAST_For(t, ex, b, el, NEW_TYPE_COMMENT(p, tc), EXTRA) }
- + | '離為' t=star_targets '在' ~ ex=star_expressions ':' tc=[TYPE_COMMENT] b=block el=[else_block] {
- + CHECK_VERSION(stmt_ty, 5, "Async for loops are", _PyAST_AsyncFor(t, ex, b, el, NEW_TYPE_COMMENT(p, tc), EXTRA)) }
- + | '離' '為' t=star_targets '在' ~ ex=star_expressions ':' tc=[TYPE_COMMENT] b=block el=[else_block] {
- + CHECK_VERSION(stmt_ty, 5, "Async for loops are", _PyAST_AsyncFor(t, ex, b, el, NEW_TYPE_COMMENT(p, tc), EXTRA)) }
- | 'async' 'for' t=star_targets 'in' ~ ex=star_expressions ':' tc=[TYPE_COMMENT] b=block el=[else_block] {
- CHECK_VERSION(stmt_ty, 5, "Async for loops are", _PyAST_AsyncFor(t, ex, b, el, NEW_TYPE_COMMENT(p, tc), EXTRA)) }
- | invalid_for_target
- @@ -412,17 +473,30 @@ for_stmt[stmt_ty]:
- with_stmt[stmt_ty]:
- | invalid_with_stmt_indent
- + | '用' '(' a[asdl_withitem_seq*]=','.with_item+ ','? ')' ':' tc=[TYPE_COMMENT] b=block {
- + _PyAST_With(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA) }
- | 'with' '(' a[asdl_withitem_seq*]=','.with_item+ ','? ')' ':' tc=[TYPE_COMMENT] b=block {
- _PyAST_With(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA) }
- + | '用' a[asdl_withitem_seq*]=','.with_item+ ':' tc=[TYPE_COMMENT] b=block {
- + _PyAST_With(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA) }
- | 'with' a[asdl_withitem_seq*]=','.with_item+ ':' tc=[TYPE_COMMENT] b=block {
- _PyAST_With(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA) }
- + | '離用' '(' a[asdl_withitem_seq*]=','.with_item+ ','? ')' ':' b=block {
- + CHECK_VERSION(stmt_ty, 5, "Async with statements are", _PyAST_AsyncWith(a, b, NULL, EXTRA)) }
- + | '離' '用' '(' a[asdl_withitem_seq*]=','.with_item+ ','? ')' ':' b=block {
- + CHECK_VERSION(stmt_ty, 5, "Async with statements are", _PyAST_AsyncWith(a, b, NULL, EXTRA)) }
- | 'async' 'with' '(' a[asdl_withitem_seq*]=','.with_item+ ','? ')' ':' b=block {
- CHECK_VERSION(stmt_ty, 5, "Async with statements are", _PyAST_AsyncWith(a, b, NULL, EXTRA)) }
- + | '離用' a[asdl_withitem_seq*]=','.with_item+ ':' tc=[TYPE_COMMENT] b=block {
- + CHECK_VERSION(stmt_ty, 5, "Async with statements are", _PyAST_AsyncWith(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA)) }
- + | '離' '用' a[asdl_withitem_seq*]=','.with_item+ ':' tc=[TYPE_COMMENT] b=block {
- + CHECK_VERSION(stmt_ty, 5, "Async with statements are", _PyAST_AsyncWith(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA)) }
- | 'async' 'with' a[asdl_withitem_seq*]=','.with_item+ ':' tc=[TYPE_COMMENT] b=block {
- CHECK_VERSION(stmt_ty, 5, "Async with statements are", _PyAST_AsyncWith(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA)) }
- | invalid_with_stmt
- with_item[withitem_ty]:
- + | e=expression '若' t=star_target &(',' | ')' | ':') { _PyAST_withitem(e, t, p->arena) }
- | e=expression 'as' t=star_target &(',' | ')' | ':') { _PyAST_withitem(e, t, p->arena) }
- | invalid_with_item
- | e=expression { _PyAST_withitem(e, NULL, p->arena) }
- @@ -432,8 +506,13 @@ with_item[withitem_ty]:
- try_stmt[stmt_ty]:
- | invalid_try_stmt
- + | '試' &&':' b=block f=finally_block { _PyAST_Try(b, NULL, NULL, f, EXTRA) }
- | 'try' &&':' b=block f=finally_block { _PyAST_Try(b, NULL, NULL, f, EXTRA) }
- + | '試' &&':' b=block ex[asdl_excepthandler_seq*]=except_block+ el=[else_block] f=[finally_block] { _PyAST_Try(b, ex, el, f, EXTRA) }
- | 'try' &&':' b=block ex[asdl_excepthandler_seq*]=except_block+ el=[else_block] f=[finally_block] { _PyAST_Try(b, ex, el, f, EXTRA) }
- + | '試' &&':' b=block ex[asdl_excepthandler_seq*]=except_star_block+ el=[else_block] f=[finally_block] {
- + CHECK_VERSION(stmt_ty, 11, "Exception groups are",
- + _PyAST_TryStar(b, ex, el, f, EXTRA)) }
- | 'try' &&':' b=block ex[asdl_excepthandler_seq*]=except_star_block+ el=[else_block] f=[finally_block] {
- CHECK_VERSION(stmt_ty, 11, "Exception groups are",
- _PyAST_TryStar(b, ex, el, f, EXTRA)) }
- @@ -444,24 +523,45 @@ try_stmt[stmt_ty]:
- except_block[excepthandler_ty]:
- | invalid_except_stmt_indent
- + | '除' e=expression ':' b=block {
- + _PyAST_ExceptHandler(e, NULL, b, EXTRA) }
- | 'except' e=expression ':' b=block {
- _PyAST_ExceptHandler(e, NULL, b, EXTRA) }
- + | '除' e=expression '若' t=NAME ':' b=block {
- + _PyAST_ExceptHandler(e, ((expr_ty) t)->v.Name.id, b, EXTRA) }
- | 'except' e=expression 'as' t=NAME ':' b=block {
- _PyAST_ExceptHandler(e, ((expr_ty) t)->v.Name.id, b, EXTRA) }
- + | '除' e=expressions ':' b=block {
- + CHECK_VERSION(
- + excepthandler_ty,
- + 14,
- + "except expressions without parentheses are",
- + _PyAST_ExceptHandler(e, NULL, b, EXTRA)) }
- | 'except' e=expressions ':' b=block {
- CHECK_VERSION(
- excepthandler_ty,
- 14,
- "except expressions without parentheses are",
- _PyAST_ExceptHandler(e, NULL, b, EXTRA)) }
- + | '除' ':' b=block { _PyAST_ExceptHandler(NULL, NULL, b, EXTRA) }
- | 'except' ':' b=block { _PyAST_ExceptHandler(NULL, NULL, b, EXTRA) }
- | invalid_except_stmt
- except_star_block[excepthandler_ty]:
- | invalid_except_star_stmt_indent
- + | '除' '*' e=expression ':' b=block {
- + _PyAST_ExceptHandler(e, NULL, b, EXTRA) }
- | 'except' '*' e=expression ':' b=block {
- _PyAST_ExceptHandler(e, NULL, b, EXTRA) }
- + | '除' '*' e=expression '若' t=NAME ':' b=block {
- + _PyAST_ExceptHandler(e, ((expr_ty) t)->v.Name.id, b, EXTRA) }
- | 'except' '*' e=expression 'as' t=NAME ':' b=block {
- _PyAST_ExceptHandler(e, ((expr_ty) t)->v.Name.id, b, EXTRA) }
- + | '除' '*' e=expressions ':' b=block {
- + CHECK_VERSION(
- + excepthandler_ty,
- + 14,
- + "except expressions without parentheses are",
- + _PyAST_ExceptHandler(e, NULL, b, EXTRA)) }
- | 'except' '*' e=expressions ':' b=block {
- CHECK_VERSION(
- excepthandler_ty,
- @@ -471,6 +571,7 @@ except_star_block[excepthandler_ty]:
- | invalid_except_star_stmt
- finally_block[asdl_stmt_seq*]:
- | invalid_finally_stmt
- + | '終' &&':' a=block { a }
- | 'finally' &&':' a=block { a }
- # Match statement
- @@ -491,7 +592,9 @@ case_block[match_case_ty]:
- | "case" pattern=patterns guard=guard? ':' body=block {
- _PyAST_match_case(pattern, guard, body, p->arena) }
- -guard[expr_ty]: 'if' guard=named_expression { guard }
- +guard[expr_ty]:
- + | '如' guard=named_expression { guard }
- + | 'if' guard=named_expression { guard }
- patterns[pattern_ty]:
- | patterns[asdl_pattern_seq*]=open_sequence_pattern {
- @@ -503,6 +606,8 @@ pattern[pattern_ty]:
- | or_pattern
- as_pattern[pattern_ty]:
- + | pattern=or_pattern '若' target=pattern_capture_target {
- + _PyAST_MatchAs(pattern, target->v.Name.id, EXTRA) }
- | pattern=or_pattern 'as' target=pattern_capture_target {
- _PyAST_MatchAs(pattern, target->v.Name.id, EXTRA) }
- | invalid_as_pattern
- @@ -526,8 +631,11 @@ literal_pattern[pattern_ty]:
- | value=signed_number !('+' | '-') { _PyAST_MatchValue(value, EXTRA) }
- | value=complex_number { _PyAST_MatchValue(value, EXTRA) }
- | value=strings { _PyAST_MatchValue(value, EXTRA) }
- + | '無' { _PyAST_MatchSingleton(Py_None, EXTRA) }
- | 'None' { _PyAST_MatchSingleton(Py_None, EXTRA) }
- + | '真' { _PyAST_MatchSingleton(Py_True, EXTRA) }
- | 'True' { _PyAST_MatchSingleton(Py_True, EXTRA) }
- + | '假' { _PyAST_MatchSingleton(Py_False, EXTRA) }
- | 'False' { _PyAST_MatchSingleton(Py_False, EXTRA) }
- # Literal expressions are used to restrict permitted mapping pattern keys
- @@ -535,8 +643,11 @@ literal_expr[expr_ty]:
- | signed_number !('+' | '-')
- | complex_number
- | &(STRING|FSTRING_START|TSTRING_START) strings
- + | '無' { _PyAST_Constant(Py_None, NULL, EXTRA) }
- | 'None' { _PyAST_Constant(Py_None, NULL, EXTRA) }
- + | '真' { _PyAST_Constant(Py_True, NULL, EXTRA) }
- | 'True' { _PyAST_Constant(Py_True, NULL, EXTRA) }
- + | '假' { _PyAST_Constant(Py_False, NULL, EXTRA) }
- | 'False' { _PyAST_Constant(Py_False, NULL, EXTRA) }
- complex_number[expr_ty]:
- @@ -705,11 +816,14 @@ expressions[expr_ty]:
- expression[expr_ty] (memo):
- | invalid_expression
- | invalid_legacy_expression
- + | a=disjunction '如' b=disjunction '另' c=expression { _PyAST_IfExp(b, a, c, EXTRA) }
- | a=disjunction 'if' b=disjunction 'else' c=expression { _PyAST_IfExp(b, a, c, EXTRA) }
- | disjunction
- | lambdef
- yield_expr[expr_ty]:
- + | '讓從' a=expression { _PyAST_YieldFrom(a, EXTRA) }
- + | '讓' '從' a=expression { _PyAST_YieldFrom(a, EXTRA) }
- | 'yield' 'from' a=expression { _PyAST_YieldFrom(a, EXTRA) }
- | 'yield' a=[star_expressions] { _PyAST_Yield(a, EXTRA) }
- @@ -754,6 +868,7 @@ conjunction[expr_ty] (memo):
- | inversion
- inversion[expr_ty] (memo):
- + | '非' a=inversion { _PyAST_UnaryOp(Not, a, EXTRA) }
- | 'not' a=inversion { _PyAST_UnaryOp(Not, a, EXTRA) }
- | comparison
- @@ -788,10 +903,10 @@ lte_bitwise_or[CmpopExprPair*]: '<=' a=bitwise_or { _PyPegen_cmpop_expr_pair(p,
- lt_bitwise_or[CmpopExprPair*]: '<' a=bitwise_or { _PyPegen_cmpop_expr_pair(p, Lt, a) }
- gte_bitwise_or[CmpopExprPair*]: '>=' a=bitwise_or { _PyPegen_cmpop_expr_pair(p, GtE, a) }
- gt_bitwise_or[CmpopExprPair*]: '>' a=bitwise_or { _PyPegen_cmpop_expr_pair(p, Gt, a) }
- -notin_bitwise_or[CmpopExprPair*]: 'not' 'in' a=bitwise_or { _PyPegen_cmpop_expr_pair(p, NotIn, a) }
- -in_bitwise_or[CmpopExprPair*]: 'in' a=bitwise_or { _PyPegen_cmpop_expr_pair(p, In, a) }
- -isnot_bitwise_or[CmpopExprPair*]: 'is' 'not' a=bitwise_or { _PyPegen_cmpop_expr_pair(p, IsNot, a) }
- -is_bitwise_or[CmpopExprPair*]: 'is' a=bitwise_or { _PyPegen_cmpop_expr_pair(p, Is, a) }
- +notin_bitwise_or[CmpopExprPair*]: ('非在'|'非' '在'|'not' 'in') a=bitwise_or { _PyPegen_cmpop_expr_pair(p, NotIn, a) }
- +in_bitwise_or[CmpopExprPair*]: ('在'|'in') a=bitwise_or { _PyPegen_cmpop_expr_pair(p, In, a) }
- +isnot_bitwise_or[CmpopExprPair*]: ('是非'|'是' '非'|'is' 'not') a=bitwise_or { _PyPegen_cmpop_expr_pair(p, IsNot, a) }
- +is_bitwise_or[CmpopExprPair*]: ('是'|'is') a=bitwise_or { _PyPegen_cmpop_expr_pair(p, Is, a) }
- # Bitwise operators
- # -----------------
- @@ -847,6 +962,7 @@ power[expr_ty]:
- # Primary elements are things like "obj.something.something", "obj[something]", "obj(something)", "obj" ...
- await_primary[expr_ty] (memo):
- + | '待' a=primary { CHECK_VERSION(expr_ty, 5, "Await expressions are", _PyAST_Await(a, EXTRA)) }
- | 'await' a=primary { CHECK_VERSION(expr_ty, 5, "Await expressions are", _PyAST_Await(a, EXTRA)) }
- | primary
- @@ -871,8 +987,11 @@ slice[expr_ty]:
- atom[expr_ty]:
- | NAME
- + | '真' { _PyAST_Constant(Py_True, NULL, EXTRA) }
- | 'True' { _PyAST_Constant(Py_True, NULL, EXTRA) }
- + | '假' { _PyAST_Constant(Py_False, NULL, EXTRA) }
- | 'False' { _PyAST_Constant(Py_False, NULL, EXTRA) }
- + | '無' { _PyAST_Constant(Py_None, NULL, EXTRA) }
- | 'None' { _PyAST_Constant(Py_None, NULL, EXTRA) }
- | &(STRING|FSTRING_START|TSTRING_START) strings
- | NUMBER
- @@ -889,6 +1008,8 @@ group[expr_ty]:
- # ----------------
- lambdef[expr_ty]:
- + | '匿' a=[lambda_params] ':' b=expression {
- + _PyAST_Lambda((a) ? a : CHECK(arguments_ty, _PyPegen_empty_arguments(p)), b, EXTRA) }
- | 'lambda' a=[lambda_params] ':' b=expression {
- _PyAST_Lambda((a) ? a : CHECK(arguments_ty, _PyPegen_empty_arguments(p)), b, EXTRA) }
- @@ -1023,8 +1144,14 @@ for_if_clauses[asdl_comprehension_seq*]:
- | a[asdl_comprehension_seq*]=for_if_clause+ { a }
- for_if_clause[comprehension_ty]:
- + | '離為' a=star_targets '在' ~ b=disjunction c[asdl_expr_seq*]=('如' z=disjunction { z })* {
- + CHECK_VERSION(comprehension_ty, 6, "Async comprehensions are", _PyAST_comprehension(a, b, c, 1, p->arena)) }
- + | '離' '為' a=star_targets '在' ~ b=disjunction c[asdl_expr_seq*]=('如' z=disjunction { z })* {
- + CHECK_VERSION(comprehension_ty, 6, "Async comprehensions are", _PyAST_comprehension(a, b, c, 1, p->arena)) }
- | 'async' 'for' a=star_targets 'in' ~ b=disjunction c[asdl_expr_seq*]=('if' z=disjunction { z })* {
- CHECK_VERSION(comprehension_ty, 6, "Async comprehensions are", _PyAST_comprehension(a, b, c, 1, p->arena)) }
- + | '為' a=star_targets '在' ~ b=disjunction c[asdl_expr_seq*]=('如' z=disjunction { z })* {
- + _PyAST_comprehension(a, b, c, 0, p->arena) }
- | 'for' a=star_targets 'in' ~ b=disjunction c[asdl_expr_seq*]=('if' z=disjunction { z })* {
- _PyAST_comprehension(a, b, c, 0, p->arena) }
- | invalid_for_if_clause
- @@ -1203,7 +1330,7 @@ invalid_arguments:
- RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, _PyPegen_get_last_comprehension_item(PyPegen_last_item(b, comprehension_ty)), "Generator expression must be parenthesized") }
- | a=args ',' args { _PyPegen_arguments_parsing_error(p, a) }
- invalid_kwarg:
- - | a[Token*]=('True'|'False'|'None') b='=' {
- + | a[Token*]=('True'|'False'|'None'|'真'|'假'|'無') b='=' {
- RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "cannot assign to %s", PyBytes_AS_STRING(a->bytes)) }
- | a=NAME b='=' expression for_if_clauses {
- RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "invalid syntax. Maybe you meant '==' or ':=' instead of '='?")}
- @@ -1215,6 +1342,7 @@ invalid_kwarg:
- # IMPORTANT: Note that the "_without_invalid" suffix causes the rule to not call invalid rules under it
- expression_without_invalid[expr_ty]:
- + | a=disjunction '如' b=disjunction '另' c=expression { _PyAST_IfExp(b, a, c, EXTRA) }
- | a=disjunction 'if' b=disjunction 'else' c=expression { _PyAST_IfExp(b, a, c, EXTRA) }
- | disjunction
- | lambdef
- @@ -1244,13 +1372,22 @@ invalid_expression:
- | !(NAME STRING | SOFT_KEYWORD) a=disjunction b=expression_without_invalid {
- _PyPegen_check_legacy_stmt(p, a) ? NULL : p->tokens[p->mark-1]->level == 0 ? NULL :
- RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "invalid syntax. Perhaps you forgot a comma?") }
- + | a=disjunction '如' b=disjunction !('另'|':') { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "expected '另' after '如' expression") }
- | a=disjunction 'if' b=disjunction !('else'|':') { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "expected 'else' after 'if' expression") }
- + | a=disjunction '如' b=disjunction '另' !expression {
- + RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("expected expression after '另', but statement is given") }
- | a=disjunction 'if' b=disjunction 'else' !expression {
- RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("expected expression after 'else', but statement is given") }
- + | a[stmt_ty]=(pass_stmt|break_stmt|continue_stmt) '如' b=disjunction '另' c=simple_stmt {
- + RAISE_SYNTAX_ERROR_KNOWN_LOCATION (a, "expected expression before '如', but statement is given") }
- | a[stmt_ty]=(pass_stmt|break_stmt|continue_stmt) 'if' b=disjunction 'else' c=simple_stmt {
- RAISE_SYNTAX_ERROR_KNOWN_LOCATION (a, "expected expression before 'if', but statement is given") }
- + | a='匿' [lambda_params] b=':' &FSTRING_MIDDLE {
- + RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "f-string: lambda expressions are not allowed without parentheses") }
- | a='lambda' [lambda_params] b=':' &FSTRING_MIDDLE {
- RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "f-string: lambda expressions are not allowed without parentheses") }
- + | a='匿' [lambda_params] b=':' &TSTRING_MIDDLE {
- + RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "t-string: lambda expressions are not allowed without parentheses") }
- | a='lambda' [lambda_params] b=':' &TSTRING_MIDDLE {
- RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "t-string: lambda expressions are not allowed without parentheses") }
- @@ -1260,7 +1397,7 @@ invalid_named_expression(memo):
- a, "cannot use assignment expressions with %s", _PyPegen_get_expr_name(a)) }
- | a=NAME '=' b=bitwise_or !('='|':=') {
- RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "invalid syntax. Maybe you meant '==' or ':=' instead of '='?") }
- - | !(list|tuple|genexp|'True'|'None'|'False') a=bitwise_or b='=' bitwise_or !('='|':=') {
- + | !(list|tuple|genexp|'True'|'None'|'False'|'真'|'假'|'無') a=bitwise_or b='=' bitwise_or !('='|':=') {
- RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot assign to %s here. Maybe you meant '==' instead of '='?",
- _PyPegen_get_expr_name(a)) }
- @@ -1294,6 +1431,8 @@ invalid_raise_stmt:
- | 'raise' expression a='from' {
- RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "did you forget an expression after 'from'?") }
- invalid_del_stmt:
- + | '刪' a=star_expressions {
- + RAISE_SYNTAX_ERROR_INVALID_TARGET(DEL_TARGETS, a) }
- | 'del' a=star_expressions {
- RAISE_SYNTAX_ERROR_INVALID_TARGET(DEL_TARGETS, a) }
- invalid_block:
- @@ -1366,14 +1505,20 @@ invalid_double_type_comments:
- | TYPE_COMMENT NEWLINE TYPE_COMMENT NEWLINE INDENT {
- RAISE_SYNTAX_ERROR("Cannot have two type comments on def") }
- invalid_with_item:
- + | expression '若' a=expression &(',' | ')' | ':') {
- + RAISE_SYNTAX_ERROR_INVALID_TARGET(STAR_TARGETS, a) }
- | expression 'as' a=expression &(',' | ')' | ':') {
- RAISE_SYNTAX_ERROR_INVALID_TARGET(STAR_TARGETS, a) }
- invalid_for_if_clause:
- + | '離'? '為' (bitwise_or (',' bitwise_or)* [',']) !'in' {
- + RAISE_SYNTAX_ERROR("'in' expected after for-loop variables") }
- | 'async'? 'for' (bitwise_or (',' bitwise_or)* [',']) !'in' {
- RAISE_SYNTAX_ERROR("'in' expected after for-loop variables") }
- invalid_for_target:
- + | '離'? '為' a=star_expressions {
- + RAISE_SYNTAX_ERROR_INVALID_TARGET(FOR_TARGETS, a) }
- | 'async'? 'for' a=star_expressions {
- RAISE_SYNTAX_ERROR_INVALID_TARGET(FOR_TARGETS, a) }
- @@ -1383,15 +1528,25 @@ invalid_group:
- | '(' a='**' expression ')' {
- RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot use double starred expression here") }
- invalid_import:
- + | a='載' ','.dotted_name+ '從' dotted_name {
- + RAISE_SYNTAX_ERROR_STARTING_FROM(a, "Did you mean to use '從 ... 載...' instead?") }
- | a='import' ','.dotted_name+ 'from' dotted_name {
- RAISE_SYNTAX_ERROR_STARTING_FROM(a, "Did you mean to use 'from ... import ...' instead?") }
- + | '載' token=NEWLINE {
- + RAISE_SYNTAX_ERROR_STARTING_FROM(token, "Expected one or more names after '載'") }
- | 'import' token=NEWLINE {
- RAISE_SYNTAX_ERROR_STARTING_FROM(token, "Expected one or more names after 'import'") }
- invalid_dotted_as_name:
- + | dotted_name '若' !(NAME (',' | ')' | NEWLINE)) a=expression {
- + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a,
- + "cannot use %s as import target", _PyPegen_get_expr_name(a)) }
- | dotted_name 'as' !(NAME (',' | ')' | NEWLINE)) a=expression {
- RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a,
- "cannot use %s as import target", _PyPegen_get_expr_name(a)) }
- invalid_import_from_as_name:
- + | NAME '若' !(NAME (',' | ')' | NEWLINE)) a=expression {
- + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a,
- + "cannot use %s as import target", _PyPegen_get_expr_name(a)) }
- | NAME 'as' !(NAME (',' | ')' | NEWLINE)) a=expression {
- RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a,
- "cannot use %s as import target", _PyPegen_get_expr_name(a)) }
- @@ -1403,46 +1558,80 @@ invalid_import_from_targets:
- RAISE_SYNTAX_ERROR_STARTING_FROM(token, "Expected one or more names after 'import'") }
- invalid_with_stmt:
- + | ['離'] '用' ','.(expression ['若' star_target])+ NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
- | ['async'] 'with' ','.(expression ['as' star_target])+ NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
- + | ['離'] '用' '(' ','.(expressions ['若' star_target])+ ','? ')' NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
- | ['async'] 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
- invalid_with_stmt_indent:
- + | ['離'] a='用' ','.(expression ['若' star_target])+ ':' NEWLINE !INDENT {
- + RAISE_INDENTATION_ERROR("expected an indented block after 'with' statement on line %d", a->lineno) }
- | ['async'] a='with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT {
- RAISE_INDENTATION_ERROR("expected an indented block after 'with' statement on line %d", a->lineno) }
- + | ['離'] a='用' '(' ','.(expressions ['若' star_target])+ ','? ')' ':' NEWLINE !INDENT {
- + RAISE_INDENTATION_ERROR("expected an indented block after 'with' statement on line %d", a->lineno) }
- | ['async'] a='with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT {
- RAISE_INDENTATION_ERROR("expected an indented block after 'with' statement on line %d", a->lineno) }
- invalid_try_stmt:
- + | a='試' ':' NEWLINE !INDENT {
- + RAISE_INDENTATION_ERROR("expected an indented block after '試' statement on line %d", a->lineno) }
- | a='try' ':' NEWLINE !INDENT {
- RAISE_INDENTATION_ERROR("expected an indented block after 'try' statement on line %d", a->lineno) }
- + | '試' ':' block !('除' | '終') { RAISE_SYNTAX_ERROR("expected '除' or '終' block") }
- | 'try' ':' block !('except' | 'finally') { RAISE_SYNTAX_ERROR("expected 'except' or 'finally' block") }
- + | '試' ':' block* except_block+ a='除' b='*' expression ['若' NAME] ':' {
- + RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "cannot have both '除' and '除*' on the same '試'") }
- | 'try' ':' block* except_block+ a='except' b='*' expression ['as' NAME] ':' {
- RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "cannot have both 'except' and 'except*' on the same 'try'") }
- + | '試' ':' block* except_star_block+ a='except' [expression ['as' NAME]] ':' {
- + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot have both '除' and '除*' on the same '試'") }
- | 'try' ':' block* except_star_block+ a='except' [expression ['as' NAME]] ':' {
- RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot have both 'except' and 'except*' on the same 'try'") }
- invalid_except_stmt:
- + | '除' a=expression ',' expressions '若' NAME ':' {
- + RAISE_SYNTAX_ERROR_STARTING_FROM(a, "multiple exception types must be parenthesized when using 'as'") }
- | 'except' a=expression ',' expressions 'as' NAME ':' {
- RAISE_SYNTAX_ERROR_STARTING_FROM(a, "multiple exception types must be parenthesized when using 'as'") }
- + | a='除' expression ['若' NAME ] NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
- | a='except' expression ['as' NAME ] NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
- + | a='除' NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
- | a='except' NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
- + | '除' expression '若' a=expression ':' block {
- + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
- + a, "cannot use except statement with %s", _PyPegen_get_expr_name(a)) }
- | 'except' expression 'as' a=expression ':' block {
- RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
- a, "cannot use except statement with %s", _PyPegen_get_expr_name(a)) }
- invalid_except_star_stmt:
- + | '除' '*' a=expression ',' expressions '若' NAME ':' {
- + RAISE_SYNTAX_ERROR_STARTING_FROM(a, "multiple exception types must be parenthesized when using 'as'") }
- | 'except' '*' a=expression ',' expressions 'as' NAME ':' {
- RAISE_SYNTAX_ERROR_STARTING_FROM(a, "multiple exception types must be parenthesized when using 'as'") }
- + | a='除' '*' expression ['若' NAME ] NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
- | a='except' '*' expression ['as' NAME ] NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
- + | a='除' '*' (NEWLINE | ':') { RAISE_SYNTAX_ERROR("expected one or more exception types") }
- | a='except' '*' (NEWLINE | ':') { RAISE_SYNTAX_ERROR("expected one or more exception types") }
- + | '除' '*' expression '若' a=expression ':' block {
- + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
- + a, "cannot use except* statement with %s", _PyPegen_get_expr_name(a)) }
- | 'except' '*' expression 'as' a=expression ':' block {
- RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
- a, "cannot use except* statement with %s", _PyPegen_get_expr_name(a)) }
- invalid_finally_stmt:
- + | a='終' ':' NEWLINE !INDENT {
- + RAISE_INDENTATION_ERROR("expected an indented block after '終' statement on line %d", a->lineno) }
- | a='finally' ':' NEWLINE !INDENT {
- RAISE_INDENTATION_ERROR("expected an indented block after 'finally' statement on line %d", a->lineno) }
- invalid_except_stmt_indent:
- + | a='除' expression ['若' NAME ] ':' NEWLINE !INDENT {
- + RAISE_INDENTATION_ERROR("expected an indented block after '除' statement on line %d", a->lineno) }
- | a='except' expression ['as' NAME ] ':' NEWLINE !INDENT {
- RAISE_INDENTATION_ERROR("expected an indented block after 'except' statement on line %d", a->lineno) }
- + | a='除' ':' NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block after '除' statement on line %d", a->lineno) }
- | a='except' ':' NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block after 'except' statement on line %d", a->lineno) }
- invalid_except_star_stmt_indent:
- + | a='除' '*' expression ['若' NAME ] ':' NEWLINE !INDENT {
- + RAISE_INDENTATION_ERROR("expected an indented block after '除*' statement on line %d", a->lineno) }
- | a='except' '*' expression ['as' NAME ] ':' NEWLINE !INDENT {
- RAISE_INDENTATION_ERROR("expected an indented block after 'except*' statement on line %d", a->lineno) }
- invalid_match_stmt:
- @@ -1454,7 +1643,11 @@ invalid_case_block:
- | a="case" patterns guard? ':' NEWLINE !INDENT {
- RAISE_INDENTATION_ERROR("expected an indented block after 'case' statement on line %d", a->lineno) }
- invalid_as_pattern:
- + | or_pattern '若' a="_" { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot use '_' as a target") }
- | or_pattern 'as' a="_" { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot use '_' as a target") }
- + | or_pattern '若' a=expression {
- + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
- + a, "cannot use %s as pattern target", _PyPegen_get_expr_name(a)) }
- | or_pattern 'as' a=expression {
- RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
- a, "cannot use %s as pattern target", _PyPegen_get_expr_name(a)) }
- @@ -1466,31 +1659,52 @@ invalid_class_pattern:
- invalid_class_argument_pattern[asdl_pattern_seq*]:
- | [positional_patterns ','] keyword_patterns ',' a=positional_patterns { a }
- invalid_if_stmt:
- + | '如' named_expression NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
- | 'if' named_expression NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
- + | a='如' a=named_expression ':' NEWLINE !INDENT {
- + RAISE_INDENTATION_ERROR("expected an indented block after '如' statement on line %d", a->lineno) }
- | a='if' a=named_expression ':' NEWLINE !INDENT {
- RAISE_INDENTATION_ERROR("expected an indented block after 'if' statement on line %d", a->lineno) }
- invalid_elif_stmt:
- + | '然' named_expression NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
- | 'elif' named_expression NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
- + | a='然' named_expression ':' NEWLINE !INDENT {
- + RAISE_INDENTATION_ERROR("expected an indented block after '然' statement on line %d", a->lineno) }
- | a='elif' named_expression ':' NEWLINE !INDENT {
- RAISE_INDENTATION_ERROR("expected an indented block after 'elif' statement on line %d", a->lineno) }
- invalid_else_stmt:
- + | a='另' ':' NEWLINE !INDENT {
- + RAISE_INDENTATION_ERROR("expected an indented block after '另' statement on line %d", a->lineno) }
- | a='else' ':' NEWLINE !INDENT {
- RAISE_INDENTATION_ERROR("expected an indented block after 'else' statement on line %d", a->lineno) }
- + | '另' ':' block '然' { RAISE_SYNTAX_ERROR("'然' block follows an '另' block")}
- | 'else' ':' block 'elif' { RAISE_SYNTAX_ERROR("'elif' block follows an 'else' block")}
- invalid_while_stmt:
- + | '當' named_expression NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
- | 'while' named_expression NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
- + | a='當' named_expression ':' NEWLINE !INDENT {
- + RAISE_INDENTATION_ERROR("expected an indented block after '當' statement on line %d", a->lineno ) }
- | a='while' named_expression ':' NEWLINE !INDENT {
- RAISE_INDENTATION_ERROR("expected an indented block after 'while' statement on line %d", a->lineno) }
- invalid_for_stmt:
- + | ['離'] '為' star_targets '在' star_expressions NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
- | ['async'] 'for' star_targets 'in' star_expressions NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
- + | ['離'] a='為' star_targets '在' star_expressions ':' NEWLINE !INDENT {
- + RAISE_INDENTATION_ERROR("expected an indented block after '為' statement on line %d", a->lineno) }
- | ['async'] a='for' star_targets 'in' star_expressions ':' NEWLINE !INDENT {
- RAISE_INDENTATION_ERROR("expected an indented block after 'for' statement on line %d", a->lineno) }
- invalid_def_raw:
- + | ['離'] a='函' NAME [type_params] '(' [params] ')' ['->' expression] ':' NEWLINE !INDENT {
- + RAISE_INDENTATION_ERROR("expected an indented block after function definition on line %d", a->lineno) }
- | ['async'] a='def' NAME [type_params] '(' [params] ')' ['->' expression] ':' NEWLINE !INDENT {
- RAISE_INDENTATION_ERROR("expected an indented block after function definition on line %d", a->lineno) }
- + | ['離'] '函' NAME [type_params] &&'(' [params] ')' ['->' expression] &&':' [func_type_comment] block
- | ['async'] 'def' NAME [type_params] &&'(' [params] ')' ['->' expression] &&':' [func_type_comment] block
- invalid_class_def_raw:
- + | '類' NAME [type_params] ['(' [arguments] ')'] NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
- | 'class' NAME [type_params] ['(' [arguments] ')'] NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
- + | a='類' NAME [type_params] ['(' [arguments] ')'] ':' NEWLINE !INDENT {
- + RAISE_INDENTATION_ERROR("expected an indented block after class definition on line %d", a->lineno) }
- | a='class' NAME [type_params] ['(' [arguments] ')'] ':' NEWLINE !INDENT {
- RAISE_INDENTATION_ERROR("expected an indented block after class definition on line %d", a->lineno) }
- diff --git a/Lib/unittest/loader.py b/Lib/unittest/loader.py
- index a52950dad22..3d3ee7608bd 100644
- --- a/Lib/unittest/loader.py
- +++ b/Lib/unittest/loader.py
- @@ -65,7 +65,7 @@ class TestLoader(object):
- This class is responsible for loading tests according to various criteria
- and returning them wrapped in a TestSuite
- """
- - testMethodPrefix = 'test'
- + testMethodPrefix = ['test', '測']
- sortTestMethodsUsing = staticmethod(util.three_way_cmp)
- testNamePatterns = None
- suiteClass = suite.TestSuite
- @@ -211,7 +211,7 @@ def getTestCaseNames(self, testCaseClass):
- """Return a sorted sequence of method names found within testCaseClass
- """
- def shouldIncludeMethod(attrname):
- - if not attrname.startswith(self.testMethodPrefix):
- + if not any([attrname.startswith(prefix) for prefix in self.testMethodPrefix]):
- return False
- testFunc = getattr(testCaseClass, attrname)
- if not callable(testFunc):
- diff --git "a/Lib/\346\270\254\345\226\256\345\205\203/__init__.py" "b/Lib/\346\270\254\345\226\256\345\205\203/__init__.py"
- new file mode 100644
- index 00000000000..551222b63d4
- --- /dev/null
- +++ "b/Lib/\346\270\254\345\226\256\345\205\203/__init__.py"
- @@ -0,0 +1,3 @@
- +import unittest
- +
- +from unittest.case import TestCase as 測例子
- diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
- index e08c63924ca..c2ba2fc1cc6 100644
- --- a/Python/bltinmodule.c
- +++ b/Python/bltinmodule.c
- @@ -3384,6 +3384,7 @@ _PyBuiltin_Init(PyInterpreterState *interp)
- SETBUILTIN("classmethod", &PyClassMethod_Type);
- SETBUILTIN("complex", &PyComplex_Type);
- SETBUILTIN("dict", &PyDict_Type);
- + SETBUILTIN("字典", &PyDict_Type);
- SETBUILTIN("enumerate", &PyEnum_Type);
- SETBUILTIN("filter", &PyFilter_Type);
- SETBUILTIN("float", &PyFloat_Type);
- @@ -3394,6 +3395,7 @@ _PyBuiltin_Init(PyInterpreterState *interp)
- SETBUILTIN("map", &PyMap_Type);
- SETBUILTIN("object", &PyBaseObject_Type);
- SETBUILTIN("range", &PyRange_Type);
- + SETBUILTIN("區間", &PyRange_Type);
- SETBUILTIN("reversed", &PyReversed_Type);
- SETBUILTIN("set", &PySet_Type);
- SETBUILTIN("slice", &PySlice_Type);
- diff --git a/Python/clinic/bltinmodule.c.h b/Python/clinic/bltinmodule.c.h
- index c826a5724f7..c77102bb3ae 100644
- --- a/Python/clinic/bltinmodule.c.h
- +++ b/Python/clinic/bltinmodule.c.h
- @@ -926,7 +926,8 @@ PyDoc_STRVAR(builtin_print__doc__,
- " whether to forcibly flush the stream.");
- #define BUILTIN_PRINT_METHODDEF \
- - {"print", _PyCFunction_CAST(builtin_print), METH_FASTCALL|METH_KEYWORDS, builtin_print__doc__},
- + {"print", _PyCFunction_CAST(builtin_print), METH_FASTCALL|METH_KEYWORDS, builtin_print__doc__}, \
- + {"印", _PyCFunction_CAST(builtin_print), METH_FASTCALL|METH_KEYWORDS, builtin_print__doc__},
- static PyObject *
- builtin_print_impl(PyObject *module, PyObject * const *args,
- diff --git a/Tools/peg_generator/pegen/c_generator.py b/Tools/peg_generator/pegen/c_generator.py
- index 09c5651f24a..63c6ce78f06 100644
- --- a/Tools/peg_generator/pegen/c_generator.py
- +++ b/Tools/peg_generator/pegen/c_generator.py
- @@ -26,6 +26,7 @@
- Rule,
- StringLeaf,
- )
- +from pegen.parser_generator import ckeywords
- from pegen.parser_generator import ParserGenerator
- EXTENSION_PREFIX = """\
- @@ -189,7 +190,7 @@ def visit_NameLeaf(self, node: NameLeaf) -> FunctionCall:
- def visit_StringLeaf(self, node: StringLeaf) -> FunctionCall:
- val = ast.literal_eval(node.value)
- - if re.match(r"[a-zA-Z_]\w*\Z", val): # This is a keyword
- + if re.match(r"[a-zA-Z_]\w*\Z", val) or val in ckeywords: # This is a keyword
- if node.value.endswith("'"):
- return self.keyword_helper(val)
- else:
- @@ -480,7 +481,7 @@ def generate(self, filename: str) -> None:
- def _group_keywords_by_length(self) -> Dict[int, List[Tuple[str, int]]]:
- groups: Dict[int, List[Tuple[str, int]]] = {}
- for keyword_str, keyword_type in self.keywords.items():
- - length = len(keyword_str)
- + length = len(keyword_str.encode('utf-8'))
- if length in groups:
- groups[length].append((keyword_str, keyword_type))
- else:
- diff --git a/Tools/peg_generator/pegen/parser_generator.py b/Tools/peg_generator/pegen/parser_generator.py
- index 52ae743c26b..b459013dd33 100644
- --- a/Tools/peg_generator/pegen/parser_generator.py
- +++ b/Tools/peg_generator/pegen/parser_generator.py
- @@ -40,6 +40,7 @@
- StringLeaf,
- )
- +ckeywords = {'過', '回', '示', '過', '讓', '從', '刪', '宣', '斷', '續', '寰', '異', '函', '離', '如', '類', '用', '為', '試', '當', '若', '類', '函', '然', '另', '除', '終', '在', '無', '真', '假', '非', '待', '匿', '是', '載', '離函', '離為', '離用', '非在', '讓從', '是非'}
- class RuleCollectorVisitor(GrammarVisitor):
- """Visitor that invokes a provided callmaker visitor with just the NamedItem nodes"""
- @@ -65,7 +66,7 @@ def __init__(self, gen: "ParserGenerator", keywords: Dict[str, int], soft_keywor
- def visit_StringLeaf(self, node: StringLeaf) -> None:
- val = ast.literal_eval(node.value)
- - if re.match(r"[a-zA-Z_]\w*\Z", val): # This is a keyword
- + if re.match(r"[a-zA-Z_]\w*\Z", val) or val in ckeywords: # This is a keyword
- if node.value.endswith("'") and node.value not in self.keywords:
- self.keywords[val] = self.generator.keyword_type()
- else:
Advertisement
Add Comment
Please, Sign In to add comment