full.py 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682
  1. # Copyright (c) 2017-2024 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. """
  16. spark grammar for Python 3.8 PyPy
  17. """
  18. from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
  19. from spark_parser.spark import rule2str
  20. from decompyle3.parsers.p37.full import Python37Parser
  21. from decompyle3.parsers.p38pypy.full_custom import Python38PyPyFullCustom
  22. from decompyle3.parsers.p38pypy.lambda_expr import Python38PyPyLambdaParser
  23. from decompyle3.parsers.parse_heads import ParserError
  24. from decompyle3.scanners.tok import Token
  25. class Python38PyPyParser(
  26. Python38PyPyLambdaParser, Python38PyPyFullCustom, Python37Parser
  27. ):
  28. def __init__(self, start_symbol: str = "stmts", debug_parser=PARSER_DEFAULT_DEBUG):
  29. Python38PyPyLambdaParser.__init__(self, start_symbol, debug_parser)
  30. self.customized = {}
  31. def customize_grammar_rules(self, tokens, customize):
  32. self.customize_grammar_rules_full38(tokens, customize)
  33. ###############################################
  34. # Python 3.8 grammar rules with statements
  35. ###############################################
  36. def p_38_full_if_ifelse(self, args):
  37. """
  38. # cf_pt introduced to keep indices the same in ifelsestmtc
  39. cf_pt ::= COME_FROM POP_TOP
  40. ifelsestmtc ::= testexpr c_stmts cf_pt else_suite
  41. # 3.8 can push a looping JUMP_LOOP into a JUMP_ from a statement that jumps to
  42. # it
  43. lastc_stmt ::= ifpoplaststmtc
  44. ifpoplaststmtc ::= testexpr POP_TOP c_stmts_opt
  45. ifelsestmtc ::= testexpr c_stmts_opt jb_cfs else_suitec JUMP_LOOP
  46. come_froms
  47. testtrue ::= or_in_ifexp POP_JUMP_IF_TRUE
  48. # The below ifelsetmtc is a really weird one for the inner if/else in:
  49. # if a:
  50. # while i:
  51. # if c:
  52. # j = j + 1
  53. # # A JUMP_LOOP is here...
  54. # else:
  55. # break
  56. # # but also a JUMP_LOOP is inserted here!
  57. # else:
  58. # j = 10
  59. ifelsestmtc ::= testexpr c_stmts_opt JUMP_LOOP else_suitec JUMP_LOOP
  60. """
  61. def p_38_full_stmt(self, args):
  62. """
  63. stmt ::= async_with_stmt38
  64. stmt ::= for38
  65. stmt ::= forelselaststmt38
  66. stmt ::= forelselaststmtc38
  67. stmt ::= forelsestmt38
  68. stmt ::= try_elsestmtl38
  69. stmt ::= try_except38
  70. stmt ::= try_except38r
  71. stmt ::= try_except38r2
  72. stmt ::= try_except38r3
  73. stmt ::= try_except38r4
  74. stmt ::= try_except38r5
  75. stmt ::= try_except38r6
  76. stmt ::= try_except38r7
  77. stmt ::= try_except_as
  78. stmt ::= try_except_ret38
  79. stmt ::= try_except_ret38a
  80. stmt ::= tryfinallystmt_break
  81. stmt ::= tryfinally38astmt
  82. stmt ::= tryfinally38rstmt
  83. stmt ::= tryfinally38rstmt2
  84. stmt ::= tryfinally38rstmt3
  85. stmt ::= tryfinally38rstmt4
  86. stmt ::= tryfinally38rstmt5
  87. stmt ::= tryfinally38stmt
  88. stmt ::= tryfinally38_return
  89. stmt ::= tryfinally38a_return
  90. stmt ::= tryfinally38rstmt2
  91. stmt ::= whileTruestmt38
  92. stmt ::= whilestmt38
  93. # FIXME: "break"" should be isolated to loops
  94. stmt ::= break
  95. break ::= POP_BLOCK BREAK_LOOP
  96. break ::= POP_BLOCK POP_TOP BREAK_LOOP
  97. break ::= POP_TOP BREAK_LOOP
  98. break ::= POP_EXCEPT BREAK_LOOP
  99. break ::= POP_TOP CONTINUE JUMP_LOOP
  100. # An except with nothing other than a single break
  101. break_except ::= POP_EXCEPT POP_TOP BREAK_LOOP
  102. # FIXME: this should be restricted to being inside a try block
  103. stmt ::= except_ret38
  104. stmt ::= except_ret38a
  105. async_with_stmt38 ::= expr
  106. BEFORE_ASYNC_WITH
  107. GET_AWAITABLE
  108. LOAD_CONST
  109. YIELD_FROM
  110. SETUP_ASYNC_WITH
  111. POP_TOP
  112. c_stmts_opt
  113. POP_BLOCK
  114. BEGIN_FINALLY
  115. COME_FROM_ASYNC_WITH
  116. WITH_CLEANUP_START
  117. GET_AWAITABLE
  118. LOAD_CONST
  119. YIELD_FROM
  120. WITH_CLEANUP_FINISH
  121. END_FINALLY
  122. async_with_stmt38 ::= expr
  123. BEFORE_ASYNC_WITH
  124. GET_AWAITABLE
  125. LOAD_CONST
  126. YIELD_FROM
  127. SETUP_ASYNC_WITH
  128. POP_TOP
  129. c_stmts_opt
  130. POP_BLOCK
  131. BEGIN_FINALLY
  132. WITH_CLEANUP_START
  133. GET_AWAITABLE
  134. LOAD_CONST
  135. YIELD_FROM
  136. WITH_CLEANUP_FINISH
  137. POP_FINALLY
  138. async_with_stmt38 ::= expr
  139. BEFORE_ASYNC_WITH
  140. GET_AWAITABLE
  141. LOAD_CONST
  142. YIELD_FROM
  143. SETUP_ASYNC_WITH
  144. POP_TOP
  145. c_stmts_opt
  146. POP_BLOCK
  147. BEGIN_FINALLY
  148. WITH_CLEANUP_START
  149. GET_AWAITABLE
  150. LOAD_CONST
  151. YIELD_FROM
  152. WITH_CLEANUP_FINISH
  153. POP_FINALLY
  154. JUMP_LOOP
  155. # Seems to be used to discard values before a return in a "for" loop
  156. discard_top ::= ROT_TWO POP_TOP
  157. discard_tops ::= discard_top+
  158. pop_tops ::= POP_TOP+
  159. return ::= return_expr
  160. discard_tops RETURN_VALUE
  161. return ::= pop_return
  162. return ::= popb_return
  163. return ::= pop_ex_return
  164. except_stmt ::= except_with_break
  165. except_stmt ::= except_with_break2
  166. except_stmt ::= pop_ex_return
  167. except_stmt ::= pop3_except_return38
  168. except_stmt ::= pop3_rot4_except_return38
  169. except_stmt ::= except_cond_pop3_rot4_except_return38
  170. except_stmts ::= except_stmt+
  171. except_stmts_opt ::= except_stmt*
  172. pop_return ::= POP_TOP return_expr RETURN_VALUE
  173. popb_return ::= return_expr POP_BLOCK RETURN_VALUE
  174. # Return from exception where value is on stack
  175. pop_ex_return ::= return_expr ROT_FOUR POP_EXCEPT RETURN_VALUE
  176. # Return from exception where value is no on stack but is computed
  177. pop_ex_return2 ::= POP_EXCEPT expr RETURN_VALUE
  178. # The below are 3.8 "except:" (no except condition)
  179. pop3_except_return38 ::= POP_TOP POP_TOP POP_TOP POP_EXCEPT POP_BLOCK
  180. CALL_FINALLY return
  181. except_return38 ::= POP_BLOCK
  182. CALL_FINALLY POP_TOP return
  183. pop3_rot4_except_return38 ::= POP_TOP POP_TOP POP_TOP
  184. except_stmts_opt return_expr ROT_FOUR
  185. POP_EXCEPT POP_BLOCK CALL_FINALLY RETURN_VALUE
  186. pop3_rot4_except_return38 ::= POP_TOP POP_TOP POP_TOP
  187. except_stmts_opt return_expr ROT_FOUR
  188. POP_EXCEPT POP_BLOCK ROT_TWO POP_TOP
  189. CALL_FINALLY RETURN_VALUE
  190. END_FINALLY COME_FROM POP_BLOCK
  191. BEGIN_FINALLY COME_FROM
  192. # The above but with an except condition name e.g. "except Exception:"
  193. except_cond_pop3_rot4_except_return38 ::= except_cond1
  194. except_stmts_opt return_expr ROT_FOUR
  195. POP_EXCEPT POP_BLOCK CALL_FINALLY RETURN_VALUE
  196. COME_FROM
  197. except_stmt ::= except_cond1 except_suite come_from_opt
  198. except_stmt ::= except_cond2 except_ret38b
  199. get_iter ::= expr GET_ITER
  200. for38 ::= expr get_iter store for_block JUMP_LOOP _come_froms
  201. for38 ::= expr get_for_iter store for_block JUMP_LOOP _come_froms
  202. for38 ::= expr get_for_iter store for_block JUMP_LOOP _come_froms
  203. POP_BLOCK
  204. for38 ::= expr get_for_iter store for_block _come_froms
  205. forelsestmt38 ::= expr get_for_iter store for_block POP_BLOCK else_suite
  206. _come_froms
  207. forelsestmt38 ::= expr get_for_iter store for_block JUMP_LOOP _come_froms
  208. else_suite _come_froms
  209. c_stmt ::= c_forelsestmt38
  210. c_stmt ::= pop_tops return
  211. c_forelsestmt38 ::= expr get_for_iter store for_block POP_BLOCK else_suitec
  212. c_forelsestmt38 ::= expr get_for_iter store for_block JUMP_LOOP _come_froms
  213. else_suitec
  214. # continue is a weird one. In 3.8, CONTINUE_LOOP was removed.
  215. # Inside an loop we can have this, which can only appear in side a try/except
  216. # And it can also appear at the end of the try except.
  217. continue ::= POP_EXCEPT JUMP_LOOP
  218. forelselaststmt38 ::= expr get_for_iter store for_block else_suitec
  219. _come_froms
  220. forelselaststmtc38 ::= expr get_for_iter store for_block else_suitec
  221. _come_froms
  222. # forelselaststmt38 ::= expr get_for_iter store for_block POP_BLOCK else_suitec
  223. # forelselaststmtc38 ::= expr get_for_iter store for_block POP_BLOCK else_suitec
  224. returns_in_except ::= _stmts except_return_value
  225. returns_in_except2 ::= _stmts except_return_value2
  226. except_return_value ::= POP_BLOCK return
  227. except_return_value ::= expr POP_BLOCK RETURN_VALUE
  228. except_return_value2 ::= POP_BLOCK return
  229. whilestmt38 ::= _come_froms testexpr c_stmts_opt COME_FROM JUMP_LOOP
  230. POP_BLOCK
  231. whilestmt38 ::= _come_froms testexpr c_stmts_opt JUMP_LOOP POP_BLOCK
  232. whilestmt38 ::= _come_froms testexpr c_stmts_opt JUMP_LOOP come_froms
  233. whilestmt38 ::= _come_froms testexprc c_stmts_opt come_froms JUMP_LOOP
  234. _come_froms
  235. whilestmt38 ::= _come_froms testexpr returns POP_BLOCK
  236. whilestmt38 ::= _come_froms testexpr c_stmts JUMP_LOOP _come_froms
  237. whilestmt38 ::= _come_froms testexpr c_stmts come_froms
  238. whilestmt38 ::= _come_froms bool_op c_stmts JUMP_LOOP _come_froms
  239. # while1elsestmt ::= c_stmts JUMP_LOOP
  240. whileTruestmt ::= _come_froms c_stmts JUMP_LOOP _come_froms
  241. POP_BLOCK
  242. while1stmt ::= _come_froms c_stmts COME_FROM_LOOP
  243. while1stmt ::= _come_froms c_stmts COME_FROM JUMP_LOOP COME_FROM_LOOP
  244. whileTruestmt38 ::= _come_froms c_stmts JUMP_LOOP _come_froms
  245. whileTruestmt38 ::= _come_froms c_stmts JUMP_LOOP COME_FROM_EXCEPT_CLAUSE
  246. whileTruestmt38 ::= _come_froms pass JUMP_LOOP
  247. for_block ::= _come_froms c_stmts_opt come_from_loops JUMP_LOOP
  248. # Note there is a 3.7 except_cond1 that doesn't have the final POP_EXCEPT
  249. except_cond1 ::= DUP_TOP expr COMPARE_OP POP_JUMP_IF_FALSE
  250. POP_TOP POP_TOP POP_TOP
  251. POP_EXCEPT
  252. except_suite ::= c_stmts_opt
  253. POP_EXCEPT POP_TOP JUMP_FORWARD POP_EXCEPT
  254. jump_except
  255. try_elsestmtl38 ::= SETUP_FINALLY suite_stmts_opt POP_BLOCK
  256. except_handler38 COME_FROM
  257. else_suitec opt_come_from_except
  258. try_except ::= SETUP_FINALLY suite_stmts_opt POP_BLOCK
  259. except_handler38
  260. try_except ::= SETUP_FINALLY suite_stmts_opt POP_BLOCK
  261. except_handler38
  262. jump_excepts
  263. come_from_except_clauses
  264. c_try_except ::= SETUP_FINALLY c_suite_stmts POP_BLOCK
  265. except_handler38
  266. c_stmt ::= c_tryfinallystmt38
  267. c_stmt ::= c_tryfinallybstmt38
  268. c_tryfinallystmt38 ::= SETUP_FINALLY c_suite_stmts_opt
  269. POP_BLOCK
  270. CALL_FINALLY
  271. POP_BLOCK
  272. POP_EXCEPT
  273. CALL_FINALLY
  274. JUMP_FORWARD
  275. POP_BLOCK BEGIN_FINALLY
  276. COME_FROM
  277. COME_FROM_FINALLY
  278. c_suite_stmts_opt END_FINALLY
  279. # try:
  280. # ..
  281. # break
  282. # finally:
  283. c_tryfinallybstmt38 ::= SETUP_FINALLY c_suite_stmts_opt
  284. POP_BLOCK
  285. CALL_FINALLY
  286. POP_BLOCK
  287. POP_EXCEPT
  288. CALL_FINALLY
  289. BREAK_LOOP
  290. POP_BLOCK BEGIN_FINALLY
  291. COME_FROM
  292. COME_FROM_FINALLY
  293. c_suite_stmts_opt END_FINALLY
  294. c_tryfinallystmt38 ::= SETUP_FINALLY c_suite_stmts_opt
  295. POP_BLOCK BEGIN_FINALLY COME_FROM COME_FROM_FINALLY
  296. c_suite_stmts_opt END_FINALLY
  297. try_except38 ::= SETUP_FINALLY POP_BLOCK POP_TOP suite_stmts_opt
  298. except_handler38a
  299. # suite_stmts has a return
  300. try_except38 ::= SETUP_FINALLY POP_BLOCK suite_stmts
  301. except_handler38b
  302. try_except38r ::= SETUP_FINALLY return_except
  303. except_handler38b
  304. return_except ::= stmts POP_BLOCK return
  305. # In 3.8 there seems to be some sort of code fiddle with POP_EXCEPT when there
  306. # is a final return in the "except" block.
  307. # So we treat the "return" separate from the other statements
  308. cond_except_stmt ::= except_cond1 except_stmts
  309. cond_except_stmts_opt ::= cond_except_stmt*
  310. try_except38r2 ::= SETUP_FINALLY
  311. suite_stmts_opt
  312. POP_BLOCK JUMP_FORWARD
  313. COME_FROM_FINALLY POP_TOP POP_TOP POP_TOP
  314. cond_except_stmts_opt
  315. POP_EXCEPT return
  316. END_FINALLY
  317. COME_FROM
  318. try_except38r3 ::= SETUP_FINALLY
  319. suite_stmts_opt
  320. POP_BLOCK JUMP_FORWARD
  321. COME_FROM_FINALLY
  322. cond_except_stmts_opt
  323. POP_EXCEPT return
  324. COME_FROM
  325. END_FINALLY
  326. COME_FROM
  327. # I think this can be combined with the r5
  328. try_except38r4 ::= SETUP_FINALLY
  329. returns_in_except
  330. COME_FROM_FINALLY
  331. except_cond1
  332. return
  333. COME_FROM
  334. END_FINALLY
  335. try_except38r5 ::= SETUP_FINALLY
  336. returns_in_except
  337. COME_FROM_FINALLY
  338. except_cond1
  339. except_ret38d
  340. COME_FROM
  341. END_FINALLY
  342. try_except38r5 ::= SETUP_FINALLY
  343. returns_in_except
  344. COME_FROM_FINALLY
  345. except_cond1
  346. except_suite
  347. COME_FROM
  348. END_FINALLY
  349. COME_FROM
  350. try_except38r5 ::= SETUP_FINALLY
  351. returns_in_except
  352. COME_FROM_FINALLY
  353. except_cond2
  354. except_ret38b
  355. END_FINALLY COME_FROM
  356. try_except38r6 ::= SETUP_FINALLY
  357. returns_in_except2
  358. COME_FROM_FINALLY
  359. POP_TOP POP_TOP POP_TOP
  360. except_ret38d
  361. END_FINALLY
  362. try_except38r7 ::= SETUP_FINALLY
  363. suite_stmts_opt
  364. POP_BLOCK JUMP_FORWARD
  365. COME_FROM_FINALLY POP_TOP POP_TOP POP_TOP
  366. return_expr
  367. ROT_FOUR POP_EXCEPT POP_BLOCK ROT_TWO POP_TOP
  368. CALL_FINALLY RETURN_VALUE
  369. END_FINALLY
  370. COME_FROM POP_BLOCK
  371. BEGIN_FINALLY
  372. COME_FROM
  373. COME_FROM_FINALLY
  374. try_except_as ::= SETUP_FINALLY POP_BLOCK suite_stmts
  375. except_handler_as END_FINALLY COME_FROM
  376. try_except_as ::= SETUP_FINALLY suite_stmts
  377. except_handler_as END_FINALLY COME_FROM
  378. try_except_ret38 ::= SETUP_FINALLY returns except_ret38a
  379. try_except_ret38a ::= SETUP_FINALLY returns except_handler38c
  380. END_FINALLY come_from_opt
  381. # Note: there is a suite_stmts_opt which seems
  382. # to be bookkeeping which is not expressed in source code
  383. except_ret38 ::= SETUP_FINALLY expr ROT_FOUR POP_BLOCK POP_EXCEPT
  384. CALL_FINALLY RETURN_VALUE COME_FROM
  385. COME_FROM_FINALLY
  386. suite_stmts_opt END_FINALLY
  387. except_ret38a ::= COME_FROM_FINALLY POP_TOP POP_TOP POP_TOP
  388. expr ROT_FOUR
  389. POP_EXCEPT RETURN_VALUE END_FINALLY
  390. except_ret38b ::= SETUP_FINALLY suite_stmts expr
  391. ROT_FOUR POP_BLOCK POP_EXCEPT
  392. CALL_FINALLY RETURN_VALUE COME_FROM
  393. COME_FROM_FINALLY
  394. suite_stmts_opt END_FINALLY
  395. POP_EXCEPT JUMP_FORWARD COME_FROM
  396. except_ret38c ::= SETUP_FINALLY suite_stmts expr
  397. ROT_FOUR POP_BLOCK POP_EXCEPT
  398. CALL_FINALLY POP_BLOCK CALL_FINALLY RETURN_VALUE
  399. COME_FROM
  400. COME_FROM_FINALLY
  401. expr STORE_FAST DELETE_FAST END_FINALLY
  402. POP_EXCEPT JUMP_FORWARD COME_FROM
  403. END_FINALLY come_any_froms
  404. except_ret38d ::= suite_stmts_opt
  405. expr ROT_FOUR
  406. POP_EXCEPT RETURN_VALUE
  407. except_handler38 ::= jump COME_FROM_FINALLY
  408. except_stmts
  409. END_FINALLY
  410. opt_come_from_except
  411. except_handler38a ::= COME_FROM_FINALLY POP_TOP POP_TOP POP_TOP
  412. POP_EXCEPT POP_TOP stmts END_FINALLY
  413. except_handler38b ::= COME_FROM_FINALLY POP_TOP POP_TOP POP_TOP
  414. POP_EXCEPT returns END_FINALLY
  415. except_handler38c ::= COME_FROM_FINALLY except_cond1 except_stmts
  416. COME_FROM
  417. except_handler38c ::= COME_FROM_FINALLY except_cond1 except_stmts
  418. POP_EXCEPT JUMP_FORWARD COME_FROM
  419. except_handler_as ::= COME_FROM_FINALLY except_cond2 tryfinallystmt
  420. POP_EXCEPT JUMP_FORWARD COME_FROM
  421. except ::= POP_TOP POP_TOP POP_TOP c_stmts_opt break
  422. POP_EXCEPT
  423. # Except of a try inside a loop
  424. except ::= POP_TOP POP_TOP POP_TOP c_stmts_opt break
  425. POP_EXCEPT JUMP_LOOP
  426. except ::= POP_TOP POP_TOP POP_TOP c_stmts_opt
  427. POP_EXCEPT JUMP_LOOP
  428. except_with_break ::= POP_TOP POP_TOP POP_TOP c_stmts break_except
  429. POP_EXCEPT JUMP_LOOP
  430. # Just except: break, no statements
  431. except_with_break2 ::= POP_TOP POP_TOP POP_TOP break_except
  432. POP_EXCEPT JUMP_LOOP
  433. except_with_return38 ::= POP_TOP POP_TOP POP_TOP stmts pop_ex_return2
  434. except_with_return38 ::= POP_TOP POP_TOP POP_TOP pop_ex_return2
  435. except_stmt ::= except_with_return38
  436. # In 3.8 any POP_EXCEPT comes before the "break" loop.
  437. # We should add a rule to check that JUMP_FORWARD is indeed a "break".
  438. break ::= POP_EXCEPT JUMP_FORWARD
  439. break ::= POP_BLOCK POP_TOP JUMP_FORWARD
  440. tryfinallystmt ::= SETUP_FINALLY suite_stmts_opt POP_BLOCK
  441. BEGIN_FINALLY COME_FROM_FINALLY suite_stmts_opt
  442. END_FINALLY
  443. tryfinallystmt_break ::=
  444. SETUP_FINALLY suite_stmts_opt POP_BLOCK POP_EXCEPT
  445. CALL_FINALLY
  446. JUMP_FORWARD POP_BLOCK
  447. BEGIN_FINALLY COME_FROM COME_FROM_FINALLY suite_stmts_opt
  448. END_FINALLY
  449. lc_setup_finally ::= LOAD_CONST SETUP_FINALLY
  450. call_finally_pt ::= CALL_FINALLY POP_TOP
  451. cf_cf_finally ::= come_from_opt COME_FROM_FINALLY
  452. pop_finally_pt ::= POP_FINALLY POP_TOP
  453. ss_end_finally ::= suite_stmts END_FINALLY
  454. sf_pb_call_returns ::= SETUP_FINALLY POP_BLOCK CALL_FINALLY returns
  455. sf_pb_call_returns ::= SETUP_FINALLY POP_BLOCK POP_EXCEPT CALL_FINALLY returns
  456. suite_stmts_return ::= suite_stmts expr
  457. suite_stmts_return ::= expr
  458. # FIXME: DRY rules below
  459. tryfinally38rstmt ::= sf_pb_call_returns
  460. cf_cf_finally
  461. ss_end_finally
  462. tryfinally38rstmt ::= sf_pb_call_returns
  463. cf_cf_finally END_FINALLY
  464. suite_stmts
  465. tryfinally38rstmt ::= sf_pb_call_returns
  466. cf_cf_finally POP_FINALLY
  467. ss_end_finally
  468. tryfinally38rstmt ::= sf_pb_call_returns
  469. COME_FROM_FINALLY POP_FINALLY
  470. ss_end_finally
  471. tryfinally38rstmt2 ::= lc_setup_finally POP_BLOCK call_finally_pt
  472. returns
  473. cf_cf_finally pop_finally_pt
  474. ss_end_finally POP_TOP
  475. tryfinally38rstmt3 ::= SETUP_FINALLY expr POP_BLOCK CALL_FINALLY RETURN_VALUE
  476. COME_FROM COME_FROM_FINALLY
  477. ss_end_finally
  478. tryfinally38rstmt4 ::= lc_setup_finally suite_stmts_opt POP_BLOCK
  479. BEGIN_FINALLY COME_FROM_FINALLY
  480. suite_stmts_return
  481. POP_FINALLY ROT_TWO POP_TOP
  482. RETURN_VALUE
  483. END_FINALLY POP_TOP
  484. tryfinally38rstmt5 ::= lc_setup_finally try_except38r7 expr
  485. POP_FINALLY ROT_TWO POP_TOP
  486. RETURN_VALUE
  487. END_FINALLY POP_TOP
  488. tryfinally38stmt ::= SETUP_FINALLY suite_stmts_opt POP_BLOCK
  489. BEGIN_FINALLY COME_FROM_FINALLY
  490. POP_FINALLY suite_stmts_opt END_FINALLY
  491. tryfinally38stmt ::= SETUP_FINALLY suite_stmts_opt POP_BLOCK
  492. BEGIN_FINALLY COME_FROM
  493. COME_FROM_FINALLY
  494. suite_stmts_opt END_FINALLY
  495. # try: .. finally: ending with return ...
  496. tryfinally38_return ::= SETUP_FINALLY suite_stmts_opt POP_BLOCK
  497. JUMP_FORWARD
  498. COME_FROM_FINALLY except_cond2 except_ret38c
  499. tryfinally38a_return ::= LOAD_CONST SETUP_FINALLY suite_stmts_opt except_return38
  500. COME_FROM COME_FROM_FINALLY
  501. suite_stmts_opt pop_finally_pt return
  502. END_FINALLY POP_TOP
  503. tryfinally38astmt ::= LOAD_CONST SETUP_FINALLY suite_stmts_opt POP_BLOCK
  504. BEGIN_FINALLY COME_FROM_FINALLY
  505. POP_FINALLY POP_TOP suite_stmts_opt END_FINALLY POP_TOP
  506. """
  507. def p_38_full_walrus(self, args):
  508. """
  509. # named_expr is also known as the "walrus op" :=
  510. expr ::= named_expr
  511. named_expr ::= expr DUP_TOP store
  512. """
  513. # FIXME: try this
  514. def reduce_is_invalid(self, rule, ast, tokens, first, last):
  515. lhs = rule[0]
  516. if lhs == "call_kw":
  517. # Make sure we don't derive call_kw
  518. nt = ast[0]
  519. while not isinstance(nt, Token):
  520. if nt[0] == "call_kw":
  521. return True
  522. nt = nt[0]
  523. pass
  524. pass
  525. n = len(tokens)
  526. last = min(last, n - 1)
  527. fn = self.reduce_check_table.get(lhs, None)
  528. try:
  529. if fn:
  530. return fn(self, lhs, n, rule, ast, tokens, first, last)
  531. except Exception:
  532. import sys
  533. import traceback
  534. print(
  535. f"Exception in {fn.__name__} {sys.exc_info()[1]}\n"
  536. + f"rule: {rule2str(rule)}\n"
  537. + f"offsets {tokens[first].offset} .. {tokens[last].offset}"
  538. )
  539. print(traceback.print_tb(sys.exc_info()[2], -1))
  540. raise ParserError(tokens[last], tokens[last].off2int(), self.debug["rules"])
  541. if lhs in ("aug_assign1", "aug_assign2") and ast[0][0] == "and":
  542. return True
  543. elif lhs == "annotate_tuple":
  544. return not isinstance(tokens[first].attr, tuple)
  545. elif lhs == "import_from37":
  546. importlist37 = ast[3]
  547. alias37 = importlist37[0]
  548. if importlist37 == "importlist37" and alias37 == "alias37":
  549. store = alias37[1]
  550. assert store == "store"
  551. return alias37[0].attr != store[0].attr
  552. return False
  553. return False
  554. return False
  555. if __name__ == "__main__":
  556. # Check grammar
  557. from decompyle3.parsers.dump import dump_and_check
  558. p = Python38PyPyParser()
  559. modified_tokens = set(
  560. """JUMP_LOOP CONTINUE RETURN_END_IF COME_FROM
  561. LOAD_GENEXPR LOAD_ASSERT LOAD_SETCOMP LOAD_DICTCOMP LOAD_CLASSNAME
  562. LAMBDA_MARKER RETURN_LAST
  563. """.split()
  564. )
  565. dump_and_check(p, (3, 8), modified_tokens)