py2_parser.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  1. # Copyright (c) 2016-2017 Rocky Bernstein
  2. """
  3. More complex expression parsing
  4. """
  5. # from __future__ import print_function
  6. import sys
  7. from spark_parser.example.python2.py2_scan import ENDMARKER, Python2Scanner
  8. from spark_parser import GenericASTBuilder
  9. from spark_parser.ast import AST
  10. DEFAULT_DEBUG = {
  11. "rules": False,
  12. "transition": False,
  13. "reduce": False,
  14. "errorstack": "full",
  15. "context": True,
  16. "dups": True,
  17. }
  18. class PythonParser(GenericASTBuilder):
  19. """A more complete spark example: a Python 2 Parser.
  20. Note: function parse() comes from GenericASTBuilder
  21. """
  22. def __init__(self, start="file_input", debug=DEFAULT_DEBUG):
  23. super(PythonParser, self).__init__(AST, start, debug=debug)
  24. self.start = start
  25. self.debug = debug
  26. # Put left-recursive list non-terminals:
  27. # x ::= x y
  28. # x ::=
  29. self.collect = frozenset(
  30. (
  31. "stmts",
  32. "comments",
  33. "dot_names",
  34. "dots",
  35. "comp_op_exprs",
  36. "newline_or_stmts",
  37. "comma_names",
  38. "comma_fpdef_opt_eqtests",
  39. )
  40. )
  41. def debug_reduce(self, rule, tokens, parent, i):
  42. """Customized format and print for our kind of tokens
  43. which gets called in debugging grammar reduce rules
  44. """
  45. prefix = " "
  46. if parent and tokens:
  47. p_token = tokens[parent]
  48. if hasattr(p_token, "line"):
  49. prefix = "L.%3d.%03d: " % (p_token.line, p_token.column)
  50. pass
  51. pass
  52. print("%s%s ::= %s" % (prefix, rule[0], " ".join(rule[1])))
  53. def nonterminal(self, nt, args):
  54. # nonterminal with a (reserved) single word derivation
  55. no_skip = ("pass_stmt", "continue_stmt", "break_stmt", "return_stmt")
  56. has_len = hasattr(args, "__len__")
  57. if nt in self.collect and len(args) > 1:
  58. #
  59. # Collect iterated thingies together.
  60. #
  61. rv = args[0]
  62. for arg in args[1:]:
  63. rv.append(arg)
  64. elif (
  65. has_len
  66. and len(args) == 1
  67. and hasattr(args[0], "__len__")
  68. and args[0] not in no_skip
  69. and len(args[0]) == 1
  70. ):
  71. # Remove singleton derivations
  72. rv = GenericASTBuilder.nonterminal(self, nt, args[0])
  73. del args[0] # save memory
  74. elif (
  75. has_len
  76. and len(args) == 2
  77. and hasattr(args[1], "__len__")
  78. and len(args[1]) == 0
  79. ):
  80. # Remove trailing epsilon rules, but only when there
  81. # are two items.
  82. if hasattr(args[0], "__len__") and len(args[0]) == 1:
  83. # Remove singleton derivation
  84. rv = args[0]
  85. else:
  86. rv = GenericASTBuilder.nonterminal(self, nt, args[:1])
  87. del args[1] # save memory
  88. else:
  89. rv = GenericASTBuilder.nonterminal(self, nt, args)
  90. return rv
  91. ##########################################################
  92. # Python 2 grammar rules. Grammar rule functions
  93. # start with the name p_ and are collected automatically
  94. ##########################################################
  95. def p_python_grammar(self, args):
  96. """
  97. ### Note: comment rules that start ## are rules from python26.gr
  98. ## We use them to assist checking translation to a SPARK-format grammar.
  99. single_input ::= NEWLINE
  100. single_input ::= simple_stmt
  101. single_input ::= compound_stmt NEWLINE
  102. file_input ::= newline_or_stmts ENDMARKER
  103. newline_or_stmts ::= newline_or_stmt*
  104. # Grammar uses NEWLINE instead of 'sep', but ; does separate statements.
  105. # The grammar is vague on how NEWLINE, INDENT, and DEDENT are computed.
  106. newline_or_stmt ::= sep
  107. newline_or_stmt ::= stmt_plus
  108. newline_or_stmt ::= comment sep
  109. stmts ::= stmt*
  110. stmts ::= stmt sep
  111. stmt_plus ::= stmt+
  112. eval_input ::= testlist newlines ENDMARKER
  113. newlines ::= NEWLINE+
  114. decorator ::= AT dotted_name arglist_opt NEWLINE
  115. arglist_opt ::= arglist?
  116. ## arglist ::= (argument ',')*
  117. ## (argument [','] | '*' test (',' argument)* [',' '**' test] | '**' test)
  118. arglist ::= argument_commas arglist2
  119. argument_commas ::= argument_commas argument_comma
  120. argument_commas ::=
  121. argument_comma ::= argument COMMA
  122. ## (argument [','] | '*' test (',' argument)* [',' '**' test] | '**' test)
  123. arglist2 ::= argument comma_opt
  124. arglist2 ::= START test comma_arguments comma_starstar_test_opt
  125. arglist2 ::= STARSTAR test
  126. comma_arguments ::= comma_argument*
  127. comma_argument ::= COMMA argument
  128. comma_starstar_test_opt ::= COMMA STARSTAR test
  129. comma_starstar_test_opt ::=
  130. ## Really [keyword '='] test
  131. ## argument ::= test [gen_for] | test '=' test
  132. argument ::= test gen_for_opt
  133. argument ::= test EQUAL test
  134. ## list_iter ::= list_for | list_if
  135. list_iter ::= list_for
  136. list_iter ::= list_if
  137. ## list_for ::= 'for' exprlist 'in' testlist_safe [list_iter]
  138. list_for ::= FOR exprlist IN testlist_safe list_iter_opt
  139. list_iter_opt ::= list_iter?
  140. ## list_if ::= 'if' old_test [list_iter]
  141. list_if ::= IF old_test list_iter_opt
  142. gen_for_opt ::= gen_for?
  143. ## gen_iter ::= gen_for | gen_if
  144. gen_iter ::= gen_for
  145. gen_iter ::= gen_if
  146. ## gen_for ::= 'for' exprlist 'in' or_test [gen_iter]
  147. gen_for ::= FOR exprlist IN or_test gen_iter_opt
  148. gen_iter_opt ::= gen_iter?
  149. ## gen_if ::= 'if' old_test [gen_iter]
  150. gen_if ::= IF old_test gen_iter_opt
  151. ## testlist1 ::= test (',' test)*
  152. testlist1 ::= test comma_tests
  153. decorators ::= decorator+
  154. decorated ::= decorators classdef_or_funcdef
  155. classdef_or_funcdef ::= classdef
  156. classdef_or_funcdef ::= funcdef
  157. funcdef ::= DEF NAME parameters COLON suite
  158. parameters ::= LPAREN varargslist_opt RPAREN
  159. varargslist_opt ::= varargslist?
  160. # FILL IN
  161. ## varargslist ::= fpdef ['=' test] ',')* ('*' NAME [',' '**' NAME] | '**' NAME)
  162. ## varargslist ::= fpdef ['=' test] (',' fpdef ['=' test])* [',']
  163. varargslist ::= fpdef eq_test_opt comma_fpdef_opt_eqtests comma_opt
  164. ## (',' fpdef ['=' test])*
  165. comma_fpdef_opt_eqtests ::= comma_fpdef_opt_eqtests COMMA fpdef eq_test_opt
  166. comma_fpdef_opt_eqtests ::=
  167. star_names ::= star_names STAR NAME star_star_opt
  168. star_names ::= star_names star_star_opt
  169. star_names ::=
  170. eq_tests ::= eq_tests eq_test
  171. eq_tests ::=
  172. eq_test_opt ::= eq_test?
  173. eq_test ::= EQUAL test
  174. star_star_opt ::= COMMA STAR_STAR NAME
  175. star_star_opt ::=
  176. ## fpdef ::= NAME | '(' fplist ')'
  177. fpdef ::= NAME
  178. fpdef ::= LPAREN fplist RPAREN
  179. ## fplist ::= fpdef (',' fpdef)* [',']
  180. fplist ::= fpdef fplist1 comma_opt
  181. ## (',' fpdef)* [',']
  182. fplist1 ::= fplist COMMA fpdef
  183. fplist1 ::=
  184. comma_opt ::= COMMA?
  185. stmt ::= simple_stmt
  186. stmt ::= compound_stmt
  187. simple_stmt ::= small_stmt
  188. small_stmt ::= expr_stmt
  189. small_stmt ::= print_stmt
  190. small_stmt ::= del_stmt
  191. small_stmt ::= pass_stmt
  192. small_stmt ::= flow_stmt
  193. small_stmt ::= import_stmt
  194. small_stmt ::= global_stmt
  195. small_stmt ::= exec_stmt
  196. small_stmt ::= assert_stmt
  197. ## expr_stmt ::= testlist (augassign (yield_expr|testlist)
  198. ## | ('=' (yield_expr|testlist))*)
  199. expr_stmt ::= testlist AUGASSIGN yield_expr_or_testlist
  200. expr_stmt ::= testlist EQUAL yield_expr_or_testlists
  201. yield_expr_or_testlists ::= yield_expr_or_testlists yield_expr_or_testlist
  202. yield_expr_or_testlists ::= yield_expr_or_testlist
  203. yield_expr_or_testlist ::= yield_expr
  204. yield_expr_or_testlist ::= testlist
  205. ## yield_expr ::= 'yield' [testlist]
  206. yield_expr ::= YIELD testlist_opt
  207. print_stmt ::= PRINT test_params_or_redirect
  208. test_params_or_redirect ::= test comma_test_opt comma_opt
  209. # FIXME: go over Not quite right as there is one or more..
  210. test_params_or_redirect ::= REDIRECT test comma_test_opt comma_opt
  211. comma_test_opt ::= COMMA test
  212. comma_test_opt ::=
  213. del_stmt ::= DEL exprlist
  214. pass_stmt ::= PASS
  215. flow_stmt ::= break_stmt
  216. flow_stmt ::= continue_stmt
  217. flow_stmt ::= return_stmt
  218. flow_stmt ::= raise_stmt
  219. flow_stmt ::= yield_stmt
  220. break_stmt ::= BREAK
  221. continue_stmt ::= CONTINUE
  222. # return_stmt ::= 'return' [testlist]
  223. return_stmt ::= RETURN testlist_opt
  224. testlist_opt ::= testlist?
  225. yield_stmt ::= yield_expr
  226. raise_stmt ::= RAISE test_opt3
  227. test_opt3 ::= test COMMA test COMMA test
  228. test_opt3 ::= test COMMA test
  229. test_opt3 ::= test
  230. global_stmt ::= GLOBAL NAME comma_names
  231. comma_names ::= comma_name*
  232. comma_name ::= COMMA NAME
  233. exec_stmt ::= EXEC expr
  234. exec_stmt ::= EXEC expr IN test
  235. exec_stmt ::= EXEC expr IN test COMMA test
  236. assert_stmt ::= ASSERT test
  237. assert_stmt ::= ASSERT test COMMA test
  238. test_opt ::= test?
  239. ## exprlist ::= expr (',' expr)* [',']
  240. exprlist ::= expr comma_exprs comma_opt
  241. ## (',' expr)*
  242. comma_exprs ::= comma_exprs COMMA expr
  243. comma_exprs ::=
  244. # testlist ::= test (',' test)* [',']
  245. testlist ::= test comma_tests comma_opt
  246. # (',' test)*
  247. comma_tests ::= comma_tests COMMA test
  248. comma_tests ::=
  249. ## Backward compatibility cruft to support:
  250. ## [ x for x in lambda : True, lambda : False if x() ]
  251. ## even while also allowing:
  252. ## lambda x : 5 if x else 2
  253. ## (But not a mix of the two)
  254. ## testlist_safe ::= old_test [(',' old_test)+ [',']]
  255. testlist_safe ::= old_test testlist_safe1_opt
  256. testlist_safe1_opt ::= comma_old_tests comma_opt
  257. testlist_safe1_opt ::=
  258. ## (',' old_test)+
  259. comma_old_tests ::= comma_old_tests comma_old_test
  260. comma_old_tests ::= comma_old_test
  261. comma_old_test ::= COMMA old_test
  262. ## old_test ::= or_test | old_lambdef
  263. old_test ::= or_test
  264. old_test ::= old_lambdef
  265. ## old_lambdef ::= 'lambda' [varargslist] ':' old_test
  266. old_lambdef ::= LAMBDA varargslist_opt COLON old_test
  267. test ::= or_test IF or_test ELSE test
  268. test ::= or_test
  269. test ::= lambdef
  270. or_test ::= and_test or_and_tests
  271. ## ('or' and_test)*
  272. or_and_tests ::= or_and_test*
  273. or_and_test ::= OR and_test
  274. ## and_test ::= not_test ('and' not_test)*
  275. and_test ::= not_test and_not_tests
  276. ## ('and' not_test)*
  277. and_not_tests ::= and_not_tests AND not_test
  278. and_not_tests ::=
  279. ## not_test ::= 'not' not_test | comparison
  280. not_test ::= NOT not_test
  281. not_test ::= comparison
  282. ## comparison ::= expr (comp_op expr)*
  283. comparison ::= expr comp_op_exprs
  284. ## (comp_op expr)*
  285. comp_op_exprs ::= comp_op_exprs comp_op expr
  286. comp_op_exprs ::=
  287. comp_op ::= COMP_OP
  288. comp_op ::= IN
  289. comp_op ::= IS
  290. comp_op ::= IS NOT
  291. # Condensation of this
  292. ## expr ::= xor_expr ('|' xor_expr)*
  293. ## xor_expr ::= and_expr ('^' and_expr)*
  294. ## and_expr ::= shift_expr ('&' shift_expr)*
  295. ## shift_expr ::= arith_expr (('<<'|'>>') arith_expr)*
  296. ## arith_expr ::= term (('+'|'-') term)*
  297. ## term ::= factor (('*'|'/'|'%'|'//') factor)*
  298. ## We don't care about operator precidence
  299. expr ::= factor binop_arith_exprs
  300. binop_arith_exprs ::= binop_arith_exprs binop factor
  301. binop_arith_exprs ::=
  302. binop ::= BINOP
  303. binop ::= PLUS
  304. binop ::= MINUS
  305. binop ::= STAR
  306. ## factor ::= ('+'|'-'|'~') factor | power
  307. factor ::= op_factor factor
  308. factor ::= power
  309. op_factor ::= PLUS
  310. op_factor ::= MINUS
  311. op_factor ::= TILDE
  312. power ::= atom trailers starstar_factor_opt
  313. ## atom ::= ('(' [yield_expr|testlist_gexp] ')' | '[' [listmaker] ']'
  314. ## | '{' [dictmaker] '}' | '`' testlist1 '`'
  315. ## | NAME | NUMBER | STRING+)
  316. atom ::= LPAREN yield_expr_or_testlist_gexp_opt RPAREN
  317. atom ::= LBRACKET listmaker_opt RBRACKET
  318. atom ::= LBRACE dictmaker_opt RBRACE
  319. atom ::= BACKTICK testlist1 BACKTICK
  320. atom ::= NUMBER
  321. atom ::= NAME
  322. atom ::= strings
  323. dictmaker_opt ::= dictmaker?
  324. ## [yield_expr|testlist_gexp]
  325. yield_expr_or_testlist_gexp_opt ::= yield_expr
  326. yield_expr_or_testlist_gexp_opt ::= testlist_gexp
  327. yield_expr_or_testlist_gexp_opt ::=
  328. listmaker_opt ::= listmaker?
  329. ## listmaker ::= test ( list_for | (',' test)* [','] )
  330. listmaker ::= test list_for_or_comma_tests_comma_opt
  331. list_for_or_comma_tests_comma_opt ::= list_for
  332. list_for_or_comma_tests_comma_opt ::= comma_tests comma_opt
  333. ## testlist_gexp ::= test ( gen_for | (',' test)* [','] )
  334. testlist_gexp ::= test gen_for_or_comma_tests_comma_opt
  335. gen_for_or_comma_tests_comma_opt ::= gen_for
  336. gen_for_or_comma_tests_comma_opt ::= comma_tests comma_opt
  337. lambdef ::= LAMBDA varargslist_opt COLON test
  338. trailers ::= trailer*
  339. ## trailer ::= '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
  340. trailer ::= LPAREN arglist_opt RPAREN
  341. trailer ::= LBRACKET subscriptlist RBRACKET
  342. trailer ::= DOT NAME
  343. ## subscriptlist ::= subscript (',' subscript)* [',']
  344. subscriptlist ::= subscript comma_subscripts comma_opt
  345. ## (',' subscript)*
  346. comma_subscripts ::= comma_subscripts comma_subscript
  347. comma_subscripts ::=
  348. ## ',' subscript
  349. comma_subscript ::= COMMA subscript
  350. ## subscript ::= '.' '.' '.' | test | [test] ':' [test] [sliceop]
  351. subscript ::= DOT DOT DOT
  352. subscript ::= test
  353. subscript ::= test_opt COLON test_opt sliceop_opt
  354. sliceop_opt ::= sliceop?
  355. ## sliceop ::= ':' [test]
  356. sliceop ::= COLON test_opt
  357. starstar_factor_opt ::= STARSTAR factor
  358. starstar_factor_opt ::=
  359. ## dictmaker ::= test ':' test (',' test ':' test)* [',']
  360. dictmaker ::= test COLON comma_test_colon_tests comma_opt
  361. ## (',' test ':' test)*
  362. comma_test_colon_tests ::= comma_test_colon_tests comma_test_colon_test
  363. comma_test_colon_tests ::=
  364. ## (',' test ':' test)
  365. comma_test_colon_test ::= COMMA test COLON test
  366. classdef ::= CLASS NAME class_subclass_opt COLON suite
  367. class_subclass_opt ::= LPAREN testlist_opt RPAREN
  368. class_subclass_opt ::=
  369. strings ::= STRING+
  370. sep ::= comments
  371. sep ::= NEWLINE
  372. sep ::= SEMICOLON
  373. comments ::= comment+
  374. comment ::= COMMENT
  375. comment ::= COMMENT NEWLINE
  376. """
  377. # Import-related grammar
  378. def p_import(self, args):
  379. r"""
  380. ## import_stmt ::= import_name | import_from
  381. import_stmt ::= import_name
  382. import_stmt ::= import_from
  383. ## import_name ::= IMPORT dotted_as_names
  384. import_name ::= IMPORT dotted_as_names
  385. ## import_from ::= ('from' ('.'* dotted_name | '.'+)
  386. ## 'import' ('*' | '(' import_as_names ')' | import_as_names))
  387. import_from ::= FROM dots_dotted_name_or_dots import_list
  388. import_as_name ::= NAME
  389. import_as_name ::= NAME AS NAME
  390. dotted_as_name ::= dotted_name
  391. dotted_as_name ::= dotted_name AS NAME
  392. dots_dotted_name_or_dots ::= dots dotted_name
  393. dots_dotted_name_or_dots ::= DOT dots
  394. dots ::= DOT*
  395. ## 'import' ('*' | '(' import_as_names ')' | import_as_names))
  396. import_list ::= IMPORT STAR
  397. import_list ::= IMPORT LPAREN import_as_names RPAREN
  398. import_list ::= IMPORT import_as_names
  399. ## import_as_names ::= import_as_name ((',' import_as_name)+\) [',']
  400. # Note: we don't do the opt comma at the end
  401. import_as_names ::= import_as_name comma_import_as_names
  402. ## (',' import_as_name)+
  403. comma_import_as_names ::= comma_import_as_names comma_import_as_name
  404. comma_import_as_names ::=
  405. ## ',' import_as_name
  406. comma_import_as_name ::= COMMA import_as_name
  407. comma_dotted_as_names ::= dotted_as_name+
  408. dotted_as_names ::= dotted_as_name comma_dotted_as_names
  409. comma_dotted_as_names ::= comma_dotted_as_names COMMA dotted_as_name
  410. comma_dotted_as_names ::=
  411. dotted_name ::= NAME dot_names
  412. dot_names ::= dot_names DOT NAME
  413. dot_names ::=
  414. """
  415. def p_compund_stmt(self, args):
  416. """
  417. compound_stmt ::= if_stmt
  418. compound_stmt ::= while_stmt
  419. compound_stmt ::= for_stmt
  420. compound_stmt ::= try_stmt
  421. compound_stmt ::= with_stmt
  422. compound_stmt ::= funcdef
  423. compound_stmt ::= classdef
  424. compound_stmt ::= decorated
  425. if_stmt ::= IF test COLON suite elif_suites else_suite_opt
  426. if_stmt ::= IF test COLON NEWLINE suite elif_suites else_suite_opt
  427. elif_suites ::= elif_suites ELIF test COLON suite
  428. elif_suites ::=
  429. else_suite_opt ::= ELSE COLON suite
  430. else_suite_opt ::=
  431. ## while_stmt ::= 'while' test ':' suite ['else' ':' suite]
  432. while_stmt ::= WHILE test COLON suite else_suite_opt
  433. ## for_stmt ::= 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]
  434. for_stmt ::= FOR exprlist IN testlist COLON suite else_colon_suite_opt
  435. ## ['else' ':' suite]
  436. else_colon_suite_opt ::= ELSE COLON suite
  437. else_colon_suite_opt ::=
  438. ## try_stmt ::= ('try' ':' suite
  439. ## ((except_clause ':' suite)+
  440. ## ['else' ':' suite]
  441. ## ['finally' ':' suite] |
  442. ## 'finally' ':' suite))
  443. ## with_stmt ::= with' test [ with_var ] ':' suite
  444. with_stmt ::= WITH test with_var_opt COLON suite
  445. with_var_opt ::= with_var?
  446. ## with_var ::= 'as' expr
  447. with_var ::= AS expr
  448. suite ::= stmt_plus
  449. suite ::= NEWLINE indent stmt_plus NEWLINE DEDENT
  450. suite ::= NEWLINE indent stmt_plus DEDENT
  451. indent ::= INDENT comments
  452. indent ::= INDENT
  453. """
  454. def parse_python2(
  455. python_stmts,
  456. start="file_input",
  457. show_tokens=False,
  458. parser_debug=DEFAULT_DEBUG,
  459. check=False,
  460. ):
  461. assert isinstance(python_stmts, str)
  462. tokens = Python2Scanner().tokenize(python_stmts)
  463. if show_tokens:
  464. for t in tokens:
  465. print(t)
  466. # For heavy grammar debugging:
  467. # parser_debug = {'rules': True, 'transition': True, 'reduce': True,
  468. # 'errorstack': 'full', 'context': True, 'dups': True}
  469. # Normal debugging:
  470. # parser_debug = {'rules': False, 'transition': False, 'reduce': True,
  471. # 'errorstack': 'full', 'context': True, 'dups': True}
  472. parser = PythonParser(start=start, debug=parser_debug)
  473. if check:
  474. parser.check_grammar()
  475. return parser.parse(tokens)
  476. if __name__ == "__main__":
  477. if len(sys.argv) == 1:
  478. for python2_stmts in (
  479. # # "if True: pass",
  480. # """
  481. # while True:
  482. # if False:
  483. # continue
  484. # """,
  485. # "if True: pass",
  486. """return f()""",
  487. ):
  488. print(python2_stmts)
  489. print("-" * 30)
  490. ast = parse_python2(
  491. python2_stmts + ENDMARKER,
  492. start="file_input",
  493. show_tokens=False,
  494. check=True,
  495. )
  496. print(ast)
  497. print("=" * 30)
  498. else:
  499. python2_stmts = " ".join(sys.argv[1:])
  500. parse_python2(python2_stmts, show_tokens=False, check=True)