full_custom.py 58 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318
  1. # Copyright (c) 2021-2023 Rocky Bernstein
  2. #
  3. # This program is free software: you can redistribute it and/or modify
  4. # it under the terms of the GNU General Public License as published by
  5. # the Free Software Foundation, either version 3 of the License, or
  6. # (at your option) any later version.
  7. #
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. # from decompyle3.parsers.reduce_check.import_from37 import import_from37_ok
  16. from decompyle3.parsers.p37.base import Python37BaseParser
  17. from decompyle3.parsers.p38.lambda_custom import Python38LambdaCustom
  18. from decompyle3.parsers.parse_heads import PythonBaseParser, nop_func
  19. from decompyle3.parsers.reduce_check import ( # joined_str_check,
  20. break_invalid,
  21. for38_invalid,
  22. forelse38_invalid,
  23. if_not_stmtc_invalid,
  24. pop_return_check,
  25. whilestmt38_check,
  26. whileTruestmt38_check,
  27. )
  28. # from decompyle3.parsers.reduce_check.ifelsestmt_check import ifelsestmt_ok
  29. from decompyle3.parsers.reduce_check.ifstmt import ifstmt
  30. from decompyle3.parsers.reduce_check.or_cond_check import or_cond_check_invalid
  31. class Python38FullCustom(Python38LambdaCustom, PythonBaseParser):
  32. def add_make_function_rule(self, rule, opname, attr, customize):
  33. """Python 3.3 added an additional LOAD_STR before MAKE_FUNCTION and
  34. this has an effect on many rules.
  35. """
  36. new_rule = rule % "LOAD_STR "
  37. self.add_unique_rule(new_rule, opname, attr, customize)
  38. @staticmethod
  39. def call_fn_name(token):
  40. """Customize CALL_FUNCTION to add the number of positional arguments"""
  41. if token.attr is not None:
  42. return f"{token.kind}_{token.attr}"
  43. else:
  44. return f"{token.kind}_0"
  45. def remove_rules_38(self):
  46. self.remove_rules(
  47. """
  48. stmt ::= async_for_stmt37
  49. stmt ::= for
  50. stmt ::= forelsestmt
  51. stmt ::= try_except36
  52. stmt ::= async_forelse_stmt
  53. # There is no SETUP_LOOP
  54. setup_loop ::= SETUP_LOOP _come_froms
  55. forelselaststmt ::= SETUP_LOOP expr get_for_iter store
  56. for_block POP_BLOCK else_suitec _come_froms
  57. forelsestmt ::= SETUP_LOOP expr get_for_iter store
  58. whileTruestmt ::= SETUP_LOOP c_stmts_opt JUMP_LOOP COME_FROM_LOOP
  59. for_block POP_BLOCK else_suite _come_froms
  60. # async_for_stmt ::= setup_loop expr
  61. # GET_AITER
  62. # SETUP_EXCEPT GET_ANEXT LOAD_CONST
  63. # YIELD_FROM
  64. # store
  65. # POP_BLOCK JUMP_FORWARD bb_end_start DUP_TOP
  66. # LOAD_GLOBAL COMPARE_OP POP_JUMP_IF_TRUE
  67. # END_FINALLY bb_end_start
  68. # for_block
  69. # COME_FROM
  70. # POP_TOP POP_TOP POP_TOP POP_EXCEPT POP_TOP POP_BLOCK
  71. # COME_FROM_LOOP
  72. # async_for_stmt37 ::= setup_loop expr
  73. # GET_AITER
  74. # SETUP_EXCEPT GET_ANEXT
  75. # LOAD_CONST YIELD_FROM
  76. # store
  77. # POP_BLOCK JUMP_LOOP COME_FROM_EXCEPT DUP_TOP
  78. # LOAD_GLOBAL COMPARE_OP POP_JUMP_IF_TRUE
  79. # END_FINALLY for_block COME_FROM
  80. # POP_TOP POP_TOP POP_TOP POP_EXCEPT
  81. # POP_TOP POP_BLOCK
  82. # COME_FROM_LOOP
  83. # async_forelse_stmt ::= setup_loop expr
  84. # GET_AITER
  85. # SETUP_EXCEPT GET_ANEXT LOAD_CONST
  86. # YIELD_FROM
  87. # store
  88. # POP_BLOCK JUMP_FORWARD COME_FROM_EXCEPT DUP_TOP
  89. # LOAD_GLOBAL COMPARE_OP POP_JUMP_IF_TRUE
  90. # END_FINALLY COME_FROM
  91. # for_block
  92. # COME_FROM
  93. # POP_TOP POP_TOP POP_TOP POP_EXCEPT POP_TOP POP_BLOCK
  94. # else_suite COME_FROM_LOOP
  95. for ::= setup_loop expr get_for_iter store for_block POP_BLOCK
  96. for ::= setup_loop expr get_for_iter store for_block POP_BLOCK NOP
  97. for_block ::= c_stmts_opt COME_FROM_LOOP JUMP_LOOP
  98. forelsestmt ::= setup_loop expr get_for_iter store for_block POP_BLOCK else_suite
  99. forelselaststmt ::= setup_loop expr get_for_iter store for_block POP_BLOCK else_suitec
  100. forelselaststmtc ::= setup_loop expr get_for_iter store for_block POP_BLOCK else_suitec
  101. try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
  102. except_handler opt_come_from_except
  103. tryfinallystmt ::= SETUP_FINALLY suite_stmts_opt POP_BLOCK
  104. LOAD_CONST COME_FROM_FINALLY suite_stmts_opt
  105. END_FINALLY
  106. tryfinally36 ::= SETUP_FINALLY returns
  107. COME_FROM_FINALLY suite_stmts_opt END_FINALLY
  108. tryfinally_return_stmt ::= SETUP_FINALLY suite_stmts_opt POP_BLOCK
  109. LOAD_CONST COME_FROM_FINALLY
  110. """
  111. )
  112. # def custom_classfunc_rule(self, opname, token, customize, next_token):
  113. # """
  114. # call ::= expr {expr}^n CALL_FUNCTION_n
  115. # call ::= expr {expr}^n CALL_FUNCTION_VAR_n
  116. # call ::= expr {expr}^n CALL_FUNCTION_VAR_KW_n
  117. # call ::= expr {expr}^n CALL_FUNCTION_KW_n
  118. # classdefdeco2 ::= LOAD_BUILD_CLASS mkfunc {expr}^n-1 CALL_FUNCTION_n
  119. # """
  120. # args_pos, args_kw = self.get_pos_kw(token)
  121. # # Additional exprs for * and ** args:
  122. # # 0 if neither
  123. # # 1 for CALL_FUNCTION_VAR or CALL_FUNCTION_KW
  124. # # 2 for * and ** args (CALL_FUNCTION_VAR_KW).
  125. # # Yes, this computation based on instruction name is a little bit hoaky.
  126. # nak = (len(opname) - len("CALL_FUNCTION")) // 3
  127. # uniq_param = args_kw + args_pos
  128. # if frozenset(("GET_AWAITABLE", "YIELD_FROM")).issubset(self.seen_ops):
  129. # rule = (
  130. # "async_call ::= expr "
  131. # + ("expr " * args_pos)
  132. # + ("kwarg " * args_kw)
  133. # + "expr " * nak
  134. # + token.kind
  135. # + " GET_AWAITABLE LOAD_CONST YIELD_FROM"
  136. # )
  137. # self.add_unique_rule(rule, token.kind, uniq_param, customize)
  138. # self.add_unique_rule(
  139. # "expr ::= async_call", token.kind, uniq_param, customize
  140. # )
  141. # if opname.startswith("CALL_FUNCTION_VAR"):
  142. # token.kind = self.call_fn_name(token)
  143. # if opname.endswith("KW"):
  144. # kw = "expr "
  145. # else:
  146. # kw = ""
  147. # rule = (
  148. # "call ::= expr expr "
  149. # + ("expr " * args_pos)
  150. # + ("kwarg " * args_kw)
  151. # + kw
  152. # + token.kind
  153. # )
  154. # # Note: semantic actions make use of the fact of whether "args_pos"
  155. # # zero or not in creating a template rule.
  156. # self.add_unique_rule(rule, token.kind, args_pos, customize)
  157. # else:
  158. # token.kind = self.call_fn_name(token)
  159. # uniq_param = args_kw + args_pos
  160. # # Note: 3.5+ have subclassed this method; so we don't handle
  161. # # 'CALL_FUNCTION_VAR' or 'CALL_FUNCTION_EX' here.
  162. # rule = (
  163. # "call ::= expr "
  164. # + ("expr " * args_pos)
  165. # + ("kwarg " * args_kw)
  166. # + "expr " * nak
  167. # + token.kind
  168. # )
  169. # self.add_unique_rule(rule, token.kind, uniq_param, customize)
  170. # if "LOAD_BUILD_CLASS" in self.seen_ops:
  171. # if (
  172. # next_token == "CALL_FUNCTION"
  173. # and next_token.attr == 1
  174. # and args_pos > 1
  175. # ):
  176. # rule = "classdefdeco2 ::= LOAD_BUILD_CLASS mkfunc %s%s_%d" % (
  177. # ("expr " * (args_pos - 1)),
  178. # opname,
  179. # args_pos,
  180. # )
  181. # self.add_unique_rule(rule, token.kind, uniq_param, customize)
  182. def customize_grammar_rules_full38(self, tokens, customize):
  183. self.customize_grammar_rules_lambda38(tokens, customize)
  184. self.customize_reduce_checks_full38(tokens, customize)
  185. self.remove_rules_38()
  186. # include instructions that don't need customization,
  187. # but we'll do a finer check after the rough breakout.
  188. customize_instruction_basenames = frozenset(
  189. (
  190. "BEFORE",
  191. "BUILD",
  192. "CALL",
  193. "CONTINUE",
  194. "DELETE",
  195. "FORMAT",
  196. "GET",
  197. "JUMP",
  198. "LOAD",
  199. "LOOKUP",
  200. "MAKE",
  201. "RETURN",
  202. "RAISE",
  203. "SETUP",
  204. "UNPACK",
  205. "WITH",
  206. )
  207. )
  208. # Opcode names in the custom_ops_processed set have rules that get added
  209. # unconditionally and the rules are constant. So they need to be done
  210. # only once and if we see the opcode a second we don't have to consider
  211. # adding more rules.
  212. #
  213. custom_ops_processed = set()
  214. # A set of instruction operation names that exist in the token stream.
  215. # We use this to customize the grammar that we create.
  216. # 2.6-compatible set comprehensions
  217. # The initial initialization is done in lambea_expr.py
  218. self.seen_ops = frozenset([t.kind for t in tokens])
  219. self.seen_op_basenames = frozenset(
  220. [opname[: opname.rfind("_")] for opname in self.seen_ops]
  221. )
  222. # Loop over instructions adding custom grammar rules based on
  223. # a specific instruction seen.
  224. if "PyPy" in customize:
  225. self.addRule(
  226. """
  227. stmt ::= assign3_pypy
  228. stmt ::= assign2_pypy
  229. assign3_pypy ::= expr expr expr store store store
  230. assign2_pypy ::= expr expr store store
  231. """,
  232. nop_func,
  233. )
  234. for i, token in enumerate(tokens):
  235. opname = token.kind
  236. # Do a quick breakout before testing potentially
  237. # each of the dozen or so instruction in if elif.
  238. if (
  239. opname[: opname.find("_")] not in customize_instruction_basenames
  240. or opname in custom_ops_processed
  241. ):
  242. continue
  243. opname_base = opname[: opname.rfind("_")]
  244. # The order of opname listed is roughly sorted below
  245. if opname == "LOAD_ASSERT" and "PyPy" in customize:
  246. rules_str = """
  247. stmt ::= JUMP_IF_NOT_DEBUG stmts COME_FROM
  248. """
  249. self.add_unique_doc_rules(rules_str, customize)
  250. elif opname == "BEFORE_ASYNC_WITH":
  251. rules_str = """
  252. stmt ::= async_with_stmt
  253. stmt ::= async_with_as_stmt
  254. c_stmt ::= c_async_with_stmt
  255. """
  256. if self.version < (3, 8):
  257. rules_str += """
  258. stmt ::= async_with_stmt SETUP_ASYNC_WITH
  259. c_stmt ::= c_async_with_stmt SETUP_ASYNC_WITH
  260. async_with_stmt ::= expr
  261. async_with_pre
  262. POP_TOP
  263. suite_stmts_opt
  264. POP_BLOCK LOAD_CONST
  265. async_with_post
  266. c_async_with_stmt ::= expr
  267. async_with_pre
  268. POP_TOP
  269. c_suite_stmts_opt
  270. POP_BLOCK LOAD_CONST
  271. async_with_post
  272. async_with_stmt ::= expr
  273. async_with_pre
  274. POP_TOP
  275. suite_stmts_opt
  276. async_with_post
  277. c_async_with_stmt ::= expr
  278. async_with_pre
  279. POP_TOP
  280. c_suite_stmts_opt
  281. async_with_post
  282. async_with_as_stmt ::= expr
  283. async_with_pre
  284. store
  285. suite_stmts_opt
  286. POP_BLOCK LOAD_CONST
  287. async_with_post
  288. c_async_with_as_stmt ::= expr
  289. async_with_pre
  290. store
  291. c_suite_stmts_opt
  292. POP_BLOCK LOAD_CONST
  293. async_with_post
  294. async_with_as_stmt ::= expr
  295. async_with_pre
  296. store
  297. suite_stmts_opt
  298. async_with_post
  299. c_async_with_as_stmt ::= expr
  300. async_with_pre
  301. store
  302. suite_stmts_opt
  303. async_with_post
  304. """
  305. else:
  306. rules_str += """
  307. async_with_pre ::= BEFORE_ASYNC_WITH GET_AWAITABLE LOAD_CONST YIELD_FROM SETUP_ASYNC_WITH
  308. async_with_post ::= BEGIN_FINALLY COME_FROM_ASYNC_WITH
  309. WITH_CLEANUP_START GET_AWAITABLE LOAD_CONST YIELD_FROM
  310. WITH_CLEANUP_FINISH END_FINALLY
  311. async_with_stmt ::= expr
  312. async_with_pre
  313. POP_TOP
  314. suite_stmts
  315. POP_TOP POP_BLOCK
  316. async_with_post
  317. c_async_with_stmt ::= expr
  318. async_with_pre
  319. POP_TOP
  320. c_suite_stmts
  321. POP_TOP POP_BLOCK
  322. async_with_post
  323. c_async_with_stmt ::= async_with_stmt
  324. async_with_stmt ::= expr
  325. async_with_pre
  326. POP_TOP
  327. c_suite_stmts
  328. POP_BLOCK
  329. BEGIN_FINALLY
  330. WITH_CLEANUP_START GET_AWAITABLE LOAD_CONST YIELD_FROM
  331. WITH_CLEANUP_FINISH POP_FINALLY POP_TOP JUMP_FORWARD
  332. POP_BLOCK
  333. BEGIN_FINALLY
  334. COME_FROM_ASYNC_WITH
  335. WITH_AWAITABLE
  336. LOAD_CONST
  337. YEILD_FROM
  338. WITH_CLEANUP_FINISH
  339. END_FINALLY
  340. async_with_as_stmt ::= expr
  341. async_with_pre
  342. store suite_stmts
  343. POP_TOP POP_BLOCK
  344. async_with_post
  345. c_async_with_as_stmt ::= expr
  346. async_with_pre
  347. store suite_stmts
  348. POP_TOP POP_BLOCK
  349. async_with_post
  350. async_with_as_stmt ::= expr
  351. async_with_pre
  352. store suite_stmts
  353. POP_BLOCK async_with_post
  354. c_async_with_as_stmt ::= expr
  355. async_with_pre
  356. store suite_stmts
  357. POP_BLOCK async_with_post
  358. """
  359. self.addRule(rules_str, nop_func)
  360. elif opname == "BUILD_STRING_2":
  361. self.addRule(
  362. """
  363. expr ::= formatted_value_debug
  364. formatted_value_debug ::= LOAD_STR formatted_value2 BUILD_STRING_2
  365. formatted_value_debug ::= LOAD_STR formatted_value1 BUILD_STRING_2
  366. """,
  367. nop_func,
  368. )
  369. custom_ops_processed.add(opname)
  370. elif opname == "BUILD_STRING_3":
  371. self.addRule(
  372. """
  373. expr ::= formatted_value_debug
  374. formatted_value_debug ::= LOAD_STR formatted_value2 LOAD_STR BUILD_STRING_3
  375. formatted_value_debug ::= LOAD_STR formatted_value1 LOAD_STR BUILD_STRING_3
  376. """,
  377. nop_func,
  378. )
  379. custom_ops_processed.add(opname)
  380. elif opname in frozenset(
  381. (
  382. "CALL_FUNCTION",
  383. "CALL_FUNCTION_EX_KW",
  384. "CALL_FUNCTION_VAR_KW",
  385. "CALL_FUNCTION_VAR",
  386. "CALL_FUNCTION_VAR_KW",
  387. )
  388. ) or opname.startswith("CALL_FUNCTION_KW"):
  389. if opname == "CALL_FUNCTION" and token.attr == 1:
  390. rule = """
  391. classdefdeco1 ::= expr classdefdeco2 CALL_FUNCTION_1
  392. classdefdeco1 ::= expr classdefdeco1 CALL_FUNCTION_1
  393. """
  394. self.addRule(rule, nop_func)
  395. # self.custom_classfunc_rule(opname, token, customize, tokens[i + 1])
  396. # Note: don't add to custom_ops_processed.
  397. elif opname_base == "CALL_METHOD":
  398. # PyPy and Python 3.7+ only - DRY with parse2
  399. if opname == "CALL_METHOD_KW":
  400. args_kw = token.attr
  401. rules_str = """
  402. expr ::= call_kw_pypy37
  403. pypy_kw_keys ::= LOAD_CONST
  404. """
  405. self.add_unique_doc_rules(rules_str, customize)
  406. rule = (
  407. "call_kw_pypy37 ::= expr "
  408. + ("expr " * args_kw)
  409. + " pypy_kw_keys "
  410. + opname
  411. )
  412. else:
  413. args_pos, args_kw = self.get_pos_kw(token)
  414. # number of apply equiv arguments:
  415. nak = (len(opname_base) - len("CALL_METHOD")) // 3
  416. rule = (
  417. "call ::= expr "
  418. + ("expr " * args_pos)
  419. + ("kwarg " * args_kw)
  420. + "expr " * nak
  421. + opname
  422. )
  423. self.add_unique_rule(rule, opname, token.attr, customize)
  424. elif opname == "CONTINUE":
  425. self.addRule("continue ::= CONTINUE", nop_func)
  426. custom_ops_processed.add(opname)
  427. elif opname == "CONTINUE_LOOP":
  428. self.addRule("continue ::= CONTINUE_LOOP", nop_func)
  429. custom_ops_processed.add(opname)
  430. elif opname == "DELETE_ATTR":
  431. self.addRule("delete ::= expr DELETE_ATTR", nop_func)
  432. custom_ops_processed.add(opname)
  433. elif opname == "DELETE_DEREF":
  434. self.addRule(
  435. """
  436. stmt ::= del_deref_stmt
  437. del_deref_stmt ::= DELETE_DEREF
  438. """,
  439. nop_func,
  440. )
  441. custom_ops_processed.add(opname)
  442. elif opname == "DELETE_SUBSCR":
  443. self.addRule(
  444. """
  445. delete ::= delete_subscript
  446. delete_subscript ::= expr expr DELETE_SUBSCR
  447. """,
  448. nop_func,
  449. )
  450. custom_ops_processed.add(opname)
  451. elif opname == "FORMAT_VALUE_ATTR":
  452. self.addRule(
  453. """
  454. expr ::= formatted_value_debug
  455. formatted_value_debug ::= LOAD_STR formatted_value2 BUILD_STRING_2
  456. expr FORMAT_VALUE_ATTR
  457. formatted_value_debug ::= LOAD_STR formatted_value2 BUILD_STRING_2
  458. formatted_value_debug ::= LOAD_STR formatted_value1 BUILD_STRING_2
  459. """,
  460. nop_func,
  461. )
  462. custom_ops_processed.add(opname)
  463. elif opname == "GET_AITER":
  464. self.addRule(
  465. """
  466. async_for ::= GET_AITER _come_froms
  467. SETUP_FINALLY GET_ANEXT LOAD_CONST YIELD_FROM POP_BLOCK
  468. async_for_stmt38 ::= expr async_for
  469. store for_block
  470. COME_FROM_FINALLY
  471. END_ASYNC_FOR
  472. # FIXME: COME_FROMs after the else_suite or
  473. # END_ASYNC_FOR distinguish which of for / forelse
  474. # is used. Add COME_FROMs and check of add up
  475. # control-flow detection phase.
  476. # async_forelse_stmt38 ::= expr async_for store
  477. # for_block COME_FROM_FINALLY END_ASYNC_FOR
  478. # else_suite
  479. async_forelse_stmt38 ::= expr async_for
  480. store for_block
  481. COME_FROM_FINALLY
  482. END_ASYNC_FOR
  483. else_suite
  484. POP_TOP COME_FROM
  485. stmt ::= async_for_stmt38
  486. stmt ::= async_forelse_stmt38
  487. stmt ::= generator_exp_async
  488. """,
  489. nop_func,
  490. )
  491. custom_ops_processed.add(opname)
  492. elif opname == "GET_ANEXT":
  493. self.addRule(
  494. """
  495. stmt ::= genexpr_func_async
  496. stmt ::= BUILD_SET_0 genexpr_func_async
  497. RETURN_VALUE
  498. _come_froms
  499. """,
  500. nop_func,
  501. )
  502. custom_ops_processed.add(opname)
  503. elif opname == "JUMP_IF_NOT_DEBUG":
  504. self.addRule(
  505. """
  506. stmt ::= assert_pypy
  507. stmt ::= assert2_pypy", nop_func)
  508. assert_pypy ::= JUMP_IF_NOT_DEBUG expr POP_JUMP_IF_TRUE
  509. LOAD_ASSERT RAISE_VARARGS_1 COME_FROM
  510. assert2_pypy ::= JUMP_IF_NOT_DEBUG assert_expr POP_JUMP_IF_TRUE
  511. LOAD_ASSERT expr CALL_FUNCTION_1
  512. RAISE_VARARGS_1 COME_FROM
  513. assert2_pypy ::= JUMP_IF_NOT_DEBUG expr POP_JUMP_IF_TRUE
  514. LOAD_ASSERT expr CALL_FUNCTION_1
  515. RAISE_VARARGS_1 COME_FROM,
  516. """,
  517. nop_func,
  518. )
  519. custom_ops_processed.add(opname)
  520. elif opname == "LOAD_CLASSDEREF":
  521. # Python 3.4+
  522. self.addRule("expr ::= LOAD_CLASSDEREF", nop_func)
  523. custom_ops_processed.add(opname)
  524. elif opname == "LOAD_CLASSNAME":
  525. self.addRule("expr ::= LOAD_CLASSNAME", nop_func)
  526. custom_ops_processed.add(opname)
  527. elif opname == "RAISE_VARARGS_0":
  528. self.addRule(
  529. """
  530. stmt ::= raise_stmt0
  531. last_stmt ::= raise_stmt0
  532. raise_stmt0 ::= RAISE_VARARGS_0
  533. """,
  534. nop_func,
  535. )
  536. custom_ops_processed.add(opname)
  537. elif opname == "RAISE_VARARGS_1":
  538. self.addRule(
  539. """
  540. stmt ::= raise_stmt1
  541. last_stmt ::= raise_stmt1
  542. raise_stmt1 ::= expr RAISE_VARARGS_1
  543. """,
  544. nop_func,
  545. )
  546. custom_ops_processed.add(opname)
  547. elif opname == "RAISE_VARARGS_2":
  548. self.addRule(
  549. """
  550. stmt ::= raise_stmt2
  551. last_stmt ::= raise_stmt2
  552. raise_stmt2 ::= expr expr RAISE_VARARGS_2
  553. """,
  554. nop_func,
  555. )
  556. custom_ops_processed.add(opname)
  557. elif opname == "RETURN_VALUE_LAMBDA":
  558. self.addRule(
  559. """
  560. return_expr_lambda ::= return_expr RETURN_VALUE_LAMBDA
  561. """,
  562. nop_func,
  563. )
  564. custom_ops_processed.add(opname)
  565. elif opname == "SETUP_EXCEPT":
  566. self.addRule(
  567. """
  568. try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
  569. except_handler opt_come_from_except
  570. c_try_except ::= SETUP_EXCEPT c_suite_stmts POP_BLOCK
  571. c_except_handler opt_come_from_except
  572. stmt ::= tryelsestmt3
  573. tryelsestmt3 ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
  574. except_handler COME_FROM else_suite
  575. opt_come_from_except
  576. tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
  577. except_handler else_suite come_from_except_clauses
  578. tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
  579. except_handler else_suite come_froms
  580. c_stmt ::= c_tryelsestmt
  581. c_tryelsestmt ::= SETUP_EXCEPT c_suite_stmts POP_BLOCK
  582. c_except_handler
  583. come_any_froms else_suitec
  584. come_from_except_clauses
  585. """,
  586. nop_func,
  587. )
  588. custom_ops_processed.add(opname)
  589. elif opname == "WITH_CLEANUP_START":
  590. rules_str = """
  591. stmt ::= with_null
  592. with_null ::= with_suffix
  593. with_suffix ::= WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY
  594. """
  595. self.addRule(rules_str, nop_func)
  596. # FIXME: reconcile with same code in lambda_custom.py
  597. elif opname == "SETUP_WITH":
  598. rules_str = """
  599. stmt ::= with
  600. stmt ::= with_as_pass
  601. stmt ::= with_as
  602. c_stmt ::= c_with
  603. c_with ::= expr SETUP_WITH POP_TOP
  604. c_suite_stmts_opt
  605. COME_FROM_WITH
  606. with_suffix
  607. c_with ::= expr SETUP_WITH POP_TOP
  608. c_suite_stmts_opt
  609. POP_BLOCK LOAD_CONST COME_FROM_WITH
  610. with_suffix
  611. with ::= expr SETUP_WITH POP_TOP
  612. suite_stmts_opt
  613. COME_FROM_WITH
  614. with_suffix
  615. with ::= expr
  616. SETUP_WITH POP_TOP suite_stmts_opt
  617. POP_BLOCK LOAD_CONST COME_FROM_WITH
  618. with_suffix
  619. with ::= expr
  620. SETUP_WITH POP_TOP suite_stmts_opt
  621. POP_BLOCK LOAD_CONST COME_FROM_WITH
  622. with_suffix
  623. with_as ::= expr
  624. SETUP_WITH store suite_stmts_opt
  625. POP_BLOCK LOAD_CONST COME_FROM_WITH
  626. with_suffix
  627. with_as ::= expr SETUP_WITH store suite_stmts_opt COME_FROM_WITH
  628. with_suffix
  629. with_as ::= expr
  630. SETUP_WITH store suite_stmts_opt
  631. POP_BLOCK LOAD_CONST COME_FROM_WITH
  632. with_suffix
  633. with_as_pass ::= expr
  634. SETUP_WITH store pass
  635. POP_BLOCK BEGIN_FINALLY COME_FROM_WITH
  636. with_suffix
  637. """
  638. if self.version < (3, 8):
  639. rules_str += """
  640. with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK
  641. LOAD_CONST
  642. with_suffix
  643. """
  644. else:
  645. rules_str += """
  646. # A return at the end of a withas stmt can be this.
  647. # FIXME: should this be a different kind of return?
  648. return ::= return_expr POP_BLOCK
  649. ROT_TWO
  650. BEGIN_FINALLY
  651. WITH_CLEANUP_START
  652. WITH_CLEANUP_FINISH
  653. POP_FINALLY
  654. RETURN_VALUE
  655. with ::= expr
  656. SETUP_WITH POP_TOP suite_stmts_opt
  657. POP_BLOCK LOAD_CONST COME_FROM_WITH
  658. with_suffix
  659. with_as ::= expr
  660. SETUP_WITH store suite_stmts
  661. POP_BLOCK LOAD_CONST COME_FROM_WITH
  662. with_as ::= expr
  663. SETUP_WITH store suite_stmts
  664. POP_BLOCK BEGIN_FINALLY COME_FROM_WITH
  665. with_suffix
  666. # with_as ::= expr SETUP_WITH store suite_stmts
  667. # COME_FROM expr COME_FROM POP_BLOCK ROT_TWO
  668. # BEGIN_FINALLY WITH_CLEANUP_START WITH_CLEANUP_FINISH
  669. # POP_FINALLY RETURN_VALUE COME_FROM_WITH
  670. # WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY
  671. with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK
  672. BEGIN_FINALLY COME_FROM_WITH
  673. with_suffix
  674. """
  675. self.addRule(rules_str, nop_func)
  676. pass
  677. return
  678. def customize_reduce_checks_full38(self, tokens, customize):
  679. """
  680. Extra tests when a reduction is made in the full grammar.
  681. Reductions here are extended from those used in the lambda grammar
  682. """
  683. self.remove_rules_38()
  684. self.check_reduce["and"] = "AST"
  685. self.check_reduce["and_cond"] = "AST"
  686. self.check_reduce["and_not"] = "AST"
  687. self.check_reduce["annotate_tuple"] = "tokens"
  688. self.check_reduce["aug_assign1"] = "AST"
  689. self.check_reduce["aug_assign2"] = "AST"
  690. self.check_reduce["c_forelsestmt38"] = "AST"
  691. self.check_reduce["c_try_except"] = "AST"
  692. self.check_reduce["c_tryelsestmt"] = "AST"
  693. self.check_reduce["if_and_stmt"] = "AST"
  694. self.check_reduce["if_and_elsestmtc"] = "AST"
  695. self.check_reduce["if_not_stmtc"] = "AST"
  696. self.check_reduce["ifelsestmt"] = "AST"
  697. self.check_reduce["ifelsestmtc"] = "AST"
  698. self.check_reduce["iflaststmt"] = "AST"
  699. self.check_reduce["iflaststmtc"] = "AST"
  700. self.check_reduce["ifstmt"] = "AST"
  701. self.check_reduce["ifstmtc"] = "AST"
  702. self.check_reduce["ifstmts_jump"] = "AST"
  703. self.check_reduce["ifstmts_jumpc"] = "AST"
  704. self.check_reduce["import_as37"] = "tokens"
  705. self.check_reduce["import_from37"] = "AST"
  706. self.check_reduce["import_from_as37"] = "tokens"
  707. self.check_reduce["lastc_stmt"] = "tokens"
  708. self.check_reduce["list_if_not"] = "AST"
  709. self.check_reduce["while1elsestmt"] = "tokens"
  710. self.check_reduce["while1stmt"] = "tokens"
  711. self.check_reduce["whilestmt"] = "tokens"
  712. self.check_reduce["not_or"] = "AST"
  713. self.check_reduce["or"] = "AST"
  714. self.check_reduce["or_cond"] = "tokens"
  715. self.check_reduce["testtrue"] = "tokens"
  716. self.check_reduce["testfalsec"] = "tokens"
  717. self.check_reduce["break"] = "tokens"
  718. self.check_reduce["forelselaststmt38"] = "AST"
  719. self.check_reduce["forelselaststmtc38"] = "AST"
  720. self.check_reduce["for38"] = "tokens"
  721. self.check_reduce["ifstmt"] = "AST"
  722. self.check_reduce["joined_str"] = "AST"
  723. self.check_reduce["pop_return"] = "tokens"
  724. self.check_reduce["whileTruestmt38"] = "AST"
  725. self.check_reduce["whilestmt38"] = "tokens"
  726. self.check_reduce["try_elsestmtl38"] = "AST"
  727. self.reduce_check_table["break"] = break_invalid
  728. self.reduce_check_table["if_not_stmtc"] = if_not_stmtc_invalid
  729. self.reduce_check_table["for38"] = for38_invalid
  730. self.reduce_check_table["c_forelsestmt38"] = forelse38_invalid
  731. self.reduce_check_table["forelselaststmt38"] = forelse38_invalid
  732. self.reduce_check_table["forelselaststmtc38"] = forelse38_invalid
  733. # self.reduce_check_table["joined_str"] = joined_str_check.joined_str_invalid
  734. self.reduce_check_table["or"] = or_cond_check_invalid
  735. self.reduce_check_table["pop_return"] = pop_return_check
  736. self.reduce_check_table["whilestmt38"] = whilestmt38_check
  737. self.reduce_check_table["whileTruestmt38"] = whileTruestmt38_check
  738. # Use update we don't destroy entries from lambda.
  739. self.reduce_check_table.update(
  740. {
  741. # "ifelsestmt": ifelsestmt_ok,
  742. "ifstmt": ifstmt,
  743. # "import_from37": import_from37_ok,
  744. }
  745. )
  746. self.check_reduce["ifelsestmt"] = "AST"
  747. self.check_reduce["ifelsestmtc"] = "AST"
  748. self.check_reduce["ifstmt"] = "AST"
  749. # self.check_reduce["import_from37"] = "AST"
  750. def customize_grammar_rules38(self, tokens, customize):
  751. Python37BaseParser.customize_grammar_rules37(self, tokens, customize)
  752. self.customize_reduce_checks_lambda38()
  753. self.customize_reduce_checks_full38(tokens, customize)
  754. # include instructions that don't need customization,
  755. # but we'll do a finer check after the rough breakout.
  756. customize_instruction_basenames = frozenset(
  757. (
  758. "BEFORE",
  759. "BUILD",
  760. "CALL",
  761. "CONTINUE",
  762. "DELETE",
  763. "FORMAT",
  764. "GET",
  765. "JUMP",
  766. "LOAD",
  767. "LOOKUP",
  768. "MAKE",
  769. "RETURN",
  770. "RAISE",
  771. "SETUP",
  772. "UNPACK",
  773. "WITH",
  774. )
  775. )
  776. # Opcode names in the custom_ops_processed set have rules that get added
  777. # unconditionally and the rules are constant. So they need to be done
  778. # only once and if we see the opcode a second we don't have to consider
  779. # adding more rules.
  780. #
  781. custom_ops_processed = set()
  782. # A set of instruction operation names that exist in the token stream.
  783. # We use this to customize the grammar that we create.
  784. # 2.6-compatible set comprehensions
  785. # The initial initialization is done in lambda_expr.py
  786. self.seen_ops = frozenset([t.kind for t in tokens])
  787. self.seen_op_basenames = frozenset(
  788. [opname[: opname.rfind("_")] for opname in self.seen_ops]
  789. )
  790. # Loop over instructions adding custom grammar rules based on
  791. # a specific instruction seen.
  792. if "PyPy" in customize:
  793. self.addRule(
  794. """
  795. stmt ::= assign3_pypy
  796. stmt ::= assign2_pypy
  797. assign3_pypy ::= expr expr expr store store store
  798. assign2_pypy ::= expr expr store store
  799. """,
  800. nop_func,
  801. )
  802. for i, token in enumerate(tokens):
  803. opname = token.kind
  804. # Do a quick breakout before testing potentially
  805. # each of the dozen or so instruction in if elif.
  806. if (
  807. opname[: opname.find("_")] not in customize_instruction_basenames
  808. or opname in custom_ops_processed
  809. ):
  810. continue
  811. opname_base = opname[: opname.rfind("_")]
  812. # The order of opname listed is roughly sorted below
  813. if opname == "LOAD_ASSERT" and "PyPy" in customize:
  814. rules_str = """
  815. stmt ::= JUMP_IF_NOT_DEBUG stmts COME_FROM
  816. """
  817. self.add_unique_doc_rules(rules_str, customize)
  818. elif opname == "BEFORE_ASYNC_WITH":
  819. rules_str = """
  820. stmt ::= async_with_stmt
  821. stmt ::= async_with_as_stmt
  822. c_stmt ::= c_async_with_stmt
  823. """
  824. if self.version < (3, 8):
  825. rules_str += """
  826. async_with_pre ::= BEFORE_ASYNC_WITH GET_AWAITABLE LOAD_CONST YIELD_FROM
  827. SETUP_ASYNC_WITH
  828. stmt ::= async_with_stmt SETUP_ASYNC_WITH
  829. c_stmt ::= c_async_with_stmt SETUP_ASYNC_WITH
  830. async_with_stmt ::= expr
  831. async_with_pre
  832. POP_TOP
  833. suite_stmts_opt
  834. POP_BLOCK LOAD_CONST
  835. async_with_post
  836. c_async_with_stmt ::= expr
  837. async_with_pre
  838. POP_TOP
  839. c_suite_stmts_opt
  840. POP_BLOCK LOAD_CONST
  841. async_with_post
  842. async_with_stmt ::= expr
  843. async_with_pre
  844. POP_TOP
  845. suite_stmts_opt
  846. async_with_post
  847. c_async_with_stmt ::= expr
  848. async_with_pre
  849. POP_TOP
  850. c_suite_stmts_opt
  851. async_with_post
  852. async_with_as_stmt ::= expr
  853. async_with_pre
  854. store
  855. suite_stmts_opt
  856. POP_BLOCK LOAD_CONST
  857. async_with_post
  858. c_async_with_as_stmt ::= expr
  859. async_with_pre
  860. store
  861. c_suite_stmts_opt
  862. POP_BLOCK LOAD_CONST
  863. async_with_post
  864. async_with_as_stmt ::= expr
  865. async_with_pre
  866. store
  867. suite_stmts_opt
  868. async_with_post
  869. c_async_with_as_stmt ::= expr
  870. async_with_pre
  871. store
  872. suite_stmts_opt
  873. async_with_post
  874. """
  875. else:
  876. rules_str += """
  877. async_with_pre ::= BEFORE_ASYNC_WITH GET_AWAITABLE LOAD_CONST YIELD_FROM SETUP_ASYNC_WITH
  878. async_with_post ::= BEGIN_FINALLY COME_FROM_ASYNC_WITH
  879. WITH_CLEANUP_START GET_AWAITABLE LOAD_CONST YIELD_FROM
  880. WITH_CLEANUP_FINISH END_FINALLY
  881. async_with_stmt ::= expr
  882. async_with_pre
  883. POP_TOP
  884. suite_stmts
  885. POP_TOP POP_BLOCK
  886. async_with_post
  887. c_async_with_stmt ::= expr
  888. async_with_pre
  889. POP_TOP
  890. c_suite_stmts
  891. POP_TOP POP_BLOCK
  892. async_with_post
  893. c_async_with_stmt ::= async_with_stmt
  894. async_with_stmt ::= expr
  895. async_with_pre
  896. POP_TOP
  897. c_suite_stmts
  898. POP_BLOCK
  899. BEGIN_FINALLY
  900. WITH_CLEANUP_START GET_AWAITABLE LOAD_CONST YIELD_FROM
  901. WITH_CLEANUP_FINISH POP_FINALLY POP_TOP JUMP_FORWARD
  902. POP_BLOCK
  903. BEGIN_FINALLY
  904. COME_FROM_ASYNC_WITH
  905. WITH_AWAITABLE
  906. LOAD_CONST
  907. YEILD_FROM
  908. WITH_CLEANUP_FINISH
  909. END_FINALLY
  910. async_with_as_stmt ::= expr
  911. async_with_pre
  912. store suite_stmts
  913. POP_TOP POP_BLOCK
  914. async_with_post
  915. c_async_with_as_stmt ::= expr
  916. async_with_pre
  917. store suite_stmts
  918. POP_TOP POP_BLOCK
  919. async_with_post
  920. async_with_as_stmt ::= expr
  921. async_with_pre
  922. store suite_stmts
  923. POP_BLOCK async_with_post
  924. c_async_with_as_stmt ::= expr
  925. async_with_pre
  926. store suite_stmts
  927. POP_BLOCK async_with_post
  928. """
  929. self.addRule(rules_str, nop_func)
  930. elif opname in frozenset(
  931. (
  932. "CALL_FUNCTION",
  933. "CALL_FUNCTION_EX_KW",
  934. "CALL_FUNCTION_VAR_KW",
  935. "CALL_FUNCTION_VAR",
  936. "CALL_FUNCTION_VAR_KW",
  937. )
  938. ) or opname.startswith("CALL_FUNCTION_KW"):
  939. if opname == "CALL_FUNCTION" and token.attr == 1:
  940. rule = """
  941. classdefdeco1 ::= expr classdefdeco2 CALL_FUNCTION_1
  942. classdefdeco1 ::= expr classdefdeco1 CALL_FUNCTION_1
  943. """
  944. self.addRule(rule, nop_func)
  945. # self.custom_classfunc_rule(opname, token, customize, tokens[i + 1])
  946. # Note: don't add to custom_ops_processed.
  947. elif opname_base == "CALL_METHOD":
  948. # PyPy and Python 3.7+ only - DRY with parse2
  949. if opname == "CALL_METHOD_KW":
  950. args_kw = token.attr
  951. rules_str = """
  952. expr ::= call_kw_pypy37
  953. pypy_kw_keys ::= LOAD_CONST
  954. """
  955. self.add_unique_doc_rules(rules_str, customize)
  956. rule = (
  957. "call_kw_pypy37 ::= expr "
  958. + ("expr " * args_kw)
  959. + " pypy_kw_keys "
  960. + opname
  961. )
  962. else:
  963. args_pos, args_kw = self.get_pos_kw(token)
  964. # number of apply equiv arguments:
  965. nak = (len(opname_base) - len("CALL_METHOD")) // 3
  966. rule = (
  967. "call ::= expr "
  968. + ("expr " * args_pos)
  969. + ("kwarg " * args_kw)
  970. + "expr " * nak
  971. + opname
  972. )
  973. self.add_unique_rule(rule, opname, token.attr, customize)
  974. elif opname == "CONTINUE":
  975. self.addRule("continue ::= CONTINUE", nop_func)
  976. custom_ops_processed.add(opname)
  977. elif opname == "CONTINUE_LOOP":
  978. self.addRule("continue ::= CONTINUE_LOOP", nop_func)
  979. custom_ops_processed.add(opname)
  980. elif opname == "DELETE_ATTR":
  981. self.addRule("delete ::= expr DELETE_ATTR", nop_func)
  982. custom_ops_processed.add(opname)
  983. elif opname == "DELETE_DEREF":
  984. self.addRule(
  985. """
  986. stmt ::= del_deref_stmt
  987. del_deref_stmt ::= DELETE_DEREF
  988. """,
  989. nop_func,
  990. )
  991. custom_ops_processed.add(opname)
  992. elif opname == "DELETE_SUBSCR":
  993. self.addRule(
  994. """
  995. delete ::= delete_subscript
  996. delete_subscript ::= expr expr DELETE_SUBSCR
  997. """,
  998. nop_func,
  999. )
  1000. custom_ops_processed.add(opname)
  1001. elif opname == "GET_AITER":
  1002. self.addRule(
  1003. """
  1004. stmt ::= generator_exp_async
  1005. stmt ::= genexpr_func_async
  1006. """,
  1007. nop_func,
  1008. )
  1009. custom_ops_processed.add(opname)
  1010. elif opname == "GET_ANEXT":
  1011. self.addRule(
  1012. """
  1013. stmt ::= BUILD_SET_0 genexpr_func_async
  1014. RETURN_VALUE
  1015. bb_doms_end_opt
  1016. """,
  1017. nop_func,
  1018. )
  1019. custom_ops_processed.add(opname)
  1020. elif opname == "JUMP_IF_NOT_DEBUG":
  1021. self.addRule(
  1022. """
  1023. stmt ::= assert_pypy
  1024. stmt ::= assert2_pypy", nop_func)
  1025. assert_pypy ::= JUMP_IF_NOT_DEBUG expr POP_JUMP_IF_TRUE
  1026. LOAD_ASSERT RAISE_VARARGS_1 COME_FROM
  1027. assert2_pypy ::= JUMP_IF_NOT_DEBUG assert_expr POP_JUMP_IF_TRUE
  1028. LOAD_ASSERT expr CALL_FUNCTION_1
  1029. RAISE_VARARGS_1 COME_FROM
  1030. assert2_pypy ::= JUMP_IF_NOT_DEBUG expr POP_JUMP_IF_TRUE
  1031. LOAD_ASSERT expr CALL_FUNCTION_1
  1032. RAISE_VARARGS_1 COME_FROM,
  1033. """,
  1034. nop_func,
  1035. )
  1036. custom_ops_processed.add(opname)
  1037. elif opname == "LOAD_CLASSDEREF":
  1038. # Python 3.4+
  1039. self.addRule("expr ::= LOAD_CLASSDEREF", nop_func)
  1040. custom_ops_processed.add(opname)
  1041. elif opname == "LOAD_CLASSNAME":
  1042. self.addRule("expr ::= LOAD_CLASSNAME", nop_func)
  1043. custom_ops_processed.add(opname)
  1044. elif opname == "RAISE_VARARGS_0":
  1045. self.addRule(
  1046. """
  1047. stmt ::= raise_stmt0
  1048. last_stmt ::= raise_stmt0
  1049. raise_stmt0 ::= RAISE_VARARGS_0
  1050. """,
  1051. nop_func,
  1052. )
  1053. custom_ops_processed.add(opname)
  1054. elif opname == "RAISE_VARARGS_1":
  1055. self.addRule(
  1056. """
  1057. stmt ::= raise_stmt1
  1058. last_stmt ::= raise_stmt1
  1059. raise_stmt1 ::= expr RAISE_VARARGS_1
  1060. """,
  1061. nop_func,
  1062. )
  1063. custom_ops_processed.add(opname)
  1064. elif opname == "RAISE_VARARGS_2":
  1065. self.addRule(
  1066. """
  1067. stmt ::= raise_stmt2
  1068. last_stmt ::= raise_stmt2
  1069. raise_stmt2 ::= expr expr RAISE_VARARGS_2
  1070. """,
  1071. nop_func,
  1072. )
  1073. custom_ops_processed.add(opname)
  1074. elif opname == "RETURN_VALUE_LAMBDA":
  1075. self.addRule(
  1076. """
  1077. return_expr_lambda ::= return_expr RETURN_VALUE_LAMBDA
  1078. """,
  1079. nop_func,
  1080. )
  1081. custom_ops_processed.add(opname)
  1082. elif opname == "SETUP_EXCEPT":
  1083. self.addRule(
  1084. """
  1085. try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
  1086. except_handler opt_come_from_except
  1087. c_try_except ::= SETUP_EXCEPT c_suite_stmts POP_BLOCK
  1088. c_except_handler opt_come_from_except
  1089. stmt ::= tryelsestmt3
  1090. tryelsestmt3 ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
  1091. except_handler COME_FROM else_suite
  1092. opt_come_from_except
  1093. tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
  1094. except_handler else_suite come_from_except_clauses
  1095. tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
  1096. except_handler else_suite come_froms
  1097. c_stmt ::= c_tryelsestmt
  1098. c_tryelsestmt ::= SETUP_EXCEPT c_suite_stmts POP_BLOCK
  1099. c_except_handler
  1100. come_any_froms else_suitec
  1101. come_from_except_clauses
  1102. """,
  1103. nop_func,
  1104. )
  1105. custom_ops_processed.add(opname)
  1106. elif opname == "WITH_CLEANUP_START":
  1107. rules_str = """
  1108. stmt ::= with_null
  1109. with_null ::= with_suffix
  1110. with_suffix ::= WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY
  1111. """
  1112. self.addRule(rules_str, nop_func)
  1113. # FIXME: reconcile with same code in lambda_custom.py
  1114. elif opname == "SETUP_WITH":
  1115. rules_str = """
  1116. stmt ::= with
  1117. stmt ::= with_as
  1118. c_stmt ::= c_with
  1119. c_with ::= expr SETUP_WITH POP_TOP
  1120. c_suite_stmts_opt
  1121. COME_FROM_WITH
  1122. with_suffix
  1123. c_with ::= expr SETUP_WITH POP_TOP
  1124. c_suite_stmts_opt
  1125. POP_BLOCK LOAD_CONST COME_FROM_WITH
  1126. with_suffix
  1127. with ::= expr SETUP_WITH POP_TOP
  1128. suite_stmts_opt
  1129. COME_FROM_WITH
  1130. with_suffix
  1131. with_as ::= expr SETUP_WITH store suite_stmts_opt COME_FROM_WITH
  1132. with_suffix
  1133. with ::= expr
  1134. SETUP_WITH POP_TOP suite_stmts_opt
  1135. POP_BLOCK LOAD_CONST COME_FROM_WITH
  1136. with_suffix
  1137. with_as ::= expr
  1138. SETUP_WITH store suite_stmts_opt
  1139. POP_BLOCK LOAD_CONST COME_FROM_WITH
  1140. with_suffix
  1141. with ::= expr
  1142. SETUP_WITH POP_TOP suite_stmts_opt
  1143. POP_BLOCK LOAD_CONST COME_FROM_WITH
  1144. with_suffix
  1145. with_as ::= expr
  1146. SETUP_WITH store suite_stmts_opt
  1147. POP_BLOCK LOAD_CONST COME_FROM_WITH
  1148. with_suffix
  1149. """
  1150. if self.version < (3, 8):
  1151. rules_str += """
  1152. with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK
  1153. LOAD_CONST
  1154. with_suffix
  1155. """
  1156. else:
  1157. rules_str += """
  1158. # A return at the end of a withas stmt can be this.
  1159. # FIXME: should this be a different kind of return?
  1160. return ::= return_expr POP_BLOCK
  1161. ROT_TWO
  1162. BEGIN_FINALLY
  1163. WITH_CLEANUP_START
  1164. WITH_CLEANUP_FINISH
  1165. POP_FINALLY
  1166. RETURN_VALUE
  1167. with ::= expr
  1168. SETUP_WITH POP_TOP suite_stmts_opt
  1169. POP_BLOCK LOAD_CONST COME_FROM_WITH
  1170. with_suffix
  1171. with_as ::= expr
  1172. SETUP_WITH store suite_stmts
  1173. POP_BLOCK LOAD_CONST COME_FROM_WITH
  1174. with_as ::= expr
  1175. SETUP_WITH store suite_stmts
  1176. POP_BLOCK BEGIN_FINALLY COME_FROM_WITH
  1177. with_suffix
  1178. # with_as ::= expr SETUP_WITH store suite_stmts
  1179. # COME_FROM expr COME_FROM POP_BLOCK ROT_TWO
  1180. # BEGIN_FINALLY WITH_CLEANUP_START WITH_CLEANUP_FINISH
  1181. # POP_FINALLY RETURN_VALUE COME_FROM_WITH
  1182. # WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY
  1183. with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK
  1184. BEGIN_FINALLY COME_FROM_WITH
  1185. with_suffix
  1186. """
  1187. self.addRule(rules_str, nop_func)
  1188. pass
  1189. return