consts.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682
  1. # Copyright (c) 2017-2020, 2022-2024 by 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. """Constants and initial table values used in pysource.py and fragments.py"""
  16. import re
  17. import sys
  18. from decompyle3.parsers.treenode import SyntaxTree
  19. from decompyle3.scanners.tok import NoneToken, Token
  20. minint = -sys.maxsize - 1
  21. maxint = sys.maxsize
  22. # Operator precedence See
  23. # https://docs.python.org/3/reference/expressions.html#operator-precedence
  24. # for a list. We keep the same top-to-botom order here as in the above links,
  25. # so we start with low precedence (high values) and go down in value.
  26. # Things at the bottom of this list below with high precedence (low value) will
  27. # tend to have parenthesis around them. Things at the top
  28. # of the list will tend not to have parenthesis around them.
  29. # Note: The values in this table are even numbers. Inside
  30. # various templates we use odd values. Avoiding equal-precedent comparisons
  31. # avoids ambiguity what to do when the precedence is equal.
  32. # The precedence of a key below applies the key, a node, and the its
  33. # *parent*. A node however sometimes sets the precedence for its
  34. # children. For example, "call" has precedence 2 so we don't get
  35. # additional the additional parenthesis of: ".. op (call())". However
  36. # for call's children, it parameters, we set the the precedence high,
  37. # say to 100, to make sure we avoid additional parenthesis in
  38. # call((.. op ..)).
  39. NO_PARENTHESIS_EVER = 100
  40. PARENTHESIS_ALWAYS = -2
  41. # fmt: off
  42. PRECEDENCE = {
  43. "named_expr": 40, # :=
  44. "dict_unpack": 38, # **kwargs
  45. "list_unpack": 38, # *args
  46. "yield_from": 38,
  47. "tuple_list_starred": 38, # *x, *y, *z - about at the level of yield?
  48. "unpack": 38, # A guess. Used in "async with ... as ...
  49. # This might also get used in tuple assignment?
  50. "_lambda_body": 30,
  51. "lambda_body": 32, # lambda ... : lambda_body
  52. "yield": 30, # Needs to be below named_expr and lambda_body
  53. "if_exp": 28, # IfExp ( a if x else b)
  54. "if_exp_lambda": 28, # IfExp involving a lambda expression
  55. "if_exp_not_lambda": 28, # negated IfExp involving a lambda expression
  56. "if_exp_not": 28, # IfExp ( a if not x else b)
  57. "if_exp_true": 28, # (a if True else b)
  58. "if_exp_ret": 28,
  59. "or": 26, # Boolean OR
  60. # x and y or z. Note that although we may need
  61. # parenthesis around (a and y or z) , inside the
  62. # implied order is (a and y) or z.
  63. "and_or_expr": 26,
  64. "ret_or": 26,
  65. "and": 24, # Boolean AND
  66. "ret_and": 24,
  67. "not": 22, # Boolean NOT
  68. "unary_not": 22, # Boolean NOT
  69. "compare": 20, # in, not in, is, is not, <, <=, >, >=, !=, ==
  70. "BINARY_AND": 14, # Bitwise AND
  71. "BINARY_OR": 18, # Bitwise OR
  72. "BINARY_XOR": 16, # Bitwise XOR
  73. "BINARY_LSHIFT": 12, # Shifts <<
  74. "BINARY_RSHIFT": 12, # Shifts >>
  75. "BINARY_ADD": 10, # -
  76. "BINARY_SUBTRACT": 10, # +
  77. "BINARY_DIVIDE": 8, # /
  78. "BINARY_FLOOR_DIVIDE": 8, # //
  79. "BINARY_MATRIX_MULTIPLY": 8, # @
  80. "BINARY_MODULO": 8, # Remainder, %
  81. "BINARY_MULTIPLY": 8, # *
  82. "BINARY_TRUE_DIVIDE": 8, # Division /
  83. "unary_op": 6, # Positive, negative, bitwise NOT: +x, -x, ~x
  84. "BINARY_POWER": 4, # Exponentiation: **
  85. "await_expr": 3, # await x, *
  86. "attribute": 2, # x.attribute
  87. "buildslice2": 2, # x[index]
  88. "buildslice3": 2, # x[index:index]
  89. "call": 2, # x(arguments...)
  90. "delete_subscript": 2,
  91. "slice0": 2,
  92. "slice1": 2,
  93. "slice2": 2,
  94. "slice3": 2,
  95. "store_subscript": 2,
  96. "subscript": 2,
  97. "dict": 0, # {expressions...}
  98. "dict_comp": 0,
  99. "generator_exp": 0, # (expressions...)
  100. "list": 0, # [expressions...]
  101. "list_comp": 0,
  102. "set_comp": 0,
  103. "set_comp_expr": 0,
  104. "unary_convert": 0,
  105. }
  106. LINE_LENGTH = 80
  107. # Some parse trees created below are used for comparing code
  108. # fragments (like "return None" at the end of functions).
  109. ASSIGN_DOC_STRING = lambda doc_string, doc_load: SyntaxTree( # noqa
  110. "assign",
  111. [
  112. SyntaxTree(
  113. "expr", [Token(doc_load, pattr=doc_string, attr=doc_string)]
  114. ),
  115. SyntaxTree("store", [Token("STORE_NAME", pattr="__doc__", optype="name")]),
  116. ],
  117. )
  118. PASS = SyntaxTree(
  119. "stmts", [SyntaxTree("sstmt", [SyntaxTree("stmt", [SyntaxTree("pass", [])])])]
  120. )
  121. NAME_MODULE = SyntaxTree(
  122. "assign",
  123. [
  124. SyntaxTree(
  125. "expr", [Token("LOAD_NAME", pattr="__name__", offset=0, has_arg=True, optype="name")]
  126. ),
  127. SyntaxTree(
  128. "store", [Token("STORE_NAME", pattr="__module__", offset=3, has_arg=True, optype="name")]
  129. ),
  130. ],
  131. )
  132. NEWLINE = SyntaxTree("newline", [])
  133. NONE = SyntaxTree("expr", [NoneToken])
  134. RETURN_NONE = SyntaxTree("stmt", [SyntaxTree("return", [NONE, Token("RETURN_VALUE")])])
  135. RETURN_LOCALS = SyntaxTree(
  136. "return",
  137. [
  138. SyntaxTree("return_expr", [SyntaxTree("expr", [Token("LOAD_LOCALS")])]),
  139. Token("RETURN_VALUE"),
  140. ],
  141. )
  142. # God intended \t, but Python has decided to use 4 spaces.
  143. # If you want real tabs, use Go.
  144. # TAB = "\t"
  145. TAB = " " * 4
  146. INDENT_PER_LEVEL = " " # additional intent per pretty-print level
  147. TABLE_R = {
  148. "STORE_ATTR": ("%c.%[1]{pattr}", 0),
  149. "DELETE_ATTR": ("%|del %c.%[-1]{pattr}\n", 0),
  150. }
  151. TABLE_DIRECT = {
  152. "BINARY_ADD": ( "+" ,),
  153. "BINARY_AND": ( "&" ,),
  154. "BINARY_DIVIDE": ( "/" ,),
  155. "BINARY_FLOOR_DIVIDE": ( "//" ,),
  156. "BINARY_LSHIFT": ( "<<",),
  157. "BINARY_MATRIX_MULTIPLY": ( "@" ,),
  158. "BINARY_MODULO": ( "%%",),
  159. "BINARY_MULTIPLY": ( "*" ,),
  160. "BINARY_OR": ( "|" ,),
  161. "BINARY_POWER": ( "**",),
  162. "BINARY_RSHIFT": ( ">>",),
  163. "BINARY_SUBTRACT": ( "-" ,),
  164. "BINARY_TRUE_DIVIDE": ( "/" ,), # Not in <= 2.1; 2.6 generates INPLACE_DIVIDE only?
  165. "BINARY_XOR": ( "^" ,),
  166. "DELETE_FAST": ( "%|del %{pattr}\n", ),
  167. "DELETE_GLOBAL": ( "%|del %{pattr}\n", ),
  168. "DELETE_NAME": ( "%|del %{pattr}\n", ),
  169. "IMPORT_FROM": ( "%{pattr}", ),
  170. "IMPORT_NAME_ATTR": ( "%{pattr}", ),
  171. "INPLACE_ADD": ( "+=" ,),
  172. "INPLACE_AND": ( "&=" ,),
  173. "INPLACE_DIVIDE": ( "/=" ,),
  174. "INPLACE_FLOOR_DIVIDE": ( "//=" ,),
  175. "INPLACE_LSHIFT": ( "<<=",),
  176. "INPLACE_MATRIX_MULTIPLY": ( "@=" ,),
  177. "INPLACE_MODULO": ( "%%=",),
  178. "INPLACE_MULTIPLY": ( "*=" ,),
  179. "INPLACE_OR": ( "|=" ,),
  180. "INPLACE_POWER": ( "**=",),
  181. "INPLACE_RSHIFT": ( ">>=",),
  182. "INPLACE_SUBTRACT": ( "-=" ,),
  183. "INPLACE_TRUE_DIVIDE": ( "/=" ,),
  184. "INPLACE_XOR": ( "^=" ,),
  185. "LOAD_ARG": ( "%{pattr}", ),
  186. "LOAD_ASSERT": ( "%{pattr}", ),
  187. "LOAD_CLASSNAME": ( "%{pattr}", ),
  188. "LOAD_DEREF": ( "%{pattr}", ),
  189. "LOAD_FAST": ( "%{pattr}", ),
  190. "LOAD_GLOBAL": ( "%{pattr}", ),
  191. "LOAD_LOCALS": ( "locals()", ),
  192. "LOAD_NAME": ( "%{pattr}", ),
  193. "LOAD_STR": ( "%{pattr}", ),
  194. "STORE_DEREF": ( "%{pattr}", ),
  195. "STORE_FAST": ( "%{pattr}", ),
  196. "STORE_GLOBAL": ( "%{pattr}", ),
  197. "STORE_NAME": ( "%{pattr}", ),
  198. "UNARY_INVERT": ( "~"),
  199. "UNARY_NEGATIVE": ( "-",),
  200. "UNARY_NOT": ( "not ", ),
  201. "UNARY_POSITIVE": ( "+",),
  202. "and": (
  203. "%c and %c",
  204. (0, ("and_parts", "expr", "expr_pjif", "expr_jifop_cfs", "not")),
  205. (1, ("expr", "expr_pjif", "expr_jifop_cfs")),
  206. ),
  207. "and2": ("%c", 3),
  208. "assign": (
  209. "%|%c = %p\n",
  210. -1,
  211. (0, ("expr", "branch_op"), PRECEDENCE["tuple_list_starred"] + 1)
  212. ),
  213. "attribute": ("%c.%[1]{pattr}", (0, "expr")),
  214. # This nonterminal we create on the fly in semantic routines
  215. "attribute_w_parens": ("(%c).%[1]{pattr}", (0, "expr")),
  216. # The 2nd parameter should have a = suffix.
  217. # There is a rule with a 4th parameter "store"
  218. # which we don't use here.
  219. "aug_assign1": (
  220. "%|%c %c %c\n", 0, 2, 1
  221. ),
  222. # There is a rule with a 4th parameter "store"
  223. # which we don't use here.
  224. "aug_assign2": (
  225. "%|%c.%[2]{pattr} %c %c\n", 0, -3, -4
  226. ),
  227. # bin_op (formerly "binary_expr") is the Python AST BinOp
  228. "bin_op": ("%c %c %c", 0, (-1, "binary_operator"), (1, "expr")),
  229. "break": ("%|break\n",),
  230. "build_tuple2": (
  231. "%P",
  232. (0, -1, ", ", NO_PARENTHESIS_EVER)
  233. ),
  234. "c_compare_chained": ("%p %p", (0, 29), (1, 30)),
  235. "c_except": (
  236. "%|except:\n%+%c%-",
  237. (3, ("c_stmts_opt", "c_returns", "c_stmts", "pass")),
  238. ),
  239. "c_tryelsestmt": ("%|try:\n%+%c%-%c%|else:\n%+%c%-", 1, 3, 4),
  240. "c_tryfinallystmt": (
  241. "%|try:\n%+%c%-%|finally:\n%+%c%-\n\n",
  242. (1, "c_suite_stmts_opt"),
  243. (5, "c_suite_stmts_opt"),
  244. ),
  245. "call_stmt": (
  246. "%|%p\n",
  247. # When a call statement contains only a named_expr (:=)
  248. # the named_expr should have parenthesis around it.
  249. (0, PRECEDENCE["named_expr"] - 1),
  250. ),
  251. # "classdef": (), # handled by n_classdef()
  252. # A custom rule in n_function def distinguishes whether to call this or
  253. # function_def_async
  254. "classdefdeco": ("\n\n%c", 0),
  255. "classdefdeco1": ("%|@%c\n%c", 0, 1),
  256. "comp_body": ("",), # ignore when recursing
  257. "comp_if": (" if %c%c", 0, 1),
  258. # Note: Adding "if" is handled inside the
  259. # comprehension
  260. "comp_if_or": (
  261. "%p or %p ",
  262. (0,
  263. ("or_parts", "or_parts_true_loop", "or_parts_false_loop"), PRECEDENCE["or"]
  264. ),
  265. (1, "expr", PRECEDENCE["or"] ),
  266. ),
  267. "comp_if_not": (
  268. " if not %p%c",
  269. (0, "expr", PRECEDENCE["unary_not"]), 2
  270. ),
  271. # Note: Adding "if" is handled inside the
  272. # comprehension
  273. "comp_if_not_and": (
  274. "not (%p and %p)",
  275. (0, "expr_pjif", PRECEDENCE["and"] ),
  276. (1, "expr", PRECEDENCE["and"] ),
  277. ),
  278. # Note: Adding "if" is handled inside the
  279. # comprehension
  280. "comp_if_not_or": (
  281. "not (%p or %p)",
  282. (0, "expr_pjif", PRECEDENCE["and"] ),
  283. (1, "expr", PRECEDENCE["and"] ),
  284. ),
  285. "comp_iter": ("%c", 0),
  286. "compare_single": ('%p %[-1]{pattr.replace("-", " ")} %p', (0, 19), (1, 19)),
  287. "compare_chained": ("%p %p", (0, 29), (1, 30)),
  288. "compare_chained_middle": ('%[3]{pattr.replace("-", " ")} %p %p', (0, 19), (-2, 19)),
  289. "compare_chained_right": ('%[1]{pattr.replace("-", " ")} %p', (0, 19)),
  290. "conditional_not_lambda": ("%p if not %c else %c", (2, "expr", 27), 0, 4),
  291. "continue": ("%|continue\n",),
  292. "delete_subscript": (
  293. "%|del %p[%c]\n",
  294. (0, "expr", PRECEDENCE["subscript"]),
  295. (1, "expr"),
  296. ),
  297. "designList": ("%c = %c", 0, -1),
  298. "dict_comp_body": ("%c: %c", 1, 0),
  299. "elifelifstmt": ("%|elif %c:\n%+%c%-%c", 0, 1, 3),
  300. "elifelsestmt": ("%|elif %c:\n%+%c%-%|else:\n%+%c%-", 0, 1, 3),
  301. "elifelsestmtr": ("%|elif %c:\n%+%c%-%|else:\n%+%c%-\n\n", 0, 1, 2),
  302. "elifelsestmtr2": (
  303. "%|elif %c:\n%+%c%-%|else:\n%+%c%-\n\n",
  304. 0,
  305. 1,
  306. 3,
  307. ), # has COME_FROM
  308. "elifstmt": ("%|elif %c:\n%+%c%-", 0, 1),
  309. "except": ("%|except:\n%+%c%-", 3),
  310. "except_cond1": ("%|except %c:\n", 1),
  311. "except_suite": ("%+%c%-%C", 0, (1, maxint, "")),
  312. # In Python 3.6+, this is more complicated in the presence of "returns"
  313. "except_suite_finalize": ("%+%c%-%C", 1, (3, maxint, "")),
  314. "expr_stmt": (
  315. "%|%p\n",
  316. # When a statement contains only a named_expr (:=)
  317. # the named_expr should have parenthesis around it.
  318. (0, "expr", PRECEDENCE["named_expr"] - 1)
  319. ),
  320. # Note: Python 3.8+ changes this
  321. "for": ("%|for %c in %c:\n%+%c%-\n\n", (3, "store"), (1, "expr"), (4, "for_block")),
  322. "forelsestmt": (
  323. "%|for %c in %c:\n%+%c%-%|else:\n%+%c%-\n\n",
  324. (3, "store"),
  325. (1, "expr"),
  326. (4, "for_block"),
  327. -2,
  328. ),
  329. "forelselaststmt": (
  330. "%|for %c in %c:\n%+%c%-%|else:\n%+%c%-",
  331. (3, "store"),
  332. (1, "expr"),
  333. (4, "for_block"),
  334. -2,
  335. ),
  336. "forelselaststmtc": (
  337. "%|for %c in %c:\n%+%c%-%|else:\n%+%c%-\n\n",
  338. (3, "store"),
  339. (1, "expr"),
  340. (4, "for_block"),
  341. -2,
  342. ),
  343. "function_def": ("\n\n%|def %c\n", -2), # -2 to handle closures
  344. "function_def_deco": ("\n\n%c", (0, "mkfuncdeco")),
  345. "gen_comp_body": ("%c", 0),
  346. "get_iter": ("iter(%c)", (0, "expr"),),
  347. "if_exp": (
  348. "%p if %c else %c",
  349. (1, 27), # "expr-like thing
  350. 0, # expr-like thing
  351. 3,
  352. ),
  353. "if_exp_lambda": (
  354. "%c if %c else %c",
  355. (1, ("expr", "return_expr_lambda")),
  356. (0, "expr_pjif"),
  357. (-1, ("return_expr_lambda", "return_if_lambda")),
  358. ),
  359. "if_exp_lambda2": (
  360. "%c if %c else %c",
  361. (1, ("expr", "return_expr_lambda")),
  362. (0, "and_parts"),
  363. (-2, "return_expr_lambda"),
  364. ),
  365. "if_exp_not_lambda2": (
  366. "%c if not (%c) else %c",
  367. (2, "expr"),
  368. (0, "expr"),
  369. (-1, "return_expr_lambda"),
  370. ),
  371. "if_exp_loop": (
  372. "%c if %c else %c",
  373. (1, "expr"),
  374. (0, ("expr_pjif")),
  375. (-1, "expr"),
  376. ),
  377. # The arg2 is dead-code
  378. "if_expr_true": ("%p if 1 else %c", (0, "expr", 27), 2),
  379. # The arg 1 is dead-code
  380. "if_exp_dead_code": (
  381. "%c if True else %c",
  382. (0, "return_expr_lambda"),
  383. (1, "return_expr_lambda"),
  384. ),
  385. "if_exp_true": ("%p if 1 else %c", (0, "expr", 27), 2),
  386. "if_exp_ret": ("%p if %p else %p", (2, 27), (0, 27), (-1, 27)),
  387. "if_exp_not": (
  388. "%p if not %p else %p",
  389. (2, 27),
  390. (0, "expr", PRECEDENCE["unary_not"]),
  391. (4, 27),
  392. ),
  393. # Generally the args here are 0: (some sort of) "testexpr",
  394. # 1: (some sort of) "cstmts_opt",
  395. # 2 or 3: "else_suite"
  396. # But unfortunately there are irregularities, For example, 2.6- uses "testexpr_then"
  397. # and sometimes "cstmts" instead of "cstmts_opt" happens.
  398. # Down the line we might isolate these into version-specific rules.
  399. "ifelsestmt": ("%|if %c:\n%+%c%-%|else:\n%+%c%-", 0, 1, 3),
  400. "ifelsestmtc": ("%|if %c:\n%+%c%-%|else:\n%+%c%-", 0, 1, 3),
  401. # This is created only via transformation.
  402. "ifelifstmt": ("%|if %c:\n%+%c%-%c", 0, 1, 3),
  403. "ifelsestmtr": ("%|if %c:\n%+%c%-%|else:\n%+%c%-", 0, 1, 2),
  404. "ifelsestmtr2": ("%|if %c:\n%+%c%-%|else:\n%+%c%-\n\n", 0, 1, 3), # has COME_FROM
  405. "iflaststmt": ("%|if %c:\n%+%c%-", 0, 1),
  406. "iflaststmtc": ("%|if %c:\n%+%c%-", 0, 1),
  407. "ifstmt": (
  408. "%|if %c:\n%+%c%-", (0, ("testexpr", "bool_op")), (1, ("ifstmts_jump", "stmts"))
  409. ),
  410. "import": ("%|import %c\n", 2),
  411. "importlist": ("%C", (0, maxint, ", ")),
  412. # Note: the below rule isn't really complete:
  413. # n_import_from() smashes node[2].pattr
  414. "import_from": (
  415. "%|from %[2]{pattr} import %c\n",
  416. (3, "importlist")
  417. ),
  418. "import_from_star": (
  419. "%|from %[2]{pattr} import *\n",
  420. ),
  421. "kv": ("%c: %c", 3, 1),
  422. "kv2": ("%c: %c", 1, 2),
  423. "kwarg": ("%[0]{attr}=%c", 1),
  424. "kwargs": ("%D", (0, maxint, ", ")),
  425. "kwargs1": ("%D", (0, maxint, ", ")),
  426. "lc_body": ("",), # ignore when recursing
  427. "list_iter": ("%c", 0),
  428. "list_for": (" for %c in %c%c", 2, 0, 3),
  429. "list_if": (" if %p%c", (0, "expr", 27), 2),
  430. "list_if_not": (" if not %p%c", (0, "expr", PRECEDENCE["unary_not"]), 2),
  431. "list_if_or_not": (
  432. " if %c or not %c %c",
  433. (0, "expr_pjit"),
  434. (1, "expr_pjit"),
  435. (3, "list_iter"),
  436. ),
  437. "mkfuncdeco": ("%|@%c\n%c", (0, "expr"), 1),
  438. # A custom rule in n_function def distinguishes whether to call this or
  439. # function_def_async
  440. "mkfuncdeco0": ("%|def %c\n", (0, "mkfunc")),
  441. # In cases where we desire an explicit new line.
  442. # After docstrings which are followed by a "def" is
  443. # one situations where Python formatting desires two newlines,
  444. # and this is added, as a transformation rule.
  445. "newline": ("\n"),
  446. "or": ("%p or %p", (0, PRECEDENCE["or"]), (1, PRECEDENCE["or"])),
  447. "or_expr": ("%c or %c", (0, "expr"), (2, "expr"),),
  448. "pass": ("%|pass\n",),
  449. "raise_stmt0": ("%|raise\n",),
  450. "raise_stmt1": ("%|raise %c\n", 0),
  451. "raise_stmt3": ("%|raise %c, %c, %c\n", 0, 1, 2),
  452. # Note: we have a custom rule, which calls when we don't
  453. # have "return None"
  454. # "return": ( "%|return %c\n", 0),
  455. "return_if_stmt": ("return %c\n", 0),
  456. "ret_and": ("%c and %c", 0, 2),
  457. "ret_or": ("%c or %c", 0, 2),
  458. "set_comp_body": ("%c", 0),
  459. "set_iter": ( "%c", 0 ),
  460. "slice0": (
  461. "%c[:]",
  462. (0, "expr"),
  463. ),
  464. "slice1": (
  465. "%c[%p:]",
  466. (0, "expr"),
  467. (1, NO_PARENTHESIS_EVER)
  468. ),
  469. "slice2": ( "[%c:%p]",
  470. (0, "expr"),
  471. (1, NO_PARENTHESIS_EVER)
  472. ),
  473. "slice3": (
  474. "%c[%p:%p]",
  475. (0, "expr"),
  476. (1, NO_PARENTHESIS_EVER),
  477. (2, NO_PARENTHESIS_EVER)
  478. ),
  479. "store_subscript": (
  480. "%p[%c]",
  481. (0, "expr", PRECEDENCE["subscript"]), (1, "expr")
  482. ),
  483. # This nonterminal we create on the fly in semantic routines
  484. "store_w_parens": (
  485. "(%c).%[1]{pattr}",
  486. (0, "expr")
  487. ),
  488. # This is only generated by transform
  489. # it is a string at the beginning of a function that is *not* a docstring
  490. # 3.7 test_fstring.py tests for this kind of crap.
  491. # For compatibility with older Python, we'll use "%" instead of
  492. # a format string.
  493. "string_at_beginning": ('%|"%%s" %% %c\n', 0),
  494. "subscript": (
  495. "%p[%p]",
  496. (0, "expr", PRECEDENCE["subscript"]),
  497. (1, "expr", NO_PARENTHESIS_EVER)
  498. ),
  499. "subscript2": (
  500. "%p[%p]",
  501. (0, "expr", PRECEDENCE["subscript"]),
  502. (1, "expr", NO_PARENTHESIS_EVER)
  503. ),
  504. "testtrue": ("not %p", (0, PRECEDENCE["unary_not"])),
  505. "try_except": ("%|try:\n%+%c%-%c\n\n", 1, 3),
  506. "tryelsestmt": ("%|try:\n%+%c%-%c%|else:\n%+%c%-\n\n", 1, 3, 4),
  507. "tryelsestmt3": ("%|try:\n%+%c%-%c%|else:\n%+%c%-\n\n", 1, 3, 5),
  508. # unary_op (formerly "unary_expr") is the Python AST UnaryOp
  509. "unary_op": ("%c%c", (1, "unary_operator"), (0, "expr")),
  510. "unary_not": ("not %c", (0, "expr")),
  511. "unary_convert": ("`%c`", (0, "expr"),),
  512. "unpack": ("%C%,", (1, maxint, ", ")),
  513. # This nonterminal we create on the fly in semantic routines
  514. "unpack_w_parens": ("(%C%,)", (1, maxint, ", ")),
  515. "unpack_list": ("[%C]", (1, maxint, ", ")),
  516. "whileTruestmt": ("%|while True:\n%+%c%-\n\n", 1),
  517. "whilestmt": ("%|while %c:\n%+%c%-\n\n", 1, 2),
  518. "while1stmt": ("%|while 1:\n%+%c%-\n\n", 1),
  519. "while1elsestmt": ("%|while 1:\n%+%c%-%|else:\n%+%c%-\n\n", 1, -2),
  520. "whileelsestmt": ("%|while %c:\n%+%c%-%|else:\n%+%c%-\n\n", 1, 2, -2),
  521. "whileelselaststmt": ("%|while %c:\n%+%c%-%|else:\n%+%c%-", 1, 2, -2),
  522. "tryelsestmtl": ("%|try:\n%+%c%-%c%|else:\n%+%c%-", 1, 3, 4),
  523. # Note: this is generated generated by grammar rules but in this phase.
  524. "tf_try_except": ("%c%-%c%+", 1, 3),
  525. "tf_tryelsestmt": ("%c%-%c%|else:\n%+%c", 1, 3, 4),
  526. "tryfinallystmt": (
  527. "%|try:\n%+%c%-%|finally:\n%+%c%-\n\n",
  528. (1, "suite_stmts_opt"),
  529. (-2, "suite_stmts_opt"),
  530. ),
  531. "tryfinallystmt_break": (
  532. "%|try:\n%+%c%-%|finally:\n%+%c%-\n%|break\n",
  533. (1, "suite_stmts_opt"),
  534. (-2, "suite_stmts_opt"),
  535. ),
  536. # If there are situations where we need "with ... as ()"
  537. # We may need to customize this in n_with_as
  538. "with_as": (
  539. "%|with %c as %c:\n%+%c%-",
  540. (0, "expr"),
  541. (2, "store"),
  542. (3, ("suite_stmts_opt", "_stmts")),
  543. ),
  544. # "yield": ( "yield %c", 0),
  545. }
  546. # fmt: on
  547. MAP_DIRECT = (TABLE_DIRECT,)
  548. MAP_R = (TABLE_R, -1)
  549. MAP = {
  550. "stmt": MAP_R,
  551. "c_stmt": MAP_R,
  552. "call": MAP_R,
  553. "delete": MAP_R,
  554. "store": MAP_R,
  555. }
  556. ASSIGN_TUPLE_PARAM = lambda param_name: SyntaxTree( # noqa
  557. "expr", [Token("LOAD_FAST", pattr=param_name)]
  558. )
  559. escape = re.compile(
  560. r"""
  561. (?P<prefix> [^%]* )
  562. % ( \[ (?P<child> -? \d+ ) \] )?
  563. ((?P<type> [^{] ) |
  564. ( [{] (?P<expr> [^}]* ) [}] ))
  565. """,
  566. re.VERBOSE,
  567. )