
    dafBL                        d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlm	Z	 d dl
mZ d dl
mZ d dlmZmZ d dlmZ  ej$                         r ej&                  d       ej(                  d        ej*                  d      5  d d	lmZ d d
lmZmZmZ ddd       dZ ej<                          G d dej>                               Z y# 1 sw Y   5xY w)    N)Path)
test_tools)support)	os_helperimport_helper)assert_python_okz+peg_generator test disabled under PGO buildpeg_generator)GeneratedParser)parse_stringgenerate_parser_c_extensiongenerate_c_parser_sourcea  
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()
c                   (   e Zd ZdZed        Z ej                         d        Zd Z	d Z
d Zd!dZd!d	Zd!d
Zd!dZd!dZd!dZd!dZd!dZd!dZd!dZd!dZd!dZd!dZd!dZd!dZd!dZd!dZd!dZd!dZd!dZd!dZ d!dZ!d!dZ"d!dZ#d!d Z$y)"TestCParserFc                 &   | j                   rt        j                  d      d| _         t        j                         | _        t        j                  j                  | j
                  t        j                        rd | _        t        j                  | j
                        | _        | j                  t        j                  | j                         t!        j"                         5 }|j%                  t'        j(                  d            }t+        j,                  |ddgd      j/                         }|j%                  t1        j2                  |             | j                  |j5                         j6                         d d d        y # 1 sw Y   y xY w)Nz.gh-105063: can not rerun because of ref. leaksTdirvenv-cz6import sysconfig; print(sysconfig.get_path('platlib')))text)_has_rununittestSkipTestosgetcwdtmp_basepathsamefiler   SAVEDCWDtempfilemkdtemplibrary_diraddClassCleanupshutilrmtree
contextlib	ExitStackenter_contextr   $setup_venv_with_pip_setuptools_wheel
subprocesscheck_outputstripr   DirsOnSysPathpop_allclose)clsstack
python_exesitepackagess       @/root/Python-3.12.4/Lib/test/test_peg_generator/test_c_parser.py
setUpClasszTestCParser.setUpClassM   s&   <<
 ##$TUU yy{77CLL)*<*<=CL #**s||<FMM3??;!!# 	7u,,W-Y-YZ`-abJ%22T#[\ eg   ; ;L IJ 5 56	7 	7 	7s   $BFFc                 l   t        t        j                        | _        t	        j
                         }|| j                  d|z         t        j                         | _	        t        j                  | j                        | _        | j                  t        j                   | j                               y )NzThe %r command is not foundr   )dict	sysconfig_CONFIG_VARS_backup_config_varsr   missing_compiler_executableskipTestr   r   old_cwdr   r    r   tmp_pathenterContextr   
change_cwd)selfcmds     r3   setUpzTestCParser.setUpn   sz    #'	(>(>#? 113?MM7#=>yy{ ((T]];)..t}}=>    c                    t        j                  | j                         t        j                  | j
                         t        j                  j                          t        j                  j                  | j                         y )N)r   chdirr<   r#   r$   r=   r7   r8   clearupdater9   )r@   s    r3   tearDownzTestCParser.tearDownx   sN    
dmm$$$&%%d&>&>?rC   c                 f    t        |t              }t        |t        d      | j                         y )N.)r!   )r   GrammarParserr   r   r!   )r@   grammar_sourcegrammars      r3   build_extensionzTestCParser.build_extension~   s&    ~}= 	$GT#YDDTDTUrC   c                     | j                  |       t        j                  t        j                  |      d      }t	        dt
        j                  | j                  |             y )Nz        r   )extension_pathtest_source)rN   textwrapindentdedentr   TEST_TEMPLATEformatr=   r@   rL   rQ   s      r3   run_testzTestCParser.run_test   sK    ^,oohook&BGL  ; W	
rC   Nc                 0    d}d}| j                  ||       y )Na  
        start[mod_ty]: a[asdl_stmt_seq*]=stmt* $ { _PyAST_Module(a, NULL, p->arena) }
        stmt[stmt_ty]: a=expr_stmt { a }
        expr_stmt[stmt_ty]: a=expression NEWLINE { _PyAST_Expr(a, EXTRA) }
        expression[expr_ty]: ( l=expression '+' r=term { _PyAST_BinOp(l, Add, r, EXTRA) }
                            | l=expression '-' r=term { _PyAST_BinOp(l, Sub, r, EXTRA) }
                            | t=term { t }
                            )
        term[expr_ty]: ( l=term '*' r=factor { _PyAST_BinOp(l, Mult, r, EXTRA) }
                    | l=term '/' r=factor { _PyAST_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))
        rX   rW   s      r3   test_c_parserzTestCParser.test_c_parser   s     ($ 	nk2rC   c                 0    d}d}| j                  ||       y )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)
        rZ   rW   s      r3   test_lookaheadzTestCParser.test_lookahead        
 	nk2rC   c                 0    d}d}| j                  ||       y )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)
        rZ   rW   s      r3   test_negative_lookaheadz#TestCParser.test_negative_lookahead   r^   rC   c                 0    d}d}| j                  ||       y )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)
        rZ   rW   s      r3   test_cutzTestCParser.test_cut   s     
 	nk2rC   c                 0    d}d}| j                  ||       y )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)
        rZ   rW   s      r3   test_gatherzTestCParser.test_gather   r^   rC   c                 0    d}d}| j                  ||       y )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)
        rZ   rW   s      r3   test_left_recursionzTestCParser.test_left_recursion        
 	nk2rC   c                 0    d}d}| j                  ||       y )Nz@
        start: NUMBER | sign start
        sign: ['-']
        zg
        valid_cases = ["23", "-34"]
        self.check_input_strings_for_grammar(valid_cases)
        rZ   rW   s      r3   test_advanced_left_recursivez(TestCParser.test_advanced_left_recursive         	nk2rC   c                 0    d}d}| j                  ||       y )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)
        rZ   rW   s      r3   test_mutually_left_recursivez(TestCParser.test_mutually_left_recursive  rg   rC   c                 0    d}d}| j                  ||       y )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)
        rZ   rW   s      r3   "test_nasty_mutually_left_recursivez.TestCParser.test_nasty_mutually_left_recursive  s     

 	nk2rC   c                 0    d}d}| j                  ||       y )Nao  
        start[mod_ty]: a=[statements] ENDMARKER { _PyAST_Module(a, NULL, p->arena) }
        statements[asdl_stmt_seq*]: a[asdl_stmt_seq*]=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 { _PyAST_Return(NULL, EXTRA) }
        zJ
        stmt = "return"
        self.verify_ast_generation(stmt)
        rZ   rW   s      r3   test_return_stmt_noexpr_actionz*TestCParser.test_return_stmt_noexpr_action        	nk2rC   c                 0    d}d}| j                  ||       y )Nz
        start[mod_ty]: a[asdl_stmt_seq*]=';'.pass_stmt+ NEWLINE ENDMARKER { _PyAST_Module(a, NULL, p->arena) }
        pass_stmt[stmt_ty]: a='pass' { _PyAST_Pass(EXTRA)}
        zN
        stmt = "pass; pass"
        self.verify_ast_generation(stmt)
        rZ   rW   s      r3   test_gather_action_astz"TestCParser.test_gather_action_ast)  rj   rC   c                 0    d}d}| j                  ||       y )Naa  
        start[mod_ty]: a=[statements] ENDMARKER { _PyAST_Module(a, NULL, p->arena) }
        statements[asdl_stmt_seq*]: a[asdl_stmt_seq*]=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 { _PyAST_Pass(EXTRA) }
        H
        stmt = "pass"
        self.verify_ast_generation(stmt)
        rZ   rW   s      r3   test_pass_stmt_actionz!TestCParser.test_pass_stmt_action4  rq   rC   c                 0    d}d}| j                  ||       y )Nak  
        start[mod_ty]: a=[statements] ENDMARKER { _PyAST_Module(a, NULL, p->arena) }
        statements[asdl_stmt_seq*]: a=statement+ { (asdl_stmt_seq*)_PyPegen_seq_flatten(p, a) }
        statement[asdl_stmt_seq*]:  a=compound_stmt { (asdl_stmt_seq*)_PyPegen_singleton_seq(p, a) } | simple_stmt

        simple_stmt[asdl_stmt_seq*]: a=small_stmt b=further_small_stmt* [';'] NEWLINE {
                                            (asdl_stmt_seq*)_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 { _PyAST_If(a, b, NULL, EXTRA) }

        small_stmt[stmt_ty]: pass_stmt

        pass_stmt[stmt_ty]: a='pass' { _PyAST_Pass(EXTRA) }

        full_expression: NAME
        ru   rZ   rW   s      r3   test_if_stmt_actionzTestCParser.test_if_stmt_actionC  s     * 	nk2rC   c                 0    d}d}| j                  ||       y )Na  
        start[mod_ty]: a[asdl_stmt_seq*]=import_from+ NEWLINE ENDMARKER { _PyAST_Module(a, NULL, p->arena)}
        import_from[stmt_ty]: ( a='from' !'import' c=simple_name 'import' d=import_as_names_from {
                                _PyAST_ImportFrom(c->v.Name.id, d, 0, EXTRA) }
                            | a='from' '.' 'import' c=import_as_names_from {
                                _PyAST_ImportFrom(NULL, c, 1, EXTRA) }
                            )
        simple_name[expr_ty]: NAME
        import_as_names_from[asdl_alias_seq*]: a[asdl_alias_seq*]=','.import_as_name_from+ { a }
        import_as_name_from[alias_ty]: a=NAME 'as' b=NAME { _PyAST_alias(((expr_ty) a)->v.Name.id, ((expr_ty) b)->v.Name.id, EXTRA) }
        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))
        rZ   rW   s      r3   test_same_name_different_typesz*TestCParser.test_same_name_different_types_  s     
 	nk2rC   c                 0    d}d}| j                  ||       y )NaW  
        start[mod_ty]: a=[statements] ENDMARKER { _PyAST_Module(a, NULL, p->arena) }
        statements[asdl_stmt_seq*]: a=statement+ { (asdl_stmt_seq*)_PyPegen_seq_flatten(p, a) }
        statement[asdl_stmt_seq*]: a=compound_stmt { (asdl_stmt_seq*)_PyPegen_singleton_seq(p, a) }
        compound_stmt[stmt_ty]: with_stmt
        with_stmt[stmt_ty]: (
            a='with' '(' b[asdl_withitem_seq*]=','.with_item+ ')' ':' c=block {
                _PyAST_With(b, (asdl_stmt_seq*) _PyPegen_singleton_seq(p, c), NULL, EXTRA) }
        )
        with_item[withitem_ty]: (
            e=NAME o=['as' t=NAME { t }] { _PyAST_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' { _PyAST_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()))]"
        ))
        rZ   rW   s      r3   test_with_stmt_with_parenz%TestCParser.test_with_stmt_with_parens  s      	nk2rC   c                 0    d}d}| j                  ||       y )Na~  
        start[mod_ty]: a=expr ENDMARKER { _PyAST_Module(a, NULL, p->arena) }
        expr[asdl_stmt_seq*]: a=listcomp NEWLINE { (asdl_stmt_seq*)_PyPegen_singleton_seq(p, _PyAST_Expr(a, EXTRA)) }
        listcomp[expr_ty]: (
            a='[' b=NAME c=for_if_clauses d=']' { _PyAST_ListComp(b, c, EXTRA) }
        )
        for_if_clauses[asdl_comprehension_seq*]: (
            a[asdl_comprehension_seq*]=(y=[ASYNC] 'for' a=NAME 'in' b=NAME c[asdl_expr_seq*]=('if' z=NAME { z })*
                { _PyAST_comprehension(_PyAST_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)
        rZ   rW   s      r3   test_ternary_operatorz!TestCParser.test_ternary_operator  s     
 	nk2rC   c                 0    d}d}| j                  ||       y )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 "<string>", line 1' in tb)
            self.assertTrue(f"SyntaxError: invalid syntax" in tb)
        rZ   rW   s      r3   test_syntax_error_for_stringz(TestCParser.test_syntax_error_for_string  s      	nk2rC   c                     d}t        |t              }t        |      }| j                  d|v        | j                  d|v        | j                  d|v        y )Nz
        @header 'SOME HEADER'
        @subheader 'SOME SUBHEADER'
        @trailer 'SOME TRAILER'
        start: expr+ NEWLINE? ENDMARKER
        expr: x=NAME
        zSOME HEADERzSOME SUBHEADERzSOME TRAILER)r   rK   r   
assertTruer@   rL   rM   parser_sources       r3   test_headers_and_trailerz$TestCParser.test_headers_and_trailer  sU     ~}=0967(M9:-78rC   c                 0    d}d}| j                  ||       y )NzV
        start: expr+ NEWLINE? ENDMARKER
        expr: NAME {PyTuple_New(-1)}
        zb
        with self.assertRaises(SystemError):
            parse.parse_string("a", mode=0)
        rZ   rW   s      r3   test_error_in_ruleszTestCParser.test_error_in_rules  s     
 	nk2rC   c                 J    d}t        |t              }t        |      }d|vsJ y )NzE
        start: expr+ NEWLINE? ENDMARKER
        expr: 'foo'
        expect_soft_keywordr   rK   r   r   s       r3   test_no_soft_keywordsz!TestCParser.test_no_soft_keywords  s/     ~}=09$M999rC   c                 J    d}t        |t              }t        |      }d|v sJ y )NzE
        start: expr+ NEWLINE? ENDMARKER
        expr: "foo"
        r   r   r   s       r3   test_soft_keywordszTestCParser.test_soft_keywords  s/     ~}=09$555rC   c                 0    d}d}| j                  ||       y )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)
        rZ   rW   s      r3   test_soft_keywords_parsez$TestCParser.test_soft_keywords_parse  r^   rC   c                 0    d}d}| j                  ||       y )NzL
        start: &"if" "if" expr '+' expr NEWLINE
        expr: NAME
        r   rZ   rW   s      r3   test_soft_keywords_lookaheadz(TestCParser.test_soft_keywords_lookahead  r^   rC   c                 0    d}d}| j                  ||       y )Nz*
        start: NAME &&':' | NAME
        z
        self.assertEqual(parse.parse_string("number :", mode=0), None)
        with self.assertRaises(SyntaxError) as e:
            parse.parse_string("a", mode=0)
        self.assertIn("expected ':'", str(e.exception))
        rZ   rW   s      r3   test_forcedzTestCParser.test_forced  s      	nk2rC   c                 0    d}d}| j                  ||       y )Nz2
        start: NAME &&(':' | ';') | NAME
        a8  
        self.assertEqual(parse.parse_string("number :", mode=0), None)
        self.assertEqual(parse.parse_string("number ;", mode=0), None)
        with self.assertRaises(SyntaxError) as e:
            parse.parse_string("a", mode=0)
        self.assertIn("expected (':' | ';')", e.exception.args[0])
        rZ   rW   s      r3   test_forced_with_groupz"TestCParser.test_forced_with_group   s      	nk2rC   )returnN)%__name__
__module____qualname__r   classmethodr4   r   requires_venv_with_piprB   rH   rN   rX   r[   r]   r`   rb   rd   rf   ri   rl   rn   rp   rs   rv   rx   rz   r|   r~   r   r   r   r   r   r   r   r   r    rC   r3   r   r   H   s     H7 7@ $W##%? &?@V
'3R
3
33 
3
3	3
333	33383(343$3 9
3:6
3
3
33rC   r   )!r%   r)   r7   rR   r   r   r#   r   pathlibr   testr   r   test.supportr   r   test.support.script_helperr   check_cflags_pgor   skip_if_missingimports_under_toolpegen.grammar_parserr
   rK   pegen.testutilr   r   r   rU   requires_subprocessTestCaser   r   rC   r3   <module>r      s         	      1 77
(

I
JJ 
  ? +"Z""?3 E (V B3(## B3 B3k s   CC