full.py 29 KB

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