a  ze?@sddlZddlZddlZddlmZddlmZddlmZddlm Z ddl m Z e dZ e dZere ree vred ed ed <dd lmZdd lmZmZmZdd lmZWdn1s0YdZGdddeejZdS)N)TempdirManager)Path) test_tools)support)assert_python_okZPY_CFLAGS_NODISTZPGO_PROF_USE_FLAGz+peg_generator test disabled under PGO buildZ peg_generator)GeneratedParser) parse_stringgenerate_parser_c_extensiongenerate_c_parser_source)ast_dumpa tmp_dir = {extension_path!r} import ast import traceback import sys import unittest from test import test_tools with test_tools.imports_under_tool("peg_generator"): from pegen.ast_dump import ast_dump sys.path.insert(0, tmp_dir) import parse class Tests(unittest.TestCase): def check_input_strings_for_grammar( self, valid_cases = (), invalid_cases = (), ): if valid_cases: for case in valid_cases: parse.parse_string(case, mode=0) if invalid_cases: for case in invalid_cases: with self.assertRaises(SyntaxError): parse.parse_string(case, mode=0) def verify_ast_generation(self, stmt): expected_ast = ast.parse(stmt) actual_ast = parse.parse_string(stmt, mode=1) self.assertEqual(ast_dump(expected_ast), ast_dump(actual_ast)) def test_parse(self): {test_source} unittest.main() cszeZdZfddZfddZddZddZd d d d Zd d d dZd d ddZ d d ddZ d d ddZ d d ddZ d d ddZ d d ddZd d ddZd d ddZd d dd Zd d d!d"Zd d d#d$Zd d d%d&Zd d d'd(Zd d d)d*Zd d d+d,Zd d d-d.Zd d d/d0Zd d d1d2Zd d d3d4Zd d d5d6Zd d d7d8ZZS)9 TestCParsercs`t}|dur|d|tt|||_t|j}| | |j ddddS)NzThe %r command is not found) rZmissing_compiler_executableZskipTestsuperr setUpmkdtemptmp_path change_cwd __enter__Z addCleanup__exit__)selfcmdr __class__Y/opt/bitninja-python-dojo/embedded/lib/python3.9/test/test_peg_generator/test_c_parser.pyrGs  zTestCParser.setUpcstt|dSN)r r tearDown)rrrrrQszTestCParser.tearDowncCst|t}t|t|jdSr)r GrammarParserr rr)rgrammar_sourcegrammarrrrbuild_extensionTs zTestCParser.build_extensioncCs6||tt|d}tdtj|j|ddS)Nz z-c)Zextension_path test_source)rtextwrapindentdedentr TEST_TEMPLATEformatrrrr rrrrun_testXs  zTestCParser.run_testN)returncCsd}d}|||dS)Na~ start[mod_ty]: a=stmt* $ { Module(a, NULL, p->arena) } stmt[stmt_ty]: a=expr_stmt { a } expr_stmt[stmt_ty]: a=expression NEWLINE { _Py_Expr(a, EXTRA) } expression[expr_ty]: ( l=expression '+' r=term { _Py_BinOp(l, Add, r, EXTRA) } | l=expression '-' r=term { _Py_BinOp(l, Sub, r, EXTRA) } | t=term { t } ) term[expr_ty]: ( l=term '*' r=factor { _Py_BinOp(l, Mult, r, EXTRA) } | l=term '/' r=factor { _Py_BinOp(l, Div, r, EXTRA) } | f=factor { f } ) factor[expr_ty]: ('(' e=expression ')' { e } | a=atom { a } ) atom[expr_ty]: ( n=NAME { n } | n=NUMBER { n } | s=STRING { s } ) a expressions = [ "4+5", "4-5", "4*5", "1+4*5", "1+4/5", "(1+1) + (1+1)", "(1+1) - (1+1)", "(1+1) * (1+1)", "(1+1) / (1+1)", ] for expr in expressions: the_ast = parse.parse_string(expr, mode=1) expected_ast = ast.parse(expr) self.assertEqual(ast_dump(the_ast), ast_dump(expected_ast)) r'r&rrr test_c_parser`szTestCParser.test_c_parsercCsd}d}|||dS)NzW start: NAME &NAME expr NEWLINE? ENDMARKER expr: NAME | NUMBER z valid_cases = ["foo bar"] invalid_cases = ["foo 34"] self.check_input_strings_for_grammar(valid_cases, invalid_cases) r)r&rrrtest_lookaheadszTestCParser.test_lookaheadcCsd}d}|||dS)NzW start: NAME !NAME expr NEWLINE? ENDMARKER expr: NAME | NUMBER z valid_cases = ["foo 34"] invalid_cases = ["foo bar"] self.check_input_strings_for_grammar(valid_cases, invalid_cases) r)r&rrrtest_negative_lookaheadsz#TestCParser.test_negative_lookaheadcCsd}d}|||dS)Nzs start: X ~ Y Z | X Q S X: 'x' Y: 'y' Z: 'z' Q: 'q' S: 's' z valid_cases = ["x y z"] invalid_cases = ["x q s"] self.check_input_strings_for_grammar(valid_cases, invalid_cases) r)r&rrrtest_cutszTestCParser.test_cutcCsd}d}|||dS)NzI start: ';'.pass_stmt+ NEWLINE pass_stmt: 'pass' z valid_cases = ["pass", "pass; pass"] invalid_cases = ["pass;", "pass; pass;"] self.check_input_strings_for_grammar(valid_cases, invalid_cases) r)r&rrr test_gatherszTestCParser.test_gathercCsd}d}|||dS)Nzj start: expr NEWLINE expr: ('-' term | expr '+' term | term) term: NUMBER z valid_cases = ["-34", "34", "34 + 12", "1 + 1 + 2 + 3"] self.check_input_strings_for_grammar(valid_cases) r)r&rrrtest_left_recursionszTestCParser.test_left_recursioncCsd}d}|||dS)Nz@ start: NUMBER | sign start sign: ['-'] zg valid_cases = ["23", "-34"] self.check_input_strings_for_grammar(valid_cases) r)r&rrrtest_advanced_left_recursivesz(TestCParser.test_advanced_left_recursivecCsd}d}|||dS)NzV start: foo 'E' foo: bar 'A' | 'B' bar: foo 'C' | 'D' zn valid_cases = ["B E", "D A C A E"] self.check_input_strings_for_grammar(valid_cases) r)r&rrrtest_mutually_left_recursivesz(TestCParser.test_mutually_left_recursivecCsd}d}|||dS)Nzf start: target '=' target: maybe '+' | NAME maybe: maybe '-' | target z valid_cases = ["x ="] invalid_cases = ["x - + ="] self.check_input_strings_for_grammar(valid_cases, invalid_cases) r)r&rrr"test_nasty_mutually_left_recursivesz.TestCParser.test_nasty_mutually_left_recursivecCsd}d}|||dS)NaP start[mod_ty]: a=[statements] ENDMARKER { Module(a, NULL, p->arena) } statements[asdl_seq*]: a=statement+ { a } statement[stmt_ty]: simple_stmt simple_stmt[stmt_ty]: small_stmt small_stmt[stmt_ty]: return_stmt return_stmt[stmt_ty]: a='return' NEWLINE { _Py_Return(NULL, EXTRA) } zJ stmt = "return" self.verify_ast_generation(stmt) r)r&rrrtest_return_stmt_noexpr_actionsz*TestCParser.test_return_stmt_noexpr_actioncCsd}d}|||dS)Nz start[mod_ty]: a=';'.pass_stmt+ NEWLINE ENDMARKER { Module(a, NULL, p->arena) } pass_stmt[stmt_ty]: a='pass' { _Py_Pass(EXTRA)} zN stmt = "pass; pass" self.verify_ast_generation(stmt) r)r&rrrtest_gather_action_astsz"TestCParser.test_gather_action_astcCsd}d}|||dS)NaB start[mod_ty]: a=[statements] ENDMARKER { Module(a, NULL, p->arena) } statements[asdl_seq*]: a=statement+ { a } statement[stmt_ty]: simple_stmt simple_stmt[stmt_ty]: small_stmt small_stmt[stmt_ty]: pass_stmt pass_stmt[stmt_ty]: a='pass' NEWLINE { _Py_Pass(EXTRA) } H stmt = "pass" self.verify_ast_generation(stmt) r)r&rrrtest_pass_stmt_actionsz!TestCParser.test_pass_stmt_actioncCsd}d}|||dS)Na start[mod_ty]: a=[statements] ENDMARKER { Module(a, NULL, p->arena) } statements[asdl_seq*]: a=statement+ { _PyPegen_seq_flatten(p, a) } statement[asdl_seq*]: a=compound_stmt { _PyPegen_singleton_seq(p, a) } | simple_stmt simple_stmt[asdl_seq*]: a=small_stmt b=further_small_stmt* [';'] NEWLINE { _PyPegen_seq_insert_in_front(p, a, b) } further_small_stmt[stmt_ty]: ';' a=small_stmt { a } block: simple_stmt | NEWLINE INDENT a=statements DEDENT { a } compound_stmt: if_stmt if_stmt: 'if' a=full_expression ':' b=block { _Py_If(a, b, NULL, EXTRA) } small_stmt[stmt_ty]: pass_stmt pass_stmt[stmt_ty]: a='pass' { _Py_Pass(EXTRA) } full_expression: NAME r5r)r&rrrtest_if_stmt_actionszTestCParser.test_if_stmt_actioncCsd}d}|||dS)Na start[mod_ty]: a=import_from+ NEWLINE ENDMARKER { Module(a, NULL, p->arena)} import_from[stmt_ty]: ( a='from' !'import' c=simple_name 'import' d=import_as_names_from { _Py_ImportFrom(c->v.Name.id, d, 0, EXTRA) } | a='from' '.' 'import' c=import_as_names_from { _Py_ImportFrom(NULL, c, 1, EXTRA) } ) simple_name[expr_ty]: NAME import_as_names_from[asdl_seq*]: a=','.import_as_name_from+ { a } import_as_name_from[alias_ty]: a=NAME 'as' b=NAME { _Py_alias(((expr_ty) a)->v.Name.id, ((expr_ty) b)->v.Name.id, p->arena) } z for stmt in ("from a import b as c", "from . import a as b"): expected_ast = ast.parse(stmt) actual_ast = parse.parse_string(stmt, mode=1) self.assertEqual(ast_dump(expected_ast), ast_dump(actual_ast)) r)r&rrrtest_same_name_different_types1s z*TestCParser.test_same_name_different_typescCsd}d}|||dS)Na start[mod_ty]: a=[statements] ENDMARKER { Module(a, NULL, p->arena) } statements[asdl_seq*]: a=statement+ { _PyPegen_seq_flatten(p, a) } statement[asdl_seq*]: a=compound_stmt { _PyPegen_singleton_seq(p, a) } compound_stmt[stmt_ty]: with_stmt with_stmt[stmt_ty]: ( a='with' '(' b=','.with_item+ ')' ':' c=block { _Py_With(b, _PyPegen_singleton_seq(p, c), NULL, EXTRA) } ) with_item[withitem_ty]: ( e=NAME o=['as' t=NAME { t }] { _Py_withitem(e, _PyPegen_set_expr_context(p, o, Store), p->arena) } ) block[stmt_ty]: a=pass_stmt NEWLINE { a } | NEWLINE INDENT a=pass_stmt DEDENT { a } pass_stmt[stmt_ty]: a='pass' { _Py_Pass(EXTRA) } a stmt = "with (\n a as b,\n c as d\n): pass" the_ast = parse.parse_string(stmt, mode=1) self.assertTrue(ast_dump(the_ast).startswith( "Module(body=[With(items=[withitem(context_expr=Name(id='a', ctx=Load()), optional_vars=Name(id='b', ctx=Store())), " "withitem(context_expr=Name(id='c', ctx=Load()), optional_vars=Name(id='d', ctx=Store()))]" )) r)r&rrrtest_with_stmt_with_parenEsz%TestCParser.test_with_stmt_with_parencCsd}d}|||dS)Na start[mod_ty]: a=expr ENDMARKER { Module(a, NULL, p->arena) } expr[asdl_seq*]: a=listcomp NEWLINE { _PyPegen_singleton_seq(p, _Py_Expr(a, EXTRA)) } listcomp[expr_ty]: ( a='[' b=NAME c=for_if_clauses d=']' { _Py_ListComp(b, c, EXTRA) } ) for_if_clauses[asdl_seq*]: ( a=(y=[ASYNC] 'for' a=NAME 'in' b=NAME c=('if' z=NAME { z })* { _Py_comprehension(_Py_Name(((expr_ty) a)->v.Name.id, Store, EXTRA), b, c, (y == NULL) ? 0 : 1, p->arena) })+ { a } ) zW stmt = "[i for i in a if b]" self.verify_ast_generation(stmt) r)r&rrrtest_ternary_operator_s z!TestCParser.test_ternary_operatorcCsd}d}|||dS)NzD start: expr+ NEWLINE? ENDMARKER expr: NAME aa for text in ("a b 42 b a", "\u540d \u540d 42 \u540d \u540d"): try: parse.parse_string(text, mode=0) except SyntaxError as e: tb = traceback.format_exc() self.assertTrue('File "", line 1' in tb) self.assertTrue(f"SyntaxError: invalid syntax" in tb) r)r&rrrtest_syntax_error_for_stringqs z(TestCParser.test_syntax_error_for_stringcCsDd}t|t}t|}|d|v|d|v|d|vdS)Nz @header 'SOME HEADER' @subheader 'SOME SUBHEADER' @trailer 'SOME TRAILER' start: expr+ NEWLINE? ENDMARKER expr: x=NAME z SOME HEADERzSOME SUBHEADERz SOME TRAILER)rrr Z assertTruerrrZ parser_sourcerrrtest_headers_and_trailers  z$TestCParser.test_headers_and_trailercCsd}d}|||dS)NzV start: expr+ NEWLINE? ENDMARKER expr: NAME {PyTuple_New(-1)} zb with self.assertRaises(SystemError): parse.parse_string("a", mode=0) r)r&rrrtest_error_in_rulesszTestCParser.test_error_in_rulescCs&d}t|t}t|}d|vs"JdS)NzE start: expr+ NEWLINE? ENDMARKER expr: 'foo' expect_soft_keywordrrr r<rrrtest_no_soft_keywordss z!TestCParser.test_no_soft_keywordscCs&d}t|t}t|}d|vs"JdS)NzE start: expr+ NEWLINE? ENDMARKER expr: "foo" r?r@r<rrrtest_soft_keywordss zTestCParser.test_soft_keywordscCsd}d}|||dS)NzF start: "if" expr '+' expr NEWLINE expr: NAME valid_cases = ["if if + if"] invalid_cases = ["if if"] self.check_input_strings_for_grammar(valid_cases, invalid_cases) r)r&rrrtest_soft_keywords_parsesz$TestCParser.test_soft_keywords_parsecCsd}d}|||dS)NzL start: &"if" "if" expr '+' expr NEWLINE expr: NAME rCr)r&rrrtest_soft_keywords_lookaheadsz(TestCParser.test_soft_keywords_lookahead)__name__ __module__ __qualname__rrrr'r*r+r,r-r.r/r0r1r2r3r4r6r7r8r9r:r;r=r>rArBrDrE __classcell__rrrrr Fs6 )            r )Z sysconfigr!ZunittestZdistutils.tests.supportrpathlibrtestrrZtest.support.script_helperrZget_config_varZ_py_cflags_nodistZ _pgo_flagZSkipTestZskip_if_missingZimports_under_toolZpegen.grammar_parserrrZpegen.testutilrr r Zpegen.ast_dumpr r$ZTestCaser rrrrs$           *+