full.py 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989
  1. # Copyright (c) 2020-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.7
  17. """
  18. from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
  19. from decompyle3.parsers.p37.lambda_expr import Python37LambdaParser
  20. class Python37Parser(Python37LambdaParser):
  21. def __init__(self, start_symbol: str = "stmts", debug_parser=PARSER_DEFAULT_DEBUG):
  22. super(Python37Parser, self).__init__(start_symbol, debug_parser)
  23. self.customized = {}
  24. ###############################################
  25. # Python 3.7 grammar rules with statements
  26. ###############################################
  27. def p_start37(self, args):
  28. """
  29. # The start or goal symbol
  30. stmts ::= sstmt+
  31. """
  32. def p_eval_mode(self, args):
  33. """
  34. # eval-mode compilation. Single-mode interactive compilation
  35. # adds another rule.
  36. expr_stmt ::= expr POP_TOP
  37. """
  38. def p_stmt_loop(self, args):
  39. """
  40. #########################################################
  41. # Higher-level rules for statements in some sort of loop.
  42. #
  43. # Loops allow "continue" and "break" at the Python level.
  44. # At the bytecode level, there are backward jumps.
  45. #
  46. # Productions that can appear outside of
  47. # loop should be derivable from inside a loop, but
  48. # not necessarily vice versa, such as for "BREAK"
  49. # and "CONTINUE" (pseudo or real) instructions.
  50. #
  51. # Nonterminal names that start "c_" or end in "c", indicates
  52. # rule that can only to appear in a loop.
  53. # (The "c" stands for "continue". It is
  54. # a little bit historical. "l" was considered but can
  55. # be confused with "last".)
  56. #
  57. #########################################################
  58. c_stmts ::= _stmts
  59. c_stmts ::= _stmts lastc_stmt
  60. c_stmts ::= lastc_stmt
  61. c_stmts ::= continues
  62. c_stmts ::= c_stmt+
  63. c_stmts ::= c_returns
  64. # Additional statements that *must* be in a loop
  65. c_stmt ::= break
  66. c_stmt ::= continue
  67. # If statement inside a loop. The RHS may have looping jumps in them.
  68. c_stmt ::= ifstmtc
  69. c_stmt ::= if_not_stmtc
  70. c_stmt ::= if_and_elsestmtc
  71. c_stmt ::= ifelsestmtc
  72. c_stmt ::= c_tryfinallystmt
  73. c_stmt ::= c_try_except
  74. c_stmt ::= c_try_except36
  75. c_stmt ::= stmt
  76. c_stmts_opt ::= c_stmts
  77. c_stmts_opt ::= pass
  78. else_suitec ::= c_stmts
  79. else_suitec ::= c_returns
  80. else_suitec ::= suite_stmts
  81. c_suite_stmts ::= c_stmts
  82. c_suite_stmts ::= suite_stmts
  83. c_suite_stmts_opt ::= c_suite_stmts
  84. c_suite_stmts_opt ::= suite_stmts_opt
  85. c_returns ::= c_stmts return
  86. c_returns ::= returns
  87. c_except ::= POP_TOP POP_TOP POP_TOP c_stmts_opt POP_EXCEPT jump
  88. c_except ::= POP_TOP POP_TOP POP_TOP c_returns
  89. # FIXME regularize name c_last_stmt, etc.
  90. # Do we really need these?
  91. lastc_stmt ::= forelselaststmtc
  92. lastc_stmt ::= iflaststmtc
  93. # FIXME: Do we need these?
  94. lastc_stmt ::= ifelsestmtc
  95. lastc_stmt ::= tryelsestmtc
  96. """
  97. def p_stmt(self, args):
  98. """
  99. pass ::=
  100. stmts_opt ::= stmts
  101. stmts_opt ::= pass
  102. stmts ::= stmt+
  103. stmts ::= stmts last_stmt
  104. _stmts ::= stmts
  105. suite_stmts ::= _stmts
  106. suite_stmts ::= returns
  107. suite_stmts_opt ::= suite_stmts
  108. # passtmt is needed for semantic actions to add "pass"
  109. suite_stmts_opt ::= pass
  110. else_suite_opt ::= else_suite
  111. else_suite_opt ::= pass
  112. else_suite ::= suite_stmts
  113. else_suite ::= returns
  114. stmt ::= classdef
  115. stmt ::= expr_stmt
  116. stmt ::= ifstmt
  117. stmt ::= if_or_stmt
  118. stmt ::= if_and_stmt
  119. stmt ::= ifelsestmt
  120. stmt ::= if_or_not_elsestmt
  121. stmt ::= whilestmt
  122. stmt ::= while1stmt
  123. stmt ::= whileelsestmt
  124. stmt ::= while1elsestmt
  125. stmt ::= for
  126. stmt ::= forelsestmt
  127. stmt ::= try_except
  128. stmt ::= tryelsestmt
  129. stmt ::= tryfinallystmt
  130. stmt ::= last_stmt
  131. stmt ::= dict_comp_func
  132. stmt ::= set_comp_func
  133. # last_stmt is a Python statement for which
  134. # end is a "return" or raise statement and
  135. # therefore may not have a COME_FROM after
  136. # it. It does *not* have to be the last stmt of
  137. # a list of stmts or c_stmts
  138. last_stmt ::= forelselaststmt
  139. last_stmt ::= iflaststmt
  140. stmt ::= delete
  141. delete ::= DELETE_FAST
  142. delete ::= DELETE_NAME
  143. delete ::= DELETE_GLOBAL
  144. stmt ::= return
  145. # "returns" nonterminal is a sequence of statements that ends in a RETURN statement.
  146. # In later Python versions with jump optimization, this can cause JUMPs
  147. # that would normally appear to be omitted.
  148. returns ::= return
  149. returns ::= _stmts return
  150. stmt ::= genexpr_func
  151. """
  152. pass
  153. # # A "condition", in contrast to an "expr"ession ,is something that is is used in
  154. # # tests and pops the condition after testing
  155. # def p_if_conditions(self, args):
  156. # """
  157. # condition ::= and_or_cond
  158. # condition ::= nor_cond
  159. # condition ::= or_cond
  160. # stmt ::= if_cond_stmt
  161. # if_cond_stmt ::= condition stmt
  162. # if_cond_else_stmt ::= condition
  163. # """
  164. def p_function_def(self, args):
  165. """
  166. stmt ::= function_def
  167. function_def ::= mkfunc store
  168. stmt ::= function_def_deco
  169. function_def_deco ::= mkfuncdeco store
  170. mkfuncdeco ::= expr mkfuncdeco CALL_FUNCTION_1
  171. mkfuncdeco ::= expr mkfuncdeco0 CALL_FUNCTION_1
  172. mkfuncdeco0 ::= mkfunc
  173. load_closure ::= load_closure LOAD_CLOSURE
  174. load_closure ::= LOAD_CLOSURE
  175. """
  176. def p_augmented_assign(self, args):
  177. """
  178. stmt ::= aug_assign1
  179. stmt ::= aug_assign2
  180. # This is odd in that other aug_assign1's have only 3 slots
  181. # The store isn't used as that's supposed to be also
  182. # indicated in the first expr
  183. aug_assign1 ::= expr expr
  184. inplace_op store
  185. aug_assign1 ::= expr expr
  186. inplace_op ROT_THREE STORE_SUBSCR
  187. aug_assign2 ::= expr DUP_TOP LOAD_ATTR expr
  188. inplace_op ROT_TWO STORE_ATTR
  189. inplace_op ::= INPLACE_ADD
  190. inplace_op ::= INPLACE_SUBTRACT
  191. inplace_op ::= INPLACE_MULTIPLY
  192. inplace_op ::= INPLACE_TRUE_DIVIDE
  193. inplace_op ::= INPLACE_FLOOR_DIVIDE
  194. inplace_op ::= INPLACE_MODULO
  195. inplace_op ::= INPLACE_POWER
  196. inplace_op ::= INPLACE_LSHIFT
  197. inplace_op ::= INPLACE_RSHIFT
  198. inplace_op ::= INPLACE_AND
  199. inplace_op ::= INPLACE_XOR
  200. inplace_op ::= INPLACE_OR
  201. """
  202. def p_assign(self, args):
  203. """
  204. stmt ::= assign
  205. assign ::= expr DUP_TOP designList
  206. assign ::= expr store
  207. stmt ::= assign2
  208. stmt ::= assign3
  209. assign2 ::= expr expr ROT_TWO store store
  210. assign3 ::= expr expr expr ROT_THREE ROT_TWO store store store
  211. """
  212. def p_await(self, args):
  213. # Python 3.5+ Await things
  214. """
  215. # Can move this after have a p37/full_custom.py
  216. stmt ::= await_stmt
  217. await_stmt ::= await_expr POP_TOP
  218. """
  219. def p_for_loop(self, args):
  220. """
  221. setup_loop ::= SETUP_LOOP _come_froms
  222. for ::= setup_loop expr get_for_iter store for_block
  223. POP_BLOCK
  224. for ::= setup_loop expr get_for_iter store for_block
  225. POP_BLOCK COME_FROM_LOOP
  226. # FIXME: investigate - can code really produce a NOP?
  227. for ::= setup_loop expr get_for_iter store for_block POP_BLOCK NOP
  228. COME_FROM_LOOP
  229. come_from_loops ::= COME_FROM_LOOP*
  230. for_block ::= c_stmts_opt COME_FROM_LOOP JUMP_LOOP
  231. for_block ::= c_stmts_opt _come_froms JUMP_LOOP
  232. for_block ::= c_stmts_opt come_from_loops JUMP_LOOP
  233. for_block ::= c_stmts
  234. for_block ::= c_stmts JUMP_LOOP
  235. forelsestmt ::= SETUP_LOOP expr get_for_iter store
  236. for_block POP_BLOCK else_suite _come_froms
  237. forelsestmt ::= setup_loop expr get_for_iter store for_block POP_BLOCK else_suitec
  238. forelsestmt ::= setup_loop expr get_for_iter store for_block POP_BLOCK else_suite
  239. COME_FROM_LOOP
  240. forelselaststmt ::= SETUP_LOOP expr get_for_iter store
  241. for_block POP_BLOCK else_suitec _come_froms
  242. forelselaststmt ::= setup_loop expr get_for_iter store for_block POP_BLOCK else_suitec
  243. COME_FROM_LOOP
  244. forelselaststmtc ::= SETUP_LOOP expr get_for_iter store
  245. for_block POP_BLOCK else_suitec _come_froms
  246. """
  247. def p_whilestmt(self, args):
  248. """
  249. while1elsestmt ::= setup_loop c_stmts JUMP_LOOP POP_BLOCK else_suite COME_FROM_LOOP
  250. while1elsestmt ::= setup_loop c_stmts JUMP_LOOP _come_froms POP_BLOCK else_suitec COME_FROM_LOOP
  251. while1elsestmt ::= setup_loop c_stmts JUMP_LOOP else_suite COME_FROM_LOOP
  252. while1elsestmt ::= setup_loop c_stmts JUMP_LOOP else_suitec
  253. # FIXME: Python 3.? starts adding branch optimization? Put this starting there.
  254. while1stmt ::= setup_loop c_stmts _come_froms JUMP_LOOP
  255. COME_FROM_LOOP
  256. while1stmt ::= setup_loop c_stmts _come_froms JUMP_LOOP POP_BLOCK
  257. COME_FROM_LOOP
  258. while1stmt ::= setup_loop c_stmts COME_FROM_LOOP
  259. while1stmt ::= setup_loop c_stmts COME_FROM_LOOP JUMP_LOOP POP_BLOCK
  260. COME_FROM_LOOP
  261. while1stmt ::= setup_loop c_stmts POP_BLOCK
  262. COME_FROM_LOOP
  263. whileTruestmt ::= SETUP_LOOP c_stmts_opt JUMP_LOOP COME_FROM_LOOP
  264. whileTruestmt ::= setup_loop c_stmts_opt JUMP_LOOP POP_BLOCK _come_froms
  265. # FIXME the below masks a bug in not detecting COME_FROM_LOOP
  266. # grammar rules with COME_FROM -> COME_FROM_LOOP already exist
  267. whileelsestmt ::= setup_loop testexpr c_stmts_opt
  268. JUMP_LOOP POP_BLOCK
  269. else_suite COME_FROM
  270. whileelsestmt ::= setup_loop testexpr c_stmts_opt
  271. JUMP_LOOP POP_BLOCK
  272. else_suite COME_FROM_LOOP
  273. # There is no JUMP_LOOP here because c_stmts contineus, returns, or breaks
  274. whileelsestmt ::= setup_loop testexpr
  275. c_stmts come_froms POP_BLOCK
  276. else_suite COME_FROM_LOOP
  277. whilestmt ::= setup_loop testexprc c_stmts_opt COME_FROM JUMP_LOOP POP_BLOCK COME_FROM_LOOP
  278. whilestmt ::= setup_loop testexprc c_stmts_opt JUMP_LOOP POP_BLOCK COME_FROM_LOOP
  279. # We can be missing a COME_FROM_LOOP if the "while" statement is nested inside an if/else
  280. # so after the POP_BLOCK we have a JUMP_FORWARD which forms the "else" portion of the "if"
  281. # This is undoubtedly some sort of JUMP optimization going on.
  282. # We have a reduction check for this peculiar case.
  283. whilestmt ::= setup_loop testexpr c_stmts_opt JUMP_LOOP come_froms POP_BLOCK
  284. whilestmt ::= setup_loop testexpr c_stmts_opt JUMP_LOOP come_froms POP_BLOCK COME_FROM_LOOP
  285. whilestmt ::= setup_loop testexpr c_stmts_opt come_froms JUMP_LOOP come_froms POP_BLOCK COME_FROM_LOOP
  286. whilestmt ::= setup_loop testexpr c_stmts_opt come_froms POP_BLOCK COME_FROM_LOOP
  287. whilestmt ::= setup_loop testexpr returns POP_BLOCK COME_FROM_LOOP
  288. whilestmt ::= setup_loop testexpr returns come_froms POP_BLOCK COME_FROM_LOOP
  289. """
  290. def p_import20(self, args):
  291. """
  292. stmt ::= import
  293. stmt ::= import_from
  294. stmt ::= import_from_star
  295. stmt ::= importmultiple
  296. importlist ::= importlist alias
  297. importlist ::= alias
  298. alias ::= IMPORT_NAME store
  299. alias ::= IMPORT_FROM store
  300. alias ::= IMPORT_NAME attributes store
  301. import ::= LOAD_CONST LOAD_CONST alias
  302. import_from_star ::= LOAD_CONST LOAD_CONST IMPORT_NAME IMPORT_STAR
  303. import_from_star ::= LOAD_CONST LOAD_CONST IMPORT_NAME_ATTR IMPORT_STAR
  304. import_from ::= LOAD_CONST LOAD_CONST IMPORT_NAME importlist POP_TOP
  305. importmultiple ::= LOAD_CONST LOAD_CONST alias imports_cont
  306. imports_cont ::= import_cont+
  307. import_cont ::= LOAD_CONST LOAD_CONST alias
  308. attributes ::= LOAD_ATTR+
  309. """
  310. def p_import37(self, args):
  311. """
  312. # The 3.7base scanner adds IMPORT_NAME_ATTR
  313. alias ::= IMPORT_NAME_ATTR attributes store
  314. alias ::= IMPORT_NAME_ATTR store
  315. alias37 ::= IMPORT_NAME store
  316. alias37 ::= IMPORT_FROM store
  317. import_as37 ::= LOAD_CONST LOAD_CONST importlist37 store POP_TOP
  318. import_from ::= LOAD_CONST LOAD_CONST importlist POP_TOP
  319. import_from37 ::= LOAD_CONST LOAD_CONST IMPORT_NAME_ATTR importlist37 POP_TOP
  320. import_from_as37 ::= LOAD_CONST LOAD_CONST import_from_attr37 store POP_TOP
  321. # A single entry in a dotted import a.b.c.d
  322. import_one ::= importlists ROT_TWO IMPORT_FROM
  323. import_one ::= importlists ROT_TWO POP_TOP IMPORT_FROM
  324. # Semantic checks distinguish importattr37 from import_from_attr37
  325. # in the former the "from" slot in a prior LOAD_CONST is null.
  326. # Used in: import .. as ..
  327. importattr37 ::= IMPORT_NAME_ATTR IMPORT_FROM
  328. # Used in: from xx import .. as ..
  329. import_from_attr37 ::= IMPORT_NAME_ATTR IMPORT_FROM
  330. importlist37 ::= import_one
  331. importlist37 ::= importattr37
  332. importlist37 ::= alias37+
  333. importlists ::= importlist37+
  334. stmt ::= import_as37
  335. stmt ::= import_from37
  336. stmt ::= import_from_as37
  337. """
  338. def p_32on(self, args):
  339. """
  340. # Python 3.5+ has jump optimization to remove the redundant
  341. # jump_excepts. But in 3.3 we need them added
  342. except_handler ::= JUMP_FORWARD COME_FROM_EXCEPT except_stmts
  343. END_FINALLY
  344. tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
  345. except_handler else_suite
  346. jump_excepts come_from_except_clauses
  347. jump_excepts ::= jump_except+
  348. kv3 ::= expr expr STORE_MAP
  349. """
  350. return
  351. def p_35_on(self, args):
  352. """
  353. inplace_op ::= INPLACE_MATRIX_MULTIPLY
  354. # FIXME: do we need these?
  355. return_expr ::= expr
  356. return_if_stmt ::= return_expr RETURN_END_IF POP_BLOCK
  357. jb_cf ::= JUMP_LOOP COME_FROM
  358. ifelsestmtc ::= testexpr c_stmts_opt JUMP_FORWARD else_suitec
  359. # We want to keep the positions of the "then" and
  360. # "else" statements in "ifelstmtl" similar to others of this ilk.
  361. testexpr_cf ::= testexpr come_froms
  362. ifelsestmtc ::= testexpr_cf c_stmts_opt jb_cf else_suitec
  363. iflaststmt ::= testexpr stmts_opt JUMP_FORWARD
  364. """
  365. def p_37_async(self, args):
  366. """
  367. stmt ::= async_for_stmt37
  368. stmt ::= async_for_stmt
  369. stmt ::= async_for_stmt2
  370. stmt ::= async_forelse_stmt
  371. # FIXME: DRY this with rules.
  372. async_for_stmt ::= setup_loop expr
  373. GET_AITER
  374. _come_froms
  375. SETUP_EXCEPT GET_ANEXT LOAD_CONST
  376. YIELD_FROM
  377. store
  378. POP_BLOCK JUMP_FORWARD COME_FROM_EXCEPT DUP_TOP
  379. LOAD_GLOBAL COMPARE_OP POP_JUMP_IF_TRUE
  380. END_FINALLY COME_FROM
  381. for_block
  382. COME_FROM
  383. POP_TOP POP_TOP POP_TOP POP_EXCEPT POP_TOP POP_BLOCK
  384. opt_come_from_loop
  385. async_for_stmt2 ::= setup_loop expr
  386. GET_AITER
  387. _come_froms
  388. LOAD_CONST YIELD_FROM SETUP_EXCEPT GET_ANEXT LOAD_CONST
  389. YIELD_FROM
  390. store
  391. POP_BLOCK JUMP_FORWARD COME_FROM_EXCEPT DUP_TOP
  392. LOAD_GLOBAL COMPARE_OP POP_JUMP_IF_FALSE
  393. POP_TOP POP_TOP POP_TOP POP_EXCEPT POP_BLOCK
  394. JUMP_ABSOLUTE END_FINALLY COME_FROM
  395. for_block POP_BLOCK
  396. opt_come_from_loop
  397. # Order of LOAD_CONST YIELD_FROM is switched from 3.6 to save a LOAD_CONST
  398. async_for_stmt37 ::= setup_loop expr
  399. GET_AITER
  400. _come_froms
  401. SETUP_EXCEPT GET_ANEXT
  402. LOAD_CONST YIELD_FROM
  403. store
  404. POP_BLOCK JUMP_LOOP COME_FROM_EXCEPT DUP_TOP
  405. LOAD_GLOBAL COMPARE_OP POP_JUMP_IF_TRUE
  406. END_FINALLY
  407. for_block COME_FROM
  408. POP_TOP POP_TOP POP_TOP POP_EXCEPT
  409. POP_TOP POP_BLOCK
  410. COME_FROM_LOOP
  411. async_forelse_stmt ::= setup_loop expr
  412. GET_AITER
  413. _come_froms
  414. SETUP_EXCEPT GET_ANEXT LOAD_CONST
  415. YIELD_FROM
  416. store
  417. POP_BLOCK JUMP_FORWARD COME_FROM_EXCEPT DUP_TOP
  418. LOAD_GLOBAL COMPARE_OP POP_JUMP_IF_TRUE
  419. END_FINALLY COME_FROM
  420. for_block
  421. COME_FROM
  422. POP_TOP POP_TOP POP_TOP POP_EXCEPT POP_TOP POP_BLOCK
  423. else_suite COME_FROM_LOOP
  424. """
  425. def p_grammar(self, args):
  426. """sstmt ::= stmt
  427. sstmt ::= ifelsestmtr
  428. sstmt ::= return RETURN_LAST
  429. return_if_stmts ::= return_if_stmt come_from_opt
  430. return_if_stmts ::= _stmts return_if_stmt _come_froms
  431. return_if_stmt ::= return_expr RETURN_END_IF
  432. returns ::= _stmts return_if_stmt
  433. break ::= BREAK_LOOP
  434. continue ::= CONTINUE
  435. continues ::= _stmts lastc_stmt continue
  436. continues ::= lastc_stmt continue
  437. continues ::= continue
  438. kwarg ::= LOAD_STR expr
  439. kwargs ::= kwarg+
  440. classdef ::= build_class store
  441. # FIXME: we need to add these because don't detect this properly
  442. # in custom rules. Specifically if one of the exprs is CALL_FUNCTION
  443. # then we'll mistake that for the final CALL_FUNCTION.
  444. # We can fix by triggering on the CALL_FUNCTION op
  445. # Python3 introduced LOAD_BUILD_CLASS
  446. # Other definitions are in a custom rule
  447. build_class ::= LOAD_BUILD_CLASS mkfunc expr call CALL_FUNCTION_3
  448. build_class ::= LOAD_BUILD_CLASS mkfunc expr call expr CALL_FUNCTION_4
  449. stmt ::= classdefdeco
  450. classdefdeco ::= classdefdeco1 store
  451. # Some LOAD_GLOBALs we don't convert to LOAD_ASSERT because
  452. # of the intevening "expr CALL_FUNCTION1" which can be an arbitrary number
  453. # of instructions
  454. assert2 ::= expr
  455. POP_JUMP_IF_TRUE LOAD_GLOBAL expr CALL_FUNCTION_1 RAISE_VARARGS_1
  456. assert2_not ::= expr
  457. POP_JUMP_IF_FALSE LOAD_GLOBAL expr CALL_FUNCTION_1 RAISE_VARARGS_1
  458. # "assert_invert" tests on the negative of the condition given
  459. stmt ::= assert_invert
  460. assert_invert ::= testtrue LOAD_GLOBAL RAISE_VARARGS_1
  461. expr ::= LOAD_ASSERT
  462. pop_jump ::= POP_JUMP_IF_TRUE
  463. pop_jump ::= POP_JUMP_IF_FALSE
  464. # These rules need reduce checks on the "_come_froms".
  465. # When the come_from is empty the end of the "then"
  466. # can't fall through. And when the "_come_froms" aren't
  467. # empty they have to be reasonable, e.g. testexpr has to
  468. # jump to one of the COME_FROMS
  469. ifstmt ::= testexpr stmts _come_froms
  470. ifstmt ::= bool_op stmts _come_froms
  471. ifstmt ::= testexpr ifstmts_jump _come_froms
  472. stmt ::= ifstmt_bool
  473. ifstmt_bool ::= or_and_not stmts come_froms
  474. ifstmt_bool ::= or_and1 stmts come_froms
  475. ifstmt_bool ::= not_and_not stmts come_froms
  476. if_or_stmt ::= expr POP_JUMP_IF_TRUE expr pop_jump come_froms
  477. stmts COME_FROM
  478. if_and_stmt ::= expr_pjif expr COME_FROM
  479. stmts _come_froms
  480. if_and_elsestmtc ::= expr_pjif
  481. expr_pjif
  482. c_stmts jb_cfs else_suitec opt_come_from_except
  483. if_or_not_elsestmt ::= expr POP_JUMP_IF_TRUE
  484. come_from_opt expr POP_JUMP_IF_TRUE come_froms
  485. stmts jf_cfs else_suite opt_come_from_except
  486. testexpr ::= testfalse
  487. testexpr ::= testtrue
  488. testexpr ::= or_and_not
  489. testfalse ::= expr_pjif
  490. testfalsec ::= expr POP_JUMP_IF_TRUE_LOOP
  491. testfalsec ::= c_compare_chained_middleb_false_37
  492. testtrue ::= expr_pjit
  493. testtruec ::= expr POP_JUMP_IF_FALSE_LOOP
  494. # Do we have to check the c_compare_chained37 ends in a POP_JUMP_IF_FALSE_LOOP?
  495. testtruec ::= c_compare_chained37_false
  496. testtruec ::= c_compare_chained37
  497. testtruec ::= c_nand
  498. testtrue ::= compare_chained37
  499. testtrue ::= compare_chained_and
  500. testtrue ::= nor_cond
  501. testfalse ::= and_not
  502. testfalse ::= not_or
  503. testfalse ::= compare_chained37_false
  504. testfalse ::= or_cond
  505. testfalse ::= or_cond1
  506. testfalse ::= and_or_cond
  507. ifstmts_jump ::= return_if_stmts
  508. ifstmts_jump ::= stmts_opt come_froms
  509. ifstmts_jump ::= COME_FROM stmts COME_FROM
  510. # Python 3.4+ optimizes the trailing two JUMPS away
  511. ifstmts_jump ::= stmts_opt JUMP_FORWARD JUMP_FORWARD _come_froms
  512. # For "iflaststmt" there is a rule check for the below that the end of
  513. # "stmts" doesn't fall through.
  514. iflaststmt ::= testexpr stmts
  515. iflaststmt ::= testexpr returns
  516. iflaststmt ::= testexpr stmts JUMP_FORWARD
  517. iflaststmtc ::= testexpr c_stmts
  518. iflaststmtc ::= testexpr c_stmts JUMP_LOOP
  519. iflaststmtc ::= testexpr c_stmts JUMP_LOOP COME_FROM_LOOP
  520. iflaststmtc ::= testexpr c_stmts JUMP_LOOP POP_BLOCK
  521. # c_stmts might terminate, or have "continue" so no JUMP_LOOP.
  522. # But if that's true, the "testexpr" needs still to jump to the "COME_FROM'
  523. iflaststmtc ::= testexpr c_stmts come_froms
  524. # Note: in if/else kinds of statements, we err on the side
  525. # of missing "else" clauses. Therefore we include grammar
  526. # rules with and without ELSE.
  527. ifelsestmt ::= testexpr
  528. stmts_opt jf_cfs else_suite_opt opt_come_from_except
  529. ifelsestmt ::= bool_op
  530. stmts_opt jf_cfs else_suite_opt opt_come_from_except
  531. ifelsestmtc ::= testexpr
  532. c_stmts_opt jump_forward_else
  533. else_suitec opt_come_from_except
  534. ifelsestmtc ::= testexpr
  535. c_stmts_opt cf_jump_back
  536. else_suitec
  537. # This handles the case where a "JUMP_ABSOLUTE" is part
  538. # of an inner if in c_stmts_opt
  539. ifelsestmtc ::= testexpr c_stmts come_froms
  540. else_suite
  541. ifelsestmtr ::= testexpr return_if_stmts returns
  542. cf_jump_back ::= COME_FROM JUMP_LOOP
  543. # This is nested inside a try_except
  544. tryfinallystmt ::= SETUP_FINALLY suite_stmts_opt
  545. POP_BLOCK LOAD_CONST
  546. COME_FROM_FINALLY suite_stmts_opt END_FINALLY
  547. c_tryfinallystmt ::= SETUP_FINALLY c_suite_stmts_opt
  548. POP_BLOCK LOAD_CONST COME_FROM_FINALLY
  549. c_suite_stmts_opt END_FINALLY
  550. # This a funny kind of try finally inside a try_except in a loop
  551. c_except_suite ::= SETUP_FINALLY c_suite_stmts
  552. POP_BLOCK LOAD_CONST
  553. COME_FROM_FINALLY LOAD_CONST STORE_FAST DELETE_FAST
  554. END_FINALLY
  555. POP_EXCEPT JUMP_LOOP COME_FROM
  556. c_except_suite ::= except_suite
  557. c_except_suite ::= c_stmts POP_EXCEPT JUMP_LOOP
  558. c_except_handler36 ::= COME_FROM_EXCEPT c_except_stmts END_FINALLY
  559. c_try_except36 ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
  560. c_except_handler36 come_from_opt
  561. c_try_except36 ::= SETUP_EXCEPT returns
  562. c_except_handler36 come_from_opt
  563. except_handler ::= jmp_abs COME_FROM except_stmts
  564. _come_froms END_FINALLY
  565. except_handler ::= jmp_abs COME_FROM_EXCEPT except_stmts
  566. _come_froms END_FINALLY
  567. c_except_handler ::= jmp_abs COME_FROM c_except_stmts
  568. _come_froms END_FINALLY
  569. c_except_handler ::= jmp_abs COME_FROM_EXCEPT c_except_stmts
  570. _come_froms END_FINALLY
  571. c_except_handler ::= jmp_abs COME_FROM_EXCEPT c_except_stmts
  572. try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
  573. except_handler
  574. jump_excepts come_from_except_clauses
  575. c_try_except ::= SETUP_EXCEPT c_suite_stmts_opt POP_BLOCK
  576. c_except_handler
  577. jump_excepts come_from_except_clauses
  578. # FIXME: remove this
  579. except_handler ::= JUMP_FORWARD COME_FROM except_stmts
  580. come_froms END_FINALLY come_from_opt
  581. except_stmts ::= except_stmt+
  582. except_stmt ::= except_cond1 except_suite come_from_opt
  583. except_stmt ::= except_cond2 except_suite come_from_opt
  584. except_stmt ::= except_cond2 except_suite_finalize
  585. except_stmt ::= except
  586. except_stmt ::= stmt
  587. c_except_stmts ::= except_stmts
  588. c_except_stmts ::= c_except_stmt+
  589. c_except_stmt ::= c_stmt
  590. c_except_stmt ::= c_except
  591. c_except_stmt ::= except_cond1 c_except_suite come_from_opt
  592. c_except_stmt ::= except_cond2 c_except_suite come_from_opt
  593. c_except_stmt ::= stmt
  594. ## FIXME: what's except_pop_except?
  595. except_stmt ::= except_pop_except
  596. # Python3 introduced POP_EXCEPT
  597. except_suite ::= c_stmts_opt POP_EXCEPT jump_except
  598. jump_except ::= JUMP_ABSOLUTE
  599. jump_except ::= JUMP_LOOP
  600. jump_except ::= JUMP_FORWARD
  601. jump_except ::= CONTINUE
  602. # This is used in Python 3 in
  603. # "except ... as e" to remove 'e' after the c_stmts_opt finishes
  604. except_suite_finalize ::= SETUP_FINALLY c_stmts_opt except_var_finalize
  605. END_FINALLY jump
  606. except_suite_finalize ::= SETUP_FINALLY c_stmts_opt except_var_finalize
  607. END_FINALLY POP_EXCEPT jump
  608. except_var_finalize ::= POP_BLOCK POP_EXCEPT LOAD_CONST COME_FROM_FINALLY
  609. LOAD_CONST store delete
  610. except_var_finalize ::= POP_BLOCK LOAD_CONST COME_FROM_FINALLY
  611. LOAD_CONST store delete
  612. except_suite ::= returns
  613. c_except_suite ::= c_returns
  614. # except XXX:
  615. except_cond1 ::= DUP_TOP expr COMPARE_OP
  616. POP_JUMP_IF_FALSE POP_TOP POP_TOP POP_TOP
  617. # except XXX as var:
  618. except_cond2 ::= DUP_TOP expr COMPARE_OP
  619. POP_JUMP_IF_FALSE POP_TOP store POP_TOP come_from_opt
  620. except ::= POP_TOP POP_TOP POP_TOP c_stmts_opt POP_EXCEPT JUMP_FORWARD
  621. except ::= POP_TOP POP_TOP POP_TOP returns
  622. except_handler ::= JUMP_FORWARD COME_FROM_EXCEPT except_stmts
  623. come_froms END_FINALLY
  624. jmp_abs ::= JUMP_ABSOLUTE
  625. jmp_abs ::= JUMP_LOOP
  626. jmp_abs ::= JUMP_FORWARD
  627. stmt ::= assert2
  628. stmt ::= assert2_not
  629. """
  630. def p_come_from3(self, args):
  631. """
  632. # In 3.7+ a SETUP_LOOP to a JUMP_FORWARD can
  633. # get replaced by the JUMP_FORWARD addressed. Therefore COME_FROMs may
  634. # appear out of nesting order. For example:
  635. # if x
  636. # for ... jump forward endif (1)
  637. # ...
  638. # break - jump forward endif (2)
  639. # end for
  640. # optional jump forward endif (1)
  641. # else:
  642. # ...
  643. # endif
  644. # come from loop 2 - note not strictly nested
  645. # come from if-then 1
  646. come_any_froms ::= come_any_froms come_any_from
  647. come_any_froms ::= come_any_from
  648. come_any_from ::= COME_FROM_LOOP
  649. come_any_from ::= COME_FROM_EXCEPT
  650. come_any_from ::= COME_FROM
  651. opt_come_from_except ::= come_any_froms?
  652. opt_come_from_loop ::= COME_FROM_LOOP?
  653. come_from_except_clauses ::= COME_FROM_EXCEPT_CLAUSE*
  654. """
  655. def p_jump3(self, args):
  656. """
  657. # FIXME: simplify this
  658. return_expr_or_cond ::= if_exp_ret
  659. return_expr_or_cond ::= return_expr
  660. if_exp_ret ::= expr POP_JUMP_IF_FALSE expr RETURN_END_IF COME_FROM return_expr_or_cond
  661. testfalse ::= or POP_JUMP_IF_FALSE COME_FROM
  662. testfalse ::= nand
  663. testfalse ::= and
  664. testexprc ::= testexpr
  665. testexprc ::= testfalsec
  666. testexprc ::= testtruec
  667. iflaststmtc ::= testexprc c_stmts
  668. iflaststmtc ::= testexprc c_stmts JUMP_LOOP COME_FROM_LOOP
  669. iflaststmtc ::= testexprc c_stmts JUMP_LOOP opt_pop_block
  670. opt_pop_block ::= POP_BLOCK?
  671. """
  672. def p_stmt3(self, args):
  673. """
  674. if_exp_lambda ::= expr_pjif expr return_if_lambda
  675. return_stmt_lambda
  676. if_exp_not_lambda
  677. ::= expr POP_JUMP_IF_TRUE expr return_if_lambda
  678. return_stmt_lambda
  679. return_stmt_lambda ::= return_expr RETURN_VALUE_LAMBDA
  680. stmt ::= return_closure
  681. return_closure ::= LOAD_CLOSURE RETURN_VALUE RETURN_LAST
  682. stmt ::= whileTruestmt
  683. ifelsestmt ::= testexpr stmts_opt JUMP_FORWARD else_suite _come_froms
  684. ifelsestmtc ::= testexpr c_stmts_opt JUMP_FORWARD else_suite _come_froms
  685. ifstmtc ::= testexpr ifstmts_jumpc
  686. # We need a reduction rule to disambiguate ifstmtc from if_not_stmtc
  687. # The difference is that when ifstmts_jumpc geos back to to a loop
  688. # and testexprc is testtruec, then we have if_not_stmtc.
  689. ifstmtc ::= testexprc ifstmts_jumpc _come_froms
  690. if_not_stmtc ::= testexprc ifstmts_jumpc _come_froms
  691. ifstmts_jumpc ::= ifstmts_jump
  692. ifstmts_jumpc ::= c_stmts_opt come_froms
  693. ifstmts_jumpc ::= COME_FROM c_stmts come_froms
  694. ifstmts_jumpc ::= c_stmts
  695. ifstmts_jumpc ::= c_stmts JUMP_LOOP
  696. ifstmts_jump ::= stmts come_froms
  697. ifstmts_jump ::= COME_FROM stmts come_froms
  698. # The following can happen when the jump offset is large and
  699. # Python is looking to do a small jump to a larger jump to get
  700. # around the problem that the offset can't be represented in
  701. # the size allowed for the jump offset. This is more likely to
  702. # happen in wordcode Python since the offset range has been
  703. # reduced. FIXME: We should add a reduction check that the
  704. # final jump goes to another jump.
  705. ifstmts_jumpc ::= COME_FROM c_stmts JUMP_LOOP
  706. ifstmts_jumpc ::= COME_FROM c_stmts JUMP_FORWARD
  707. """
  708. def p_3try_except(self, args):
  709. """
  710. # In 3.6+, A sequence of statements ending in a RETURN can cause
  711. # JUMP_FORWARD END_FINALLY to be omitted from try middle
  712. except_return ::= POP_TOP POP_TOP POP_TOP returns
  713. except_handler ::= JUMP_FORWARD COME_FROM_EXCEPT except_return
  714. # Try middle following a returns
  715. except_handler36 ::= COME_FROM_EXCEPT except_stmts END_FINALLY
  716. stmt ::= try_except36
  717. try_except36 ::= SETUP_EXCEPT returns except_handler36
  718. opt_come_from_except
  719. try_except36 ::= SETUP_EXCEPT suite_stmts
  720. try_except36 ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
  721. except_handler36 come_from_opt
  722. # 3.6 omits END_FINALLY sometimes
  723. except_handler36 ::= COME_FROM_EXCEPT except_stmts
  724. except_handler36 ::= JUMP_FORWARD COME_FROM_EXCEPT except_stmts
  725. except_handler ::= jmp_abs COME_FROM_EXCEPT except_stmts
  726. stmt ::= tryfinally36
  727. tryfinally36 ::= SETUP_FINALLY returns
  728. COME_FROM_FINALLY suite_stmts
  729. tryfinally36 ::= SETUP_FINALLY returns
  730. COME_FROM_FINALLY suite_stmts_opt END_FINALLY
  731. except_suite_finalize ::= SETUP_FINALLY returns
  732. COME_FROM_FINALLY suite_stmts_opt END_FINALLY jump
  733. stmt ::= tryfinally_return_stmt1
  734. stmt ::= tryfinally_return_stmt2
  735. tryfinally_return_stmt1 ::= SETUP_FINALLY suite_stmts_opt POP_BLOCK LOAD_CONST
  736. COME_FROM_FINALLY returns
  737. tryfinally_return_stmt2 ::= SETUP_FINALLY suite_stmts_opt POP_BLOCK LOAD_CONST
  738. COME_FROM_FINALLY
  739. """
  740. def p_36misc(self, args):
  741. """
  742. sstmt ::= sstmt RETURN_LAST
  743. # 3.6 redoes how return_closure works. FIXME: Isolate to LOAD_CLOSURE
  744. return_closure ::= LOAD_CLOSURE DUP_TOP STORE_NAME RETURN_VALUE RETURN_LAST
  745. # 3.6 due to jump optimization, we sometimes add RETURN_END_IF where
  746. # RETURN_VALUE is meant. Specifically this can happen in
  747. # ifelsestmt -> ...else_suite _. suite_stmts... (last) stmt
  748. return ::= return_expr RETURN_END_IF
  749. return ::= return_expr RETURN_VALUE
  750. jf_cf ::= JUMP_FORWARD COME_FROM
  751. if_exp ::= expr_pjif expr jf_cf expr COME_FROM
  752. except_suite ::= c_stmts_opt COME_FROM POP_EXCEPT jump_except COME_FROM
  753. jb_cfs ::= come_from_opt JUMP_LOOP come_froms
  754. ifelsestmtc ::= testexpr c_stmts_opt jb_cfs else_suitec
  755. """
  756. def info(args):
  757. # Check grammar
  758. import sys
  759. p = Python37Parser()
  760. if len(args) > 0:
  761. arg = args[0]
  762. if arg == "3.7":
  763. from decompyle3.parser.parse37 import Python37Parser
  764. p = Python37Parser()
  765. elif arg == "3.8":
  766. from decompyle3.parser.parse38 import Python38Parser
  767. p = Python38Parser()
  768. else:
  769. raise RuntimeError("Only 3.7 and 3.8 supported")
  770. p.check_grammar()
  771. if len(sys.argv) > 1 and sys.argv[1] == "dump":
  772. print("-" * 50)
  773. p.dump_grammar()
  774. if __name__ == "__main__":
  775. # Check grammar
  776. from decompyle3.parsers.dump import dump_and_check
  777. p = Python37Parser()
  778. modified_tokens = set(
  779. """JUMP_LOOP CONTINUE RETURN_END_IF COME_FROM
  780. LOAD_GENEXPR LOAD_ASSERT LOAD_SETCOMP LOAD_DICTCOMP LOAD_CLASSNAME
  781. LAMBDA_MARKER RETURN_LAST
  782. """.split()
  783. )
  784. dump_and_check(p, (3, 7), modified_tokens)