Guest User

Untitled

a guest
Jun 8th, 2025
256
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 46.17 KB | None | 0 0
  1. diff --git a/Grammar/python.gram b/Grammar/python.gram
  2. index a5ab769910b..08827832789 100644
  3. --- a/Grammar/python.gram
  4. +++ b/Grammar/python.gram
  5. @@ -120,26 +120,26 @@ simple_stmt[stmt_ty] (memo):
  6. | assignment
  7. | &"type" type_alias
  8. | e=star_expressions { _PyAST_Expr(e, EXTRA) }
  9. - | &'return' return_stmt
  10. - | &('import' | 'from') import_stmt
  11. - | &'raise' raise_stmt
  12. - | &'pass' pass_stmt
  13. - | &'del' del_stmt
  14. - | &'yield' yield_stmt
  15. - | &'assert' assert_stmt
  16. - | &'break' break_stmt
  17. - | &'continue' continue_stmt
  18. - | &'global' global_stmt
  19. - | &'nonlocal' nonlocal_stmt
  20. + | &('return' | '回') return_stmt
  21. + | &('import' | 'from' | '載' | '從') import_stmt
  22. + | &('raise' | '示') raise_stmt
  23. + | &('pass' | '過') pass_stmt
  24. + | &('del' | '刪') del_stmt
  25. + | &('yield' | '讓') yield_stmt
  26. + | &('assert' | '宣') assert_stmt
  27. + | &('break' | '斷') break_stmt
  28. + | &('continue' | '續') continue_stmt
  29. + | &('global' | '寰') global_stmt
  30. + | &('nonlocal' | '異') nonlocal_stmt
  31.  
  32. compound_stmt[stmt_ty]:
  33. - | &('def' | '@' | 'async') function_def
  34. - | &'if' if_stmt
  35. - | &('class' | '@') class_def
  36. - | &('with' | 'async') with_stmt
  37. - | &('for' | 'async') for_stmt
  38. - | &'try' try_stmt
  39. - | &'while' while_stmt
  40. + | &('def' | '函' | '@' | 'async' | '離') function_def
  41. + | &('if' | '如') if_stmt
  42. + | &('class' | '類' | '@') class_def
  43. + | &('with' | '用' | 'async' | '離') with_stmt
  44. + | &('for' | '為' | 'async' | '離') for_stmt
  45. + | &('try' | '試') try_stmt
  46. + | &('while' | '當') while_stmt
  47. | match_stmt
  48.  
  49. # SIMPLE STATEMENTS
  50. @@ -181,35 +181,49 @@ augassign[AugOperator*]:
  51. | '//=' { _PyPegen_augoperator(p, FloorDiv) }
  52.  
  53. return_stmt[stmt_ty]:
  54. + | '回' a=[star_expressions] { _PyAST_Return(a, EXTRA) }
  55. | 'return' a=[star_expressions] { _PyAST_Return(a, EXTRA) }
  56.  
  57. raise_stmt[stmt_ty]:
  58. | invalid_raise_stmt
  59. + | '示' a=expression b=['從' z=expression { z }] { _PyAST_Raise(a, b, EXTRA) }
  60. | 'raise' a=expression b=['from' z=expression { z }] { _PyAST_Raise(a, b, EXTRA) }
  61. + | '示' { _PyAST_Raise(NULL, NULL, EXTRA) }
  62. | 'raise' { _PyAST_Raise(NULL, NULL, EXTRA) }
  63.  
  64. pass_stmt[stmt_ty]:
  65. + | '過' { _PyAST_Pass(EXTRA) }
  66. | 'pass' { _PyAST_Pass(EXTRA) }
  67.  
  68. break_stmt[stmt_ty]:
  69. + | '斷' { _PyAST_Break(EXTRA) }
  70. | 'break' { _PyAST_Break(EXTRA) }
  71.  
  72. continue_stmt[stmt_ty]:
  73. + | '續' { _PyAST_Continue(EXTRA) }
  74. | 'continue' { _PyAST_Continue(EXTRA) }
  75.  
  76. -global_stmt[stmt_ty]: 'global' a[asdl_expr_seq*]=','.NAME+ {
  77. - _PyAST_Global(CHECK(asdl_identifier_seq*, _PyPegen_map_names_to_ids(p, a)), EXTRA) }
  78. -
  79. -nonlocal_stmt[stmt_ty]: 'nonlocal' a[asdl_expr_seq*]=','.NAME+ {
  80. +global_stmt[stmt_ty]:
  81. + | '寰' a[asdl_expr_seq*]=','.NAME+ {
  82. + _PyAST_Global(CHECK(asdl_identifier_seq*, _PyPegen_map_names_to_ids(p, a)), EXTRA) }
  83. + | 'global' a[asdl_expr_seq*]=','.NAME+ {
  84. + _PyAST_Global(CHECK(asdl_identifier_seq*, _PyPegen_map_names_to_ids(p, a)), EXTRA) }
  85. +nonlocal_stmt[stmt_ty]:
  86. + | '異' a[asdl_expr_seq*]=','.NAME+ {
  87. + _PyAST_Nonlocal(CHECK(asdl_identifier_seq*, _PyPegen_map_names_to_ids(p, a)), EXTRA) }
  88. + | 'nonlocal' a[asdl_expr_seq*]=','.NAME+ {
  89. _PyAST_Nonlocal(CHECK(asdl_identifier_seq*, _PyPegen_map_names_to_ids(p, a)), EXTRA) }
  90.  
  91. del_stmt[stmt_ty]:
  92. + | '刪' a=del_targets &(';' | NEWLINE) { _PyAST_Delete(a, EXTRA) }
  93. | 'del' a=del_targets &(';' | NEWLINE) { _PyAST_Delete(a, EXTRA) }
  94. | invalid_del_stmt
  95.  
  96. yield_stmt[stmt_ty]: y=yield_expr { _PyAST_Expr(y, EXTRA) }
  97.  
  98. -assert_stmt[stmt_ty]: 'assert' a=expression b=[',' z=expression { z }] { _PyAST_Assert(a, b, EXTRA) }
  99. +assert_stmt[stmt_ty]:
  100. + | '宣' a=expression b=[',' z=expression { z }] { _PyAST_Assert(a, b, EXTRA) }
  101. + | 'assert' a=expression b=[',' z=expression { z }] { _PyAST_Assert(a, b, EXTRA) }
  102.  
  103. import_stmt[stmt_ty]:
  104. | invalid_import
  105. @@ -219,11 +233,17 @@ import_stmt[stmt_ty]:
  106. # Import statements
  107. # -----------------
  108.  
  109. -import_name[stmt_ty]: 'import' a=dotted_as_names { _PyAST_Import(a, EXTRA) }
  110. +import_name[stmt_ty]:
  111. + | '載' a=dotted_as_names { _PyAST_Import(a, EXTRA) }
  112. + | 'import' a=dotted_as_names { _PyAST_Import(a, EXTRA) }
  113. # note below: the ('.' | '...') is necessary because '...' is tokenized as ELLIPSIS
  114. import_from[stmt_ty]:
  115. + | '從' a=('.' | '...')* b=dotted_name '載' c=import_from_targets {
  116. + _PyPegen_checked_future_import(p, b->v.Name.id, c, _PyPegen_seq_count_dots(a), EXTRA) }
  117. | 'from' a=('.' | '...')* b=dotted_name 'import' c=import_from_targets {
  118. _PyPegen_checked_future_import(p, b->v.Name.id, c, _PyPegen_seq_count_dots(a), EXTRA) }
  119. + | '從' a=('.' | '...')+ '載' b=import_from_targets {
  120. + _PyAST_ImportFrom(NULL, b, _PyPegen_seq_count_dots(a), EXTRA) }
  121. | 'from' a=('.' | '...')+ 'import' b=import_from_targets {
  122. _PyAST_ImportFrom(NULL, b, _PyPegen_seq_count_dots(a), EXTRA) }
  123. import_from_targets[asdl_alias_seq*]:
  124. @@ -235,14 +255,14 @@ import_from_as_names[asdl_alias_seq*]:
  125. | a[asdl_alias_seq*]=','.import_from_as_name+ { a }
  126. import_from_as_name[alias_ty]:
  127. | invalid_import_from_as_name
  128. - | a=NAME b=['as' z=NAME { z }] { _PyAST_alias(
  129. + | a=NAME b=[('as'|'若') z=NAME { z }] { _PyAST_alias(
  130. a->v.Name.id, (b) ? ((expr_ty) b)->v.Name.id : NULL, EXTRA) }
  131.  
  132. dotted_as_names[asdl_alias_seq*]:
  133. | a[asdl_alias_seq*]=','.dotted_as_name+ { a }
  134. dotted_as_name[alias_ty]:
  135. | invalid_dotted_as_name
  136. - | a=dotted_name b=['as' z=NAME { z }] { _PyAST_alias(
  137. + | a=dotted_name b=[('as'|'若') z=NAME { z }] { _PyAST_alias(
  138. a->v.Name.id, (b) ? ((expr_ty) b)->v.Name.id : NULL, EXTRA) }
  139.  
  140. dotted_name[expr_ty]:
  141. @@ -271,6 +291,11 @@ class_def[stmt_ty]:
  142.  
  143. class_def_raw[stmt_ty]:
  144. | invalid_class_def_raw
  145. + | '類' a=NAME t=[type_params] b=['(' z=[arguments] ')' { z }] ':' c=block {
  146. + _PyAST_ClassDef(a->v.Name.id,
  147. + (b) ? ((expr_ty) b)->v.Call.args : NULL,
  148. + (b) ? ((expr_ty) b)->v.Call.keywords : NULL,
  149. + c, NULL, t, EXTRA) }
  150. | 'class' a=NAME t=[type_params] b=['(' z=[arguments] ')' { z }] ':' c=block {
  151. _PyAST_ClassDef(a->v.Name.id,
  152. (b) ? ((expr_ty) b)->v.Call.args : NULL,
  153. @@ -286,10 +311,32 @@ function_def[stmt_ty]:
  154.  
  155. function_def_raw[stmt_ty]:
  156. | invalid_def_raw
  157. + | '函' n=NAME t=[type_params] '(' params=[params] ')' a=['->' z=expression { z }] ':' tc=[func_type_comment] b=block {
  158. + _PyAST_FunctionDef(n->v.Name.id,
  159. + (params) ? params : CHECK(arguments_ty, _PyPegen_empty_arguments(p)),
  160. + b, NULL, a, NEW_TYPE_COMMENT(p, tc), t, EXTRA) }
  161. | 'def' n=NAME t=[type_params] '(' params=[params] ')' a=['->' z=expression { z }] ':' tc=[func_type_comment] b=block {
  162. _PyAST_FunctionDef(n->v.Name.id,
  163. (params) ? params : CHECK(arguments_ty, _PyPegen_empty_arguments(p)),
  164. b, NULL, a, NEW_TYPE_COMMENT(p, tc), t, EXTRA) }
  165. + | '離函' n=NAME t=[type_params] '(' params=[params] ')' a=['->' z=expression { z }] ':' tc=[func_type_comment] b=block {
  166. + CHECK_VERSION(
  167. + stmt_ty,
  168. + 5,
  169. + "Async functions are",
  170. + _PyAST_AsyncFunctionDef(n->v.Name.id,
  171. + (params) ? params : CHECK(arguments_ty, _PyPegen_empty_arguments(p)),
  172. + b, NULL, a, NEW_TYPE_COMMENT(p, tc), t, EXTRA)
  173. + ) }
  174. + | '離' '函' n=NAME t=[type_params] '(' params=[params] ')' a=['->' z=expression { z }] ':' tc=[func_type_comment] b=block {
  175. + CHECK_VERSION(
  176. + stmt_ty,
  177. + 5,
  178. + "Async functions are",
  179. + _PyAST_AsyncFunctionDef(n->v.Name.id,
  180. + (params) ? params : CHECK(arguments_ty, _PyPegen_empty_arguments(p)),
  181. + b, NULL, a, NEW_TYPE_COMMENT(p, tc), t, EXTRA)
  182. + ) }
  183. | 'async' 'def' n=NAME t=[type_params] '(' params=[params] ')' a=['->' z=expression { z }] ':' tc=[func_type_comment] b=block {
  184. CHECK_VERSION(
  185. stmt_ty,
  186. @@ -377,16 +424,23 @@ default[expr_ty]: '=' a=expression { a } | invalid_default
  187.  
  188. if_stmt[stmt_ty]:
  189. | invalid_if_stmt
  190. + | '如' a=named_expression ':' b=block c=elif_stmt {
  191. + _PyAST_If(a, b, CHECK(asdl_stmt_seq*, _PyPegen_singleton_seq(p, c)), EXTRA) }
  192. | 'if' a=named_expression ':' b=block c=elif_stmt {
  193. _PyAST_If(a, b, CHECK(asdl_stmt_seq*, _PyPegen_singleton_seq(p, c)), EXTRA) }
  194. + | '如' a=named_expression ':' b=block c=[else_block] { _PyAST_If(a, b, c, EXTRA) }
  195. | 'if' a=named_expression ':' b=block c=[else_block] { _PyAST_If(a, b, c, EXTRA) }
  196. elif_stmt[stmt_ty]:
  197. | invalid_elif_stmt
  198. + | '然' a=named_expression ':' b=block c=elif_stmt {
  199. + _PyAST_If(a, b, CHECK(asdl_stmt_seq*, _PyPegen_singleton_seq(p, c)), EXTRA) }
  200. | 'elif' a=named_expression ':' b=block c=elif_stmt {
  201. _PyAST_If(a, b, CHECK(asdl_stmt_seq*, _PyPegen_singleton_seq(p, c)), EXTRA) }
  202. + | '然' a=named_expression ':' b=block c=[else_block] { _PyAST_If(a, b, c, EXTRA) }
  203. | 'elif' a=named_expression ':' b=block c=[else_block] { _PyAST_If(a, b, c, EXTRA) }
  204. else_block[asdl_stmt_seq*]:
  205. | invalid_else_stmt
  206. + | '另' &&':' b=block { b }
  207. | 'else' &&':' b=block { b }
  208.  
  209. # While statement
  210. @@ -394,6 +448,7 @@ else_block[asdl_stmt_seq*]:
  211.  
  212. while_stmt[stmt_ty]:
  213. | invalid_while_stmt
  214. + | '當' a=named_expression ':' b=block c=[else_block] { _PyAST_While(a, b, c, EXTRA) }
  215. | 'while' a=named_expression ':' b=block c=[else_block] { _PyAST_While(a, b, c, EXTRA) }
  216.  
  217. # For statement
  218. @@ -401,8 +456,14 @@ while_stmt[stmt_ty]:
  219.  
  220. for_stmt[stmt_ty]:
  221. | invalid_for_stmt
  222. + | '為' t=star_targets '在' ~ ex=star_expressions ':' tc=[TYPE_COMMENT] b=block el=[else_block] {
  223. + _PyAST_For(t, ex, b, el, NEW_TYPE_COMMENT(p, tc), EXTRA) }
  224. | 'for' t=star_targets 'in' ~ ex=star_expressions ':' tc=[TYPE_COMMENT] b=block el=[else_block] {
  225. _PyAST_For(t, ex, b, el, NEW_TYPE_COMMENT(p, tc), EXTRA) }
  226. + | '離為' t=star_targets '在' ~ ex=star_expressions ':' tc=[TYPE_COMMENT] b=block el=[else_block] {
  227. + CHECK_VERSION(stmt_ty, 5, "Async for loops are", _PyAST_AsyncFor(t, ex, b, el, NEW_TYPE_COMMENT(p, tc), EXTRA)) }
  228. + | '離' '為' t=star_targets '在' ~ ex=star_expressions ':' tc=[TYPE_COMMENT] b=block el=[else_block] {
  229. + CHECK_VERSION(stmt_ty, 5, "Async for loops are", _PyAST_AsyncFor(t, ex, b, el, NEW_TYPE_COMMENT(p, tc), EXTRA)) }
  230. | 'async' 'for' t=star_targets 'in' ~ ex=star_expressions ':' tc=[TYPE_COMMENT] b=block el=[else_block] {
  231. CHECK_VERSION(stmt_ty, 5, "Async for loops are", _PyAST_AsyncFor(t, ex, b, el, NEW_TYPE_COMMENT(p, tc), EXTRA)) }
  232. | invalid_for_target
  233. @@ -412,17 +473,30 @@ for_stmt[stmt_ty]:
  234.  
  235. with_stmt[stmt_ty]:
  236. | invalid_with_stmt_indent
  237. + | '用' '(' a[asdl_withitem_seq*]=','.with_item+ ','? ')' ':' tc=[TYPE_COMMENT] b=block {
  238. + _PyAST_With(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA) }
  239. | 'with' '(' a[asdl_withitem_seq*]=','.with_item+ ','? ')' ':' tc=[TYPE_COMMENT] b=block {
  240. _PyAST_With(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA) }
  241. + | '用' a[asdl_withitem_seq*]=','.with_item+ ':' tc=[TYPE_COMMENT] b=block {
  242. + _PyAST_With(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA) }
  243. | 'with' a[asdl_withitem_seq*]=','.with_item+ ':' tc=[TYPE_COMMENT] b=block {
  244. _PyAST_With(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA) }
  245. + | '離用' '(' a[asdl_withitem_seq*]=','.with_item+ ','? ')' ':' b=block {
  246. + CHECK_VERSION(stmt_ty, 5, "Async with statements are", _PyAST_AsyncWith(a, b, NULL, EXTRA)) }
  247. + | '離' '用' '(' a[asdl_withitem_seq*]=','.with_item+ ','? ')' ':' b=block {
  248. + CHECK_VERSION(stmt_ty, 5, "Async with statements are", _PyAST_AsyncWith(a, b, NULL, EXTRA)) }
  249. | 'async' 'with' '(' a[asdl_withitem_seq*]=','.with_item+ ','? ')' ':' b=block {
  250. CHECK_VERSION(stmt_ty, 5, "Async with statements are", _PyAST_AsyncWith(a, b, NULL, EXTRA)) }
  251. + | '離用' a[asdl_withitem_seq*]=','.with_item+ ':' tc=[TYPE_COMMENT] b=block {
  252. + CHECK_VERSION(stmt_ty, 5, "Async with statements are", _PyAST_AsyncWith(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA)) }
  253. + | '離' '用' a[asdl_withitem_seq*]=','.with_item+ ':' tc=[TYPE_COMMENT] b=block {
  254. + CHECK_VERSION(stmt_ty, 5, "Async with statements are", _PyAST_AsyncWith(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA)) }
  255. | 'async' 'with' a[asdl_withitem_seq*]=','.with_item+ ':' tc=[TYPE_COMMENT] b=block {
  256. CHECK_VERSION(stmt_ty, 5, "Async with statements are", _PyAST_AsyncWith(a, b, NEW_TYPE_COMMENT(p, tc), EXTRA)) }
  257. | invalid_with_stmt
  258.  
  259. with_item[withitem_ty]:
  260. + | e=expression '若' t=star_target &(',' | ')' | ':') { _PyAST_withitem(e, t, p->arena) }
  261. | e=expression 'as' t=star_target &(',' | ')' | ':') { _PyAST_withitem(e, t, p->arena) }
  262. | invalid_with_item
  263. | e=expression { _PyAST_withitem(e, NULL, p->arena) }
  264. @@ -432,8 +506,13 @@ with_item[withitem_ty]:
  265.  
  266. try_stmt[stmt_ty]:
  267. | invalid_try_stmt
  268. + | '試' &&':' b=block f=finally_block { _PyAST_Try(b, NULL, NULL, f, EXTRA) }
  269. | 'try' &&':' b=block f=finally_block { _PyAST_Try(b, NULL, NULL, f, EXTRA) }
  270. + | '試' &&':' b=block ex[asdl_excepthandler_seq*]=except_block+ el=[else_block] f=[finally_block] { _PyAST_Try(b, ex, el, f, EXTRA) }
  271. | 'try' &&':' b=block ex[asdl_excepthandler_seq*]=except_block+ el=[else_block] f=[finally_block] { _PyAST_Try(b, ex, el, f, EXTRA) }
  272. + | '試' &&':' b=block ex[asdl_excepthandler_seq*]=except_star_block+ el=[else_block] f=[finally_block] {
  273. + CHECK_VERSION(stmt_ty, 11, "Exception groups are",
  274. + _PyAST_TryStar(b, ex, el, f, EXTRA)) }
  275. | 'try' &&':' b=block ex[asdl_excepthandler_seq*]=except_star_block+ el=[else_block] f=[finally_block] {
  276. CHECK_VERSION(stmt_ty, 11, "Exception groups are",
  277. _PyAST_TryStar(b, ex, el, f, EXTRA)) }
  278. @@ -444,24 +523,45 @@ try_stmt[stmt_ty]:
  279.  
  280. except_block[excepthandler_ty]:
  281. | invalid_except_stmt_indent
  282. + | '除' e=expression ':' b=block {
  283. + _PyAST_ExceptHandler(e, NULL, b, EXTRA) }
  284. | 'except' e=expression ':' b=block {
  285. _PyAST_ExceptHandler(e, NULL, b, EXTRA) }
  286. + | '除' e=expression '若' t=NAME ':' b=block {
  287. + _PyAST_ExceptHandler(e, ((expr_ty) t)->v.Name.id, b, EXTRA) }
  288. | 'except' e=expression 'as' t=NAME ':' b=block {
  289. _PyAST_ExceptHandler(e, ((expr_ty) t)->v.Name.id, b, EXTRA) }
  290. + | '除' e=expressions ':' b=block {
  291. + CHECK_VERSION(
  292. + excepthandler_ty,
  293. + 14,
  294. + "except expressions without parentheses are",
  295. + _PyAST_ExceptHandler(e, NULL, b, EXTRA)) }
  296. | 'except' e=expressions ':' b=block {
  297. CHECK_VERSION(
  298. excepthandler_ty,
  299. 14,
  300. "except expressions without parentheses are",
  301. _PyAST_ExceptHandler(e, NULL, b, EXTRA)) }
  302. + | '除' ':' b=block { _PyAST_ExceptHandler(NULL, NULL, b, EXTRA) }
  303. | 'except' ':' b=block { _PyAST_ExceptHandler(NULL, NULL, b, EXTRA) }
  304. | invalid_except_stmt
  305. except_star_block[excepthandler_ty]:
  306. | invalid_except_star_stmt_indent
  307. + | '除' '*' e=expression ':' b=block {
  308. + _PyAST_ExceptHandler(e, NULL, b, EXTRA) }
  309. | 'except' '*' e=expression ':' b=block {
  310. _PyAST_ExceptHandler(e, NULL, b, EXTRA) }
  311. + | '除' '*' e=expression '若' t=NAME ':' b=block {
  312. + _PyAST_ExceptHandler(e, ((expr_ty) t)->v.Name.id, b, EXTRA) }
  313. | 'except' '*' e=expression 'as' t=NAME ':' b=block {
  314. _PyAST_ExceptHandler(e, ((expr_ty) t)->v.Name.id, b, EXTRA) }
  315. + | '除' '*' e=expressions ':' b=block {
  316. + CHECK_VERSION(
  317. + excepthandler_ty,
  318. + 14,
  319. + "except expressions without parentheses are",
  320. + _PyAST_ExceptHandler(e, NULL, b, EXTRA)) }
  321. | 'except' '*' e=expressions ':' b=block {
  322. CHECK_VERSION(
  323. excepthandler_ty,
  324. @@ -471,6 +571,7 @@ except_star_block[excepthandler_ty]:
  325. | invalid_except_star_stmt
  326. finally_block[asdl_stmt_seq*]:
  327. | invalid_finally_stmt
  328. + | '終' &&':' a=block { a }
  329. | 'finally' &&':' a=block { a }
  330.  
  331. # Match statement
  332. @@ -491,7 +592,9 @@ case_block[match_case_ty]:
  333. | "case" pattern=patterns guard=guard? ':' body=block {
  334. _PyAST_match_case(pattern, guard, body, p->arena) }
  335.  
  336. -guard[expr_ty]: 'if' guard=named_expression { guard }
  337. +guard[expr_ty]:
  338. + | '如' guard=named_expression { guard }
  339. + | 'if' guard=named_expression { guard }
  340.  
  341. patterns[pattern_ty]:
  342. | patterns[asdl_pattern_seq*]=open_sequence_pattern {
  343. @@ -503,6 +606,8 @@ pattern[pattern_ty]:
  344. | or_pattern
  345.  
  346. as_pattern[pattern_ty]:
  347. + | pattern=or_pattern '若' target=pattern_capture_target {
  348. + _PyAST_MatchAs(pattern, target->v.Name.id, EXTRA) }
  349. | pattern=or_pattern 'as' target=pattern_capture_target {
  350. _PyAST_MatchAs(pattern, target->v.Name.id, EXTRA) }
  351. | invalid_as_pattern
  352. @@ -526,8 +631,11 @@ literal_pattern[pattern_ty]:
  353. | value=signed_number !('+' | '-') { _PyAST_MatchValue(value, EXTRA) }
  354. | value=complex_number { _PyAST_MatchValue(value, EXTRA) }
  355. | value=strings { _PyAST_MatchValue(value, EXTRA) }
  356. + | '無' { _PyAST_MatchSingleton(Py_None, EXTRA) }
  357. | 'None' { _PyAST_MatchSingleton(Py_None, EXTRA) }
  358. + | '真' { _PyAST_MatchSingleton(Py_True, EXTRA) }
  359. | 'True' { _PyAST_MatchSingleton(Py_True, EXTRA) }
  360. + | '假' { _PyAST_MatchSingleton(Py_False, EXTRA) }
  361. | 'False' { _PyAST_MatchSingleton(Py_False, EXTRA) }
  362.  
  363. # Literal expressions are used to restrict permitted mapping pattern keys
  364. @@ -535,8 +643,11 @@ literal_expr[expr_ty]:
  365. | signed_number !('+' | '-')
  366. | complex_number
  367. | &(STRING|FSTRING_START|TSTRING_START) strings
  368. + | '無' { _PyAST_Constant(Py_None, NULL, EXTRA) }
  369. | 'None' { _PyAST_Constant(Py_None, NULL, EXTRA) }
  370. + | '真' { _PyAST_Constant(Py_True, NULL, EXTRA) }
  371. | 'True' { _PyAST_Constant(Py_True, NULL, EXTRA) }
  372. + | '假' { _PyAST_Constant(Py_False, NULL, EXTRA) }
  373. | 'False' { _PyAST_Constant(Py_False, NULL, EXTRA) }
  374.  
  375. complex_number[expr_ty]:
  376. @@ -705,11 +816,14 @@ expressions[expr_ty]:
  377. expression[expr_ty] (memo):
  378. | invalid_expression
  379. | invalid_legacy_expression
  380. + | a=disjunction '如' b=disjunction '另' c=expression { _PyAST_IfExp(b, a, c, EXTRA) }
  381. | a=disjunction 'if' b=disjunction 'else' c=expression { _PyAST_IfExp(b, a, c, EXTRA) }
  382. | disjunction
  383. | lambdef
  384.  
  385. yield_expr[expr_ty]:
  386. + | '讓從' a=expression { _PyAST_YieldFrom(a, EXTRA) }
  387. + | '讓' '從' a=expression { _PyAST_YieldFrom(a, EXTRA) }
  388. | 'yield' 'from' a=expression { _PyAST_YieldFrom(a, EXTRA) }
  389. | 'yield' a=[star_expressions] { _PyAST_Yield(a, EXTRA) }
  390.  
  391. @@ -754,6 +868,7 @@ conjunction[expr_ty] (memo):
  392. | inversion
  393.  
  394. inversion[expr_ty] (memo):
  395. + | '非' a=inversion { _PyAST_UnaryOp(Not, a, EXTRA) }
  396. | 'not' a=inversion { _PyAST_UnaryOp(Not, a, EXTRA) }
  397. | comparison
  398.  
  399. @@ -788,10 +903,10 @@ lte_bitwise_or[CmpopExprPair*]: '<=' a=bitwise_or { _PyPegen_cmpop_expr_pair(p,
  400. lt_bitwise_or[CmpopExprPair*]: '<' a=bitwise_or { _PyPegen_cmpop_expr_pair(p, Lt, a) }
  401. gte_bitwise_or[CmpopExprPair*]: '>=' a=bitwise_or { _PyPegen_cmpop_expr_pair(p, GtE, a) }
  402. gt_bitwise_or[CmpopExprPair*]: '>' a=bitwise_or { _PyPegen_cmpop_expr_pair(p, Gt, a) }
  403. -notin_bitwise_or[CmpopExprPair*]: 'not' 'in' a=bitwise_or { _PyPegen_cmpop_expr_pair(p, NotIn, a) }
  404. -in_bitwise_or[CmpopExprPair*]: 'in' a=bitwise_or { _PyPegen_cmpop_expr_pair(p, In, a) }
  405. -isnot_bitwise_or[CmpopExprPair*]: 'is' 'not' a=bitwise_or { _PyPegen_cmpop_expr_pair(p, IsNot, a) }
  406. -is_bitwise_or[CmpopExprPair*]: 'is' a=bitwise_or { _PyPegen_cmpop_expr_pair(p, Is, a) }
  407. +notin_bitwise_or[CmpopExprPair*]: ('非在'|'非' '在'|'not' 'in') a=bitwise_or { _PyPegen_cmpop_expr_pair(p, NotIn, a) }
  408. +in_bitwise_or[CmpopExprPair*]: ('在'|'in') a=bitwise_or { _PyPegen_cmpop_expr_pair(p, In, a) }
  409. +isnot_bitwise_or[CmpopExprPair*]: ('是非'|'是' '非'|'is' 'not') a=bitwise_or { _PyPegen_cmpop_expr_pair(p, IsNot, a) }
  410. +is_bitwise_or[CmpopExprPair*]: ('是'|'is') a=bitwise_or { _PyPegen_cmpop_expr_pair(p, Is, a) }
  411.  
  412. # Bitwise operators
  413. # -----------------
  414. @@ -847,6 +962,7 @@ power[expr_ty]:
  415. # Primary elements are things like "obj.something.something", "obj[something]", "obj(something)", "obj" ...
  416.  
  417. await_primary[expr_ty] (memo):
  418. + | '待' a=primary { CHECK_VERSION(expr_ty, 5, "Await expressions are", _PyAST_Await(a, EXTRA)) }
  419. | 'await' a=primary { CHECK_VERSION(expr_ty, 5, "Await expressions are", _PyAST_Await(a, EXTRA)) }
  420. | primary
  421.  
  422. @@ -871,8 +987,11 @@ slice[expr_ty]:
  423.  
  424. atom[expr_ty]:
  425. | NAME
  426. + | '真' { _PyAST_Constant(Py_True, NULL, EXTRA) }
  427. | 'True' { _PyAST_Constant(Py_True, NULL, EXTRA) }
  428. + | '假' { _PyAST_Constant(Py_False, NULL, EXTRA) }
  429. | 'False' { _PyAST_Constant(Py_False, NULL, EXTRA) }
  430. + | '無' { _PyAST_Constant(Py_None, NULL, EXTRA) }
  431. | 'None' { _PyAST_Constant(Py_None, NULL, EXTRA) }
  432. | &(STRING|FSTRING_START|TSTRING_START) strings
  433. | NUMBER
  434. @@ -889,6 +1008,8 @@ group[expr_ty]:
  435. # ----------------
  436.  
  437. lambdef[expr_ty]:
  438. + | '匿' a=[lambda_params] ':' b=expression {
  439. + _PyAST_Lambda((a) ? a : CHECK(arguments_ty, _PyPegen_empty_arguments(p)), b, EXTRA) }
  440. | 'lambda' a=[lambda_params] ':' b=expression {
  441. _PyAST_Lambda((a) ? a : CHECK(arguments_ty, _PyPegen_empty_arguments(p)), b, EXTRA) }
  442.  
  443. @@ -1023,8 +1144,14 @@ for_if_clauses[asdl_comprehension_seq*]:
  444. | a[asdl_comprehension_seq*]=for_if_clause+ { a }
  445.  
  446. for_if_clause[comprehension_ty]:
  447. + | '離為' a=star_targets '在' ~ b=disjunction c[asdl_expr_seq*]=('如' z=disjunction { z })* {
  448. + CHECK_VERSION(comprehension_ty, 6, "Async comprehensions are", _PyAST_comprehension(a, b, c, 1, p->arena)) }
  449. + | '離' '為' a=star_targets '在' ~ b=disjunction c[asdl_expr_seq*]=('如' z=disjunction { z })* {
  450. + CHECK_VERSION(comprehension_ty, 6, "Async comprehensions are", _PyAST_comprehension(a, b, c, 1, p->arena)) }
  451. | 'async' 'for' a=star_targets 'in' ~ b=disjunction c[asdl_expr_seq*]=('if' z=disjunction { z })* {
  452. CHECK_VERSION(comprehension_ty, 6, "Async comprehensions are", _PyAST_comprehension(a, b, c, 1, p->arena)) }
  453. + | '為' a=star_targets '在' ~ b=disjunction c[asdl_expr_seq*]=('如' z=disjunction { z })* {
  454. + _PyAST_comprehension(a, b, c, 0, p->arena) }
  455. | 'for' a=star_targets 'in' ~ b=disjunction c[asdl_expr_seq*]=('if' z=disjunction { z })* {
  456. _PyAST_comprehension(a, b, c, 0, p->arena) }
  457. | invalid_for_if_clause
  458. @@ -1203,7 +1330,7 @@ invalid_arguments:
  459. RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, _PyPegen_get_last_comprehension_item(PyPegen_last_item(b, comprehension_ty)), "Generator expression must be parenthesized") }
  460. | a=args ',' args { _PyPegen_arguments_parsing_error(p, a) }
  461. invalid_kwarg:
  462. - | a[Token*]=('True'|'False'|'None') b='=' {
  463. + | a[Token*]=('True'|'False'|'None'|'真'|'假'|'無') b='=' {
  464. RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "cannot assign to %s", PyBytes_AS_STRING(a->bytes)) }
  465. | a=NAME b='=' expression for_if_clauses {
  466. RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "invalid syntax. Maybe you meant '==' or ':=' instead of '='?")}
  467. @@ -1215,6 +1342,7 @@ invalid_kwarg:
  468.  
  469. # IMPORTANT: Note that the "_without_invalid" suffix causes the rule to not call invalid rules under it
  470. expression_without_invalid[expr_ty]:
  471. + | a=disjunction '如' b=disjunction '另' c=expression { _PyAST_IfExp(b, a, c, EXTRA) }
  472. | a=disjunction 'if' b=disjunction 'else' c=expression { _PyAST_IfExp(b, a, c, EXTRA) }
  473. | disjunction
  474. | lambdef
  475. @@ -1244,13 +1372,22 @@ invalid_expression:
  476. | !(NAME STRING | SOFT_KEYWORD) a=disjunction b=expression_without_invalid {
  477. _PyPegen_check_legacy_stmt(p, a) ? NULL : p->tokens[p->mark-1]->level == 0 ? NULL :
  478. RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "invalid syntax. Perhaps you forgot a comma?") }
  479. + | a=disjunction '如' b=disjunction !('另'|':') { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "expected '另' after '如' expression") }
  480. | a=disjunction 'if' b=disjunction !('else'|':') { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "expected 'else' after 'if' expression") }
  481. + | a=disjunction '如' b=disjunction '另' !expression {
  482. + RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("expected expression after '另', but statement is given") }
  483. | a=disjunction 'if' b=disjunction 'else' !expression {
  484. RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("expected expression after 'else', but statement is given") }
  485. + | a[stmt_ty]=(pass_stmt|break_stmt|continue_stmt) '如' b=disjunction '另' c=simple_stmt {
  486. + RAISE_SYNTAX_ERROR_KNOWN_LOCATION (a, "expected expression before '如', but statement is given") }
  487. | a[stmt_ty]=(pass_stmt|break_stmt|continue_stmt) 'if' b=disjunction 'else' c=simple_stmt {
  488. RAISE_SYNTAX_ERROR_KNOWN_LOCATION (a, "expected expression before 'if', but statement is given") }
  489. + | a='匿' [lambda_params] b=':' &FSTRING_MIDDLE {
  490. + RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "f-string: lambda expressions are not allowed without parentheses") }
  491. | a='lambda' [lambda_params] b=':' &FSTRING_MIDDLE {
  492. RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "f-string: lambda expressions are not allowed without parentheses") }
  493. + | a='匿' [lambda_params] b=':' &TSTRING_MIDDLE {
  494. + RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "t-string: lambda expressions are not allowed without parentheses") }
  495. | a='lambda' [lambda_params] b=':' &TSTRING_MIDDLE {
  496. RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "t-string: lambda expressions are not allowed without parentheses") }
  497.  
  498. @@ -1260,7 +1397,7 @@ invalid_named_expression(memo):
  499. a, "cannot use assignment expressions with %s", _PyPegen_get_expr_name(a)) }
  500. | a=NAME '=' b=bitwise_or !('='|':=') {
  501. RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "invalid syntax. Maybe you meant '==' or ':=' instead of '='?") }
  502. - | !(list|tuple|genexp|'True'|'None'|'False') a=bitwise_or b='=' bitwise_or !('='|':=') {
  503. + | !(list|tuple|genexp|'True'|'None'|'False'|'真'|'假'|'無') a=bitwise_or b='=' bitwise_or !('='|':=') {
  504. RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot assign to %s here. Maybe you meant '==' instead of '='?",
  505. _PyPegen_get_expr_name(a)) }
  506.  
  507. @@ -1294,6 +1431,8 @@ invalid_raise_stmt:
  508. | 'raise' expression a='from' {
  509. RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "did you forget an expression after 'from'?") }
  510. invalid_del_stmt:
  511. + | '刪' a=star_expressions {
  512. + RAISE_SYNTAX_ERROR_INVALID_TARGET(DEL_TARGETS, a) }
  513. | 'del' a=star_expressions {
  514. RAISE_SYNTAX_ERROR_INVALID_TARGET(DEL_TARGETS, a) }
  515. invalid_block:
  516. @@ -1366,14 +1505,20 @@ invalid_double_type_comments:
  517. | TYPE_COMMENT NEWLINE TYPE_COMMENT NEWLINE INDENT {
  518. RAISE_SYNTAX_ERROR("Cannot have two type comments on def") }
  519. invalid_with_item:
  520. + | expression '若' a=expression &(',' | ')' | ':') {
  521. + RAISE_SYNTAX_ERROR_INVALID_TARGET(STAR_TARGETS, a) }
  522. | expression 'as' a=expression &(',' | ')' | ':') {
  523. RAISE_SYNTAX_ERROR_INVALID_TARGET(STAR_TARGETS, a) }
  524.  
  525. invalid_for_if_clause:
  526. + | '離'? '為' (bitwise_or (',' bitwise_or)* [',']) !'in' {
  527. + RAISE_SYNTAX_ERROR("'in' expected after for-loop variables") }
  528. | 'async'? 'for' (bitwise_or (',' bitwise_or)* [',']) !'in' {
  529. RAISE_SYNTAX_ERROR("'in' expected after for-loop variables") }
  530.  
  531. invalid_for_target:
  532. + | '離'? '為' a=star_expressions {
  533. + RAISE_SYNTAX_ERROR_INVALID_TARGET(FOR_TARGETS, a) }
  534. | 'async'? 'for' a=star_expressions {
  535. RAISE_SYNTAX_ERROR_INVALID_TARGET(FOR_TARGETS, a) }
  536.  
  537. @@ -1383,15 +1528,25 @@ invalid_group:
  538. | '(' a='**' expression ')' {
  539. RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot use double starred expression here") }
  540. invalid_import:
  541. + | a='載' ','.dotted_name+ '從' dotted_name {
  542. + RAISE_SYNTAX_ERROR_STARTING_FROM(a, "Did you mean to use '從 ... 載...' instead?") }
  543. | a='import' ','.dotted_name+ 'from' dotted_name {
  544. RAISE_SYNTAX_ERROR_STARTING_FROM(a, "Did you mean to use 'from ... import ...' instead?") }
  545. + | '載' token=NEWLINE {
  546. + RAISE_SYNTAX_ERROR_STARTING_FROM(token, "Expected one or more names after '載'") }
  547. | 'import' token=NEWLINE {
  548. RAISE_SYNTAX_ERROR_STARTING_FROM(token, "Expected one or more names after 'import'") }
  549. invalid_dotted_as_name:
  550. + | dotted_name '若' !(NAME (',' | ')' | NEWLINE)) a=expression {
  551. + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a,
  552. + "cannot use %s as import target", _PyPegen_get_expr_name(a)) }
  553. | dotted_name 'as' !(NAME (',' | ')' | NEWLINE)) a=expression {
  554. RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a,
  555. "cannot use %s as import target", _PyPegen_get_expr_name(a)) }
  556. invalid_import_from_as_name:
  557. + | NAME '若' !(NAME (',' | ')' | NEWLINE)) a=expression {
  558. + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a,
  559. + "cannot use %s as import target", _PyPegen_get_expr_name(a)) }
  560. | NAME 'as' !(NAME (',' | ')' | NEWLINE)) a=expression {
  561. RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a,
  562. "cannot use %s as import target", _PyPegen_get_expr_name(a)) }
  563. @@ -1403,46 +1558,80 @@ invalid_import_from_targets:
  564. RAISE_SYNTAX_ERROR_STARTING_FROM(token, "Expected one or more names after 'import'") }
  565.  
  566. invalid_with_stmt:
  567. + | ['離'] '用' ','.(expression ['若' star_target])+ NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
  568. | ['async'] 'with' ','.(expression ['as' star_target])+ NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
  569. + | ['離'] '用' '(' ','.(expressions ['若' star_target])+ ','? ')' NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
  570. | ['async'] 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
  571. invalid_with_stmt_indent:
  572. + | ['離'] a='用' ','.(expression ['若' star_target])+ ':' NEWLINE !INDENT {
  573. + RAISE_INDENTATION_ERROR("expected an indented block after 'with' statement on line %d", a->lineno) }
  574. | ['async'] a='with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT {
  575. RAISE_INDENTATION_ERROR("expected an indented block after 'with' statement on line %d", a->lineno) }
  576. + | ['離'] a='用' '(' ','.(expressions ['若' star_target])+ ','? ')' ':' NEWLINE !INDENT {
  577. + RAISE_INDENTATION_ERROR("expected an indented block after 'with' statement on line %d", a->lineno) }
  578. | ['async'] a='with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT {
  579. RAISE_INDENTATION_ERROR("expected an indented block after 'with' statement on line %d", a->lineno) }
  580.  
  581. invalid_try_stmt:
  582. + | a='試' ':' NEWLINE !INDENT {
  583. + RAISE_INDENTATION_ERROR("expected an indented block after '試' statement on line %d", a->lineno) }
  584. | a='try' ':' NEWLINE !INDENT {
  585. RAISE_INDENTATION_ERROR("expected an indented block after 'try' statement on line %d", a->lineno) }
  586. + | '試' ':' block !('除' | '終') { RAISE_SYNTAX_ERROR("expected '除' or '終' block") }
  587. | 'try' ':' block !('except' | 'finally') { RAISE_SYNTAX_ERROR("expected 'except' or 'finally' block") }
  588. + | '試' ':' block* except_block+ a='除' b='*' expression ['若' NAME] ':' {
  589. + RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "cannot have both '除' and '除*' on the same '試'") }
  590. | 'try' ':' block* except_block+ a='except' b='*' expression ['as' NAME] ':' {
  591. RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "cannot have both 'except' and 'except*' on the same 'try'") }
  592. + | '試' ':' block* except_star_block+ a='except' [expression ['as' NAME]] ':' {
  593. + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot have both '除' and '除*' on the same '試'") }
  594. | 'try' ':' block* except_star_block+ a='except' [expression ['as' NAME]] ':' {
  595. RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot have both 'except' and 'except*' on the same 'try'") }
  596. invalid_except_stmt:
  597. + | '除' a=expression ',' expressions '若' NAME ':' {
  598. + RAISE_SYNTAX_ERROR_STARTING_FROM(a, "multiple exception types must be parenthesized when using 'as'") }
  599. | 'except' a=expression ',' expressions 'as' NAME ':' {
  600. RAISE_SYNTAX_ERROR_STARTING_FROM(a, "multiple exception types must be parenthesized when using 'as'") }
  601. + | a='除' expression ['若' NAME ] NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
  602. | a='except' expression ['as' NAME ] NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
  603. + | a='除' NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
  604. | a='except' NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
  605. + | '除' expression '若' a=expression ':' block {
  606. + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
  607. + a, "cannot use except statement with %s", _PyPegen_get_expr_name(a)) }
  608. | 'except' expression 'as' a=expression ':' block {
  609. RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
  610. a, "cannot use except statement with %s", _PyPegen_get_expr_name(a)) }
  611. invalid_except_star_stmt:
  612. + | '除' '*' a=expression ',' expressions '若' NAME ':' {
  613. + RAISE_SYNTAX_ERROR_STARTING_FROM(a, "multiple exception types must be parenthesized when using 'as'") }
  614. | 'except' '*' a=expression ',' expressions 'as' NAME ':' {
  615. RAISE_SYNTAX_ERROR_STARTING_FROM(a, "multiple exception types must be parenthesized when using 'as'") }
  616. + | a='除' '*' expression ['若' NAME ] NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
  617. | a='except' '*' expression ['as' NAME ] NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
  618. + | a='除' '*' (NEWLINE | ':') { RAISE_SYNTAX_ERROR("expected one or more exception types") }
  619. | a='except' '*' (NEWLINE | ':') { RAISE_SYNTAX_ERROR("expected one or more exception types") }
  620. + | '除' '*' expression '若' a=expression ':' block {
  621. + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
  622. + a, "cannot use except* statement with %s", _PyPegen_get_expr_name(a)) }
  623. | 'except' '*' expression 'as' a=expression ':' block {
  624. RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
  625. a, "cannot use except* statement with %s", _PyPegen_get_expr_name(a)) }
  626. invalid_finally_stmt:
  627. + | a='終' ':' NEWLINE !INDENT {
  628. + RAISE_INDENTATION_ERROR("expected an indented block after '終' statement on line %d", a->lineno) }
  629. | a='finally' ':' NEWLINE !INDENT {
  630. RAISE_INDENTATION_ERROR("expected an indented block after 'finally' statement on line %d", a->lineno) }
  631. invalid_except_stmt_indent:
  632. + | a='除' expression ['若' NAME ] ':' NEWLINE !INDENT {
  633. + RAISE_INDENTATION_ERROR("expected an indented block after '除' statement on line %d", a->lineno) }
  634. | a='except' expression ['as' NAME ] ':' NEWLINE !INDENT {
  635. RAISE_INDENTATION_ERROR("expected an indented block after 'except' statement on line %d", a->lineno) }
  636. + | a='除' ':' NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block after '除' statement on line %d", a->lineno) }
  637. | a='except' ':' NEWLINE !INDENT { RAISE_INDENTATION_ERROR("expected an indented block after 'except' statement on line %d", a->lineno) }
  638. invalid_except_star_stmt_indent:
  639. + | a='除' '*' expression ['若' NAME ] ':' NEWLINE !INDENT {
  640. + RAISE_INDENTATION_ERROR("expected an indented block after '除*' statement on line %d", a->lineno) }
  641. | a='except' '*' expression ['as' NAME ] ':' NEWLINE !INDENT {
  642. RAISE_INDENTATION_ERROR("expected an indented block after 'except*' statement on line %d", a->lineno) }
  643. invalid_match_stmt:
  644. @@ -1454,7 +1643,11 @@ invalid_case_block:
  645. | a="case" patterns guard? ':' NEWLINE !INDENT {
  646. RAISE_INDENTATION_ERROR("expected an indented block after 'case' statement on line %d", a->lineno) }
  647. invalid_as_pattern:
  648. + | or_pattern '若' a="_" { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot use '_' as a target") }
  649. | or_pattern 'as' a="_" { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot use '_' as a target") }
  650. + | or_pattern '若' a=expression {
  651. + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
  652. + a, "cannot use %s as pattern target", _PyPegen_get_expr_name(a)) }
  653. | or_pattern 'as' a=expression {
  654. RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
  655. a, "cannot use %s as pattern target", _PyPegen_get_expr_name(a)) }
  656. @@ -1466,31 +1659,52 @@ invalid_class_pattern:
  657. invalid_class_argument_pattern[asdl_pattern_seq*]:
  658. | [positional_patterns ','] keyword_patterns ',' a=positional_patterns { a }
  659. invalid_if_stmt:
  660. + | '如' named_expression NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
  661. | 'if' named_expression NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
  662. + | a='如' a=named_expression ':' NEWLINE !INDENT {
  663. + RAISE_INDENTATION_ERROR("expected an indented block after '如' statement on line %d", a->lineno) }
  664. | a='if' a=named_expression ':' NEWLINE !INDENT {
  665. RAISE_INDENTATION_ERROR("expected an indented block after 'if' statement on line %d", a->lineno) }
  666. invalid_elif_stmt:
  667. + | '然' named_expression NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
  668. | 'elif' named_expression NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
  669. + | a='然' named_expression ':' NEWLINE !INDENT {
  670. + RAISE_INDENTATION_ERROR("expected an indented block after '然' statement on line %d", a->lineno) }
  671. | a='elif' named_expression ':' NEWLINE !INDENT {
  672. RAISE_INDENTATION_ERROR("expected an indented block after 'elif' statement on line %d", a->lineno) }
  673. invalid_else_stmt:
  674. + | a='另' ':' NEWLINE !INDENT {
  675. + RAISE_INDENTATION_ERROR("expected an indented block after '另' statement on line %d", a->lineno) }
  676. | a='else' ':' NEWLINE !INDENT {
  677. RAISE_INDENTATION_ERROR("expected an indented block after 'else' statement on line %d", a->lineno) }
  678. + | '另' ':' block '然' { RAISE_SYNTAX_ERROR("'然' block follows an '另' block")}
  679. | 'else' ':' block 'elif' { RAISE_SYNTAX_ERROR("'elif' block follows an 'else' block")}
  680. invalid_while_stmt:
  681. + | '當' named_expression NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
  682. | 'while' named_expression NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
  683. + | a='當' named_expression ':' NEWLINE !INDENT {
  684. + RAISE_INDENTATION_ERROR("expected an indented block after '當' statement on line %d", a->lineno ) }
  685. | a='while' named_expression ':' NEWLINE !INDENT {
  686. RAISE_INDENTATION_ERROR("expected an indented block after 'while' statement on line %d", a->lineno) }
  687. invalid_for_stmt:
  688. + | ['離'] '為' star_targets '在' star_expressions NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
  689. | ['async'] 'for' star_targets 'in' star_expressions NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
  690. + | ['離'] a='為' star_targets '在' star_expressions ':' NEWLINE !INDENT {
  691. + RAISE_INDENTATION_ERROR("expected an indented block after '為' statement on line %d", a->lineno) }
  692. | ['async'] a='for' star_targets 'in' star_expressions ':' NEWLINE !INDENT {
  693. RAISE_INDENTATION_ERROR("expected an indented block after 'for' statement on line %d", a->lineno) }
  694. invalid_def_raw:
  695. + | ['離'] a='函' NAME [type_params] '(' [params] ')' ['->' expression] ':' NEWLINE !INDENT {
  696. + RAISE_INDENTATION_ERROR("expected an indented block after function definition on line %d", a->lineno) }
  697. | ['async'] a='def' NAME [type_params] '(' [params] ')' ['->' expression] ':' NEWLINE !INDENT {
  698. RAISE_INDENTATION_ERROR("expected an indented block after function definition on line %d", a->lineno) }
  699. + | ['離'] '函' NAME [type_params] &&'(' [params] ')' ['->' expression] &&':' [func_type_comment] block
  700. | ['async'] 'def' NAME [type_params] &&'(' [params] ')' ['->' expression] &&':' [func_type_comment] block
  701. invalid_class_def_raw:
  702. + | '類' NAME [type_params] ['(' [arguments] ')'] NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
  703. | 'class' NAME [type_params] ['(' [arguments] ')'] NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
  704. + | a='類' NAME [type_params] ['(' [arguments] ')'] ':' NEWLINE !INDENT {
  705. + RAISE_INDENTATION_ERROR("expected an indented block after class definition on line %d", a->lineno) }
  706. | a='class' NAME [type_params] ['(' [arguments] ')'] ':' NEWLINE !INDENT {
  707. RAISE_INDENTATION_ERROR("expected an indented block after class definition on line %d", a->lineno) }
  708. diff --git a/Lib/unittest/loader.py b/Lib/unittest/loader.py
  709. index a52950dad22..3d3ee7608bd 100644
  710. --- a/Lib/unittest/loader.py
  711. +++ b/Lib/unittest/loader.py
  712. @@ -65,7 +65,7 @@ class TestLoader(object):
  713. This class is responsible for loading tests according to various criteria
  714. and returning them wrapped in a TestSuite
  715. """
  716. - testMethodPrefix = 'test'
  717. + testMethodPrefix = ['test', '測']
  718. sortTestMethodsUsing = staticmethod(util.three_way_cmp)
  719. testNamePatterns = None
  720. suiteClass = suite.TestSuite
  721. @@ -211,7 +211,7 @@ def getTestCaseNames(self, testCaseClass):
  722. """Return a sorted sequence of method names found within testCaseClass
  723. """
  724. def shouldIncludeMethod(attrname):
  725. - if not attrname.startswith(self.testMethodPrefix):
  726. + if not any([attrname.startswith(prefix) for prefix in self.testMethodPrefix]):
  727. return False
  728. testFunc = getattr(testCaseClass, attrname)
  729. if not callable(testFunc):
  730. 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"
  731. new file mode 100644
  732. index 00000000000..551222b63d4
  733. --- /dev/null
  734. +++ "b/Lib/\346\270\254\345\226\256\345\205\203/__init__.py"
  735. @@ -0,0 +1,3 @@
  736. +import unittest
  737. +
  738. +from unittest.case import TestCase as 測例子
  739. diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
  740. index e08c63924ca..c2ba2fc1cc6 100644
  741. --- a/Python/bltinmodule.c
  742. +++ b/Python/bltinmodule.c
  743. @@ -3384,6 +3384,7 @@ _PyBuiltin_Init(PyInterpreterState *interp)
  744. SETBUILTIN("classmethod", &PyClassMethod_Type);
  745. SETBUILTIN("complex", &PyComplex_Type);
  746. SETBUILTIN("dict", &PyDict_Type);
  747. + SETBUILTIN("字典", &PyDict_Type);
  748. SETBUILTIN("enumerate", &PyEnum_Type);
  749. SETBUILTIN("filter", &PyFilter_Type);
  750. SETBUILTIN("float", &PyFloat_Type);
  751. @@ -3394,6 +3395,7 @@ _PyBuiltin_Init(PyInterpreterState *interp)
  752. SETBUILTIN("map", &PyMap_Type);
  753. SETBUILTIN("object", &PyBaseObject_Type);
  754. SETBUILTIN("range", &PyRange_Type);
  755. + SETBUILTIN("區間", &PyRange_Type);
  756. SETBUILTIN("reversed", &PyReversed_Type);
  757. SETBUILTIN("set", &PySet_Type);
  758. SETBUILTIN("slice", &PySlice_Type);
  759. diff --git a/Python/clinic/bltinmodule.c.h b/Python/clinic/bltinmodule.c.h
  760. index c826a5724f7..c77102bb3ae 100644
  761. --- a/Python/clinic/bltinmodule.c.h
  762. +++ b/Python/clinic/bltinmodule.c.h
  763. @@ -926,7 +926,8 @@ PyDoc_STRVAR(builtin_print__doc__,
  764. " whether to forcibly flush the stream.");
  765.  
  766. #define BUILTIN_PRINT_METHODDEF \
  767. - {"print", _PyCFunction_CAST(builtin_print), METH_FASTCALL|METH_KEYWORDS, builtin_print__doc__},
  768. + {"print", _PyCFunction_CAST(builtin_print), METH_FASTCALL|METH_KEYWORDS, builtin_print__doc__}, \
  769. + {"印", _PyCFunction_CAST(builtin_print), METH_FASTCALL|METH_KEYWORDS, builtin_print__doc__},
  770.  
  771. static PyObject *
  772. builtin_print_impl(PyObject *module, PyObject * const *args,
  773. diff --git a/Tools/peg_generator/pegen/c_generator.py b/Tools/peg_generator/pegen/c_generator.py
  774. index 09c5651f24a..63c6ce78f06 100644
  775. --- a/Tools/peg_generator/pegen/c_generator.py
  776. +++ b/Tools/peg_generator/pegen/c_generator.py
  777. @@ -26,6 +26,7 @@
  778. Rule,
  779. StringLeaf,
  780. )
  781. +from pegen.parser_generator import ckeywords
  782. from pegen.parser_generator import ParserGenerator
  783.  
  784. EXTENSION_PREFIX = """\
  785. @@ -189,7 +190,7 @@ def visit_NameLeaf(self, node: NameLeaf) -> FunctionCall:
  786.  
  787. def visit_StringLeaf(self, node: StringLeaf) -> FunctionCall:
  788. val = ast.literal_eval(node.value)
  789. - if re.match(r"[a-zA-Z_]\w*\Z", val): # This is a keyword
  790. + if re.match(r"[a-zA-Z_]\w*\Z", val) or val in ckeywords: # This is a keyword
  791. if node.value.endswith("'"):
  792. return self.keyword_helper(val)
  793. else:
  794. @@ -480,7 +481,7 @@ def generate(self, filename: str) -> None:
  795. def _group_keywords_by_length(self) -> Dict[int, List[Tuple[str, int]]]:
  796. groups: Dict[int, List[Tuple[str, int]]] = {}
  797. for keyword_str, keyword_type in self.keywords.items():
  798. - length = len(keyword_str)
  799. + length = len(keyword_str.encode('utf-8'))
  800. if length in groups:
  801. groups[length].append((keyword_str, keyword_type))
  802. else:
  803. diff --git a/Tools/peg_generator/pegen/parser_generator.py b/Tools/peg_generator/pegen/parser_generator.py
  804. index 52ae743c26b..b459013dd33 100644
  805. --- a/Tools/peg_generator/pegen/parser_generator.py
  806. +++ b/Tools/peg_generator/pegen/parser_generator.py
  807. @@ -40,6 +40,7 @@
  808. StringLeaf,
  809. )
  810.  
  811. +ckeywords = {'過', '回', '示', '過', '讓', '從', '刪', '宣', '斷', '續', '寰', '異', '函', '離', '如', '類', '用', '為', '試', '當', '若', '類', '函', '然', '另', '除', '終', '在', '無', '真', '假', '非', '待', '匿', '是', '載', '離函', '離為', '離用', '非在', '讓從', '是非'}
  812.  
  813. class RuleCollectorVisitor(GrammarVisitor):
  814. """Visitor that invokes a provided callmaker visitor with just the NamedItem nodes"""
  815. @@ -65,7 +66,7 @@ def __init__(self, gen: "ParserGenerator", keywords: Dict[str, int], soft_keywor
  816.  
  817. def visit_StringLeaf(self, node: StringLeaf) -> None:
  818. val = ast.literal_eval(node.value)
  819. - if re.match(r"[a-zA-Z_]\w*\Z", val): # This is a keyword
  820. + if re.match(r"[a-zA-Z_]\w*\Z", val) or val in ckeywords: # This is a keyword
  821. if node.value.endswith("'") and node.value not in self.keywords:
  822. self.keywords[val] = self.generator.keyword_type()
  823. else:
  824.  
Advertisement
Add Comment
Please, Sign In to add comment