consts.py 20 KB

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