a
    
3jr                     @   s  d dl Z d dlZd dlZd dlmZ d dlmZmZ d dlm	Z	m
Z
mZmZmZ ed edh d dlmZ d dlmZmZmZ d dlmZmZmZ d d	lmZ d d
lmZ d dlm Z  W d   n1 s0    Y  G dd dej!Z"G dd dZ#G dd dej!Z$dS )    N)
test_tools)DictAny)	TokenInfoNAMENEWLINENUMBEROPZpeg_generator)GeneratedParser)parse_stringgenerate_parsermake_parser)GrammarVisitorGrammarErrorGrammar)ASTGrammarPrinter)Parser)PythonParserGeneratorc                   @   s  e Zd ZddddZddddZddddZddd	d
ZddddZddddZddddZ	ddddZ
ddddZddddZddddZddddZddddZddddZdddd Zddd!d"Zddd#d$Zddd%d&Zddd'd(Zddd)d*Zddd+d,Zddd-d.Zddd/d0Zddd1d2Zddd3d4Zddd5d6Zddd7d8Zddd9d:Zddd;d<Zddd=d>Z ddd?d@Z!dS )A	TestPegenNreturnc                 C   sv   d}d}t |t}|j}| t|t|  | t|d d | t|d d d}| t|d | d S )	Nzl
        start: sum NEWLINE
        sum: t1=term '+' t2=term { action } | term
        term: NUMBER
        [
        start: sum NEWLINE
        sum: term '+' term | term
        term: NUMBER
        startstart: sum NEWLINEsumsum: term '+' term | termzERule('term', None, Rhs([Alt([NamedItem(None, NameLeaf('NUMBER'))])]))term)	r   GrammarParserrulesassertEqualstrtextwrapdedentstriprepr)selfgrammar_sourceexpectedgrammarr   Zexpected_repr r)   ^/www/server/python_manager/versions/3.9.10/lib/python3.9/test/test_peg_generator/test_pegen.pytest_parse_grammar   s    
zTestPegen.test_parse_grammarc                 C   s6   d}d}t |t}| t|jd t|  d S )Nzt
        start: zero | one | one zero | one one | one zero zero | one zero one | one one zero | one one one
        z
        start:
            | zero
            | one
            | one zero
            | one one
            | one zero zero
            | one zero one
            | one one zero
            | one one one
        r   )r   r   r   r    r   r!   r"   r#   )r%   r&   r'   r(   r)   r)   r*   test_long_rule_str,   s    
zTestPegen.test_long_rule_strc                 C   sP   d}t |tj}| t|d d | t|d d | t|d d d S )Nz{
        start[int]: sum NEWLINE
        sum[int]: t1=term '+' t2=term { action } | term
        term[int]: NUMBER
        r   r   r   r   r   zFRule('term', 'int', Rhs([Alt([NamedItem(None, NameLeaf('NUMBER'))])])))r   r   r   r   r    r$   )r%   r(   r   r)   r)   r*   test_typed_rules>   s    
zTestPegen.test_typed_rulesc                 C   sp   d}t |tj}| t|d d | t|d d | t|d d t|}t d|}t d|}d S )	NA
        start: ','.thing+ NEWLINE
        thing: NUMBER
        r   zstart: ','.thing+ NEWLINEzXRule('start', None, Rhs([Alt([NamedItem(None, Gather(StringLeaf("','"), NameLeaf('thing'thingzthing: NUMBER42
z1, 2
)	r   r   r   r   r    
assertTruer$   
startswithr   )r%   r(   r   parser_classnoder)   r)   r*   test_gatherM   s    

zTestPegen.test_gatherc                 C   sJ   d}t |}td|}| |ttdddddggttdddddg d S )	Nr   r0   Z42   r   r7      stringr   endline
r7      r   r   r   r   r   r   r%   r(   r3   r4   r)   r)   r*   test_expr_grammarg   s    
zTestPegen.test_expr_grammarc                 C   s   d}t |}td|}| |ttdddddgttdddddttd	dd
ddgggttdd
dddg td|}| |ttdddddgd gttdddddg d S )NzW
        start: sum NEWLINE
        sum: term ('+' term)?
        term: NUMBER
        z1+2
1r6   r7   r7   r:   +r8   2r?   r>   r7      1
r   r   r   r   r   r	   r   rB   r)   r)   r*   test_optional_operatort   s     


z TestPegen.test_optional_operatorc                 C   s   d}t |}td|}| |ttdddddgttdddddgttd	dd
ddg td|}| |ttdddddgd gttd	ddddg d S )NzQ
        start: sum NEWLINE
        sum: term '+' ?
        term: NUMBER
        z1+
rD   r6   rE   r:   rF   r8   r>   r?   rJ   rK   rB   r)   r)   r*   test_optional_literal   s    

zTestPegen.test_optional_literalc                 C   s   d}t |}td|}| |ttdddddgttddd	ddttd
ddddgggttdddddg td|}| |ttdddddgd gttdddddg d S )NzV
        start: sum NEWLINE
        sum: term ['+' term]
        term: NUMBER
        z1 + 2
rD   r6   rE   r:   rF   r8   r?   rG   rH   r7      r>   r7      rJ   rK   rB   r)   r)   r*   test_alt_optional_operator   s     


z$TestPegen.test_alt_optional_operatorc                 C   s   d}t |}td|}| |ttdddddgttddd	ddggttd
ddddgggttdddddg td|}| |ttdddddgg ttdddddg d S )NzC
        start: thing thing* NEWLINE
        thing: NUMBER
        1 2 3
rD   r6   rE   r:   rG   r8   r?   3rH   rN   r>   rP   rJ   rA   rB   r)   r)   r*   test_repeat_0_simple   s     

zTestPegen.test_repeat_0_simplec                 C   s   d}t |}td|}| |ttdddddgttddd	ddttd
ddddgggttdddddttdddddggggttdddddg d S )NzF
        start: term ('+' term)* NEWLINE
        term: NUMBER
        
1 + 2 + 3
rD   r6   rE   r:   rF   r8   r?   rG   rH   rN   rP   r7      rT   r7      r7   	   r>   r7   
   rK   rB   r)   r)   r*   test_repeat_0_complex   s     
zTestPegen.test_repeat_0_complexc                 C   s   d}t |}td|}| |ttdddddgttddd	ddggttd
ddddgggttdddddg | t td| W d    n1 s0    Y  d S )NzC
        start: thing thing+ NEWLINE
        thing: NUMBER
        rS   rD   r6   rE   r:   rG   r8   r?   rT   rH   rN   r>   rP   rJ   )r   r   r   r   r   r   assertRaisesSyntaxErrorrB   r)   r)   r*   test_repeat_1_simple   s    
zTestPegen.test_repeat_1_simplec                 C   s   d}t |}td|}| |ttdddddgttddd	ddttd
ddddgggttdddddttdddddggggttdddddg | t td| W d    n1 s0    Y  d S )NzF
        start: term ('+' term)+ NEWLINE
        term: NUMBER
        rV   rD   r6   rE   r:   rF   r8   r?   rG   rH   rN   rP   rW   rT   rY   r[   r>   r]   rJ   )	r   r   r   r   r   r	   r   r`   ra   rB   r)   r)   r*   test_repeat_1_complex   s$    
zTestPegen.test_repeat_1_complexc                 C   sn   d}t |}td|}| |ttdddddgttddd	ddgttd
ddddggttdddddg d S )Nr.   z1, 2, 3
rD   r6   rE   r:   rG   r?   rH   rT   rP   rW   r>   rY   rA   rB   r)   r)   r*   test_repeat_with_sep_simple  s    
z%TestPegen.test_repeat_with_sep_simplec                 C   s  d}t |t}t|}|j}| |d j | |d j | |d j | |d j | |d j | |d j t d|}| |tt	d	d
dddggtt
dddddtt	dddddggtt
dddddtt	dddddggttdddddg d S )Nz
        start: expr NEWLINE
        expr: ('-' term | expr '+' term | term)
        term: NUMBER
        foo: NAME+
        bar: NAME*
        baz: NAME?
        r   exprr   foobarZbazrV   rD   r6   rE   r:   rF   r8   r?   rG   rH   rN   rP   rW   rT   rY   r[   r>   r]   )r   r   r   r   assertFalseleft_recursiver1   r   r   r   r	   r   )r%   r&   r(   r3   r   r4   r)   r)   r*   test_left_recursive'  s*    

	zTestPegen.test_left_recursivec                 C   s:   d}t |}td|}t|dd}t|}| |d d S )Na  
        start: expr NEWLINE? $ { ast.Expression(expr, lineno=1, col_offset=0) }
        expr: ( expr '+' term { ast.BinOp(expr, ast.Add(), term, lineno=expr.lineno, col_offset=expr.col_offset, end_lineno=term.end_lineno, end_col_offset=term.end_col_offset) }
            | expr '-' term { ast.BinOp(expr, ast.Sub(), term, lineno=expr.lineno, col_offset=expr.col_offset, end_lineno=term.end_lineno, end_col_offset=term.end_col_offset) }
            | term { term }
            )
        term: ( l=term '*' r=factor { ast.BinOp(l, ast.Mult(), r, lineno=l.lineno, col_offset=l.col_offset, end_lineno=r.end_lineno, end_col_offset=r.end_col_offset) }
            | l=term '/' r=factor { ast.BinOp(l, ast.Div(), r, lineno=l.lineno, col_offset=l.col_offset, end_lineno=r.end_lineno, end_col_offset=r.end_col_offset) }
            | factor { factor }
            )
        factor: ( '(' expr ')' { expr }
                | atom { atom }
                )
        atom: ( n=NAME { ast.Name(id=n.string, ctx=ast.Load(), lineno=n.start[0], col_offset=n.start[1], end_lineno=n.end[0], end_col_offset=n.end[1]) }
            | n=NUMBER { ast.Constant(value=ast.literal_eval(n.string), lineno=n.start[0], col_offset=n.start[1], end_lineno=n.end[0], end_col_offset=n.end[1]) }
            )
        z(1 + 2*3 + 5)/(6 - 2)
 evalg      @)r   r   compilerl   r   )r%   r(   r3   r4   codevalr)   r)   r*   test_python_exprG  s    
zTestPegen.test_python_exprc                 C   sJ   d}t |t}t }t||}|j}| |d j | |d j d S )Nz>
        start: sign NUMBER
        sign: ['-' | '+']
        r   sign)	r   r   ioStringIOr   r   rh   nullabler1   r%   r&   r(   outgenrr   r)   r)   r*   test_nullable_  s    

zTestPegen.test_nullablec                 C   sj   d}t |t}t }t||}|j}| |d j | |d j | |d j	 | |d j	 d S )Nz@
        start: NUMBER | sign start
        sign: ['-']
        r   rq   )
r   r   rr   rs   r   r   rh   rt   r1   ri   ru   r)   r)   r*   test_advanced_left_recursivek  s    

z&TestPegen.test_advanced_left_recursivec           	      C   sR  d}t |t}t }t||}|j}| |d j | |d j | |d j |	d i }t
| | |d }t d|}| |ttdd	d
ddgttdddddgttdddddgttdddddgttdddddg t d|}| | | |ttdd	d
ddgttdddddgttdddddgttdddddg d S )NzV
        start: foo 'E'
        foo: bar 'A' | 'B'
        bar: foo 'C' | 'D'
        r   rf   rg   <string>r
   z	D A C A EDr6   rE   )typer;   r   r<   r=   Ar8   r?   CrH   rN   rP   rW   ErY   r[   zB C A EB)r   r   rr   rs   r   r   rh   ri   r1   generateexecgetvaluer   r   r   ZassertIsNotNone)	r%   r&   r(   rv   rw   r   nsr3   r4   r)   r)   r*   test_mutually_left_recursivey  sB    






z&TestPegen.test_mutually_left_recursivec                 C   s|   d}t |t}t }t||}|d i }t| | |d }| t	 t d| W d    n1 sn0    Y  d S )Nzf
        start: target '='
        target: maybe '+' | NAME
        maybe: maybe '-' | target
        rz   r
   zx - + =)
r   r   rr   rs   r   r   r   r   r`   ra   )r%   r&   r(   rv   rw   r   r3   r)   r)   r*   "test_nasty_mutually_left_recursive  s    



z,TestPegen.test_nasty_mutually_left_recursivec                 C   s   d}t |}td|}| |ttdddddgttddd	ddttd
ddddgttdddddttd
ddddgggggggg d S )Nz
        start: (expr_stmt | assign_stmt) &'.'
        expr_stmt: !(target '=') expr
        assign_stmt: target '=' expr
        expr: term ('+' term)*
        target: NAME
        term: NUMBER
        zfoo = 12 + 12 .rf   r6   r?   r:   =rH   rN   Z12rP   rY   rF   r[   r]   )r7      )r7      )r   r   r   r   r   r	   r   rB   r)   r)   r*   test_lookahead  s@    

zTestPegen.test_lookaheadc                 C   s:   d}|  t t| W d    n1 s,0    Y  d S )Nz&
        start: foo=!'x' NAME
        )r`   ra   r   r%   r(   r)   r)   r*   test_named_lookahead_error  s    z$TestPegen.test_named_lookahead_errorc                 C   s   d}t | d S )NzA
        start: attr | NAME
        attr: start '.' NAME
        r   r   r)   r)   r*   test_start_leader  s    zTestPegen.test_start_leaderc                 C   s   d}t | d S )Nz 
        start: [NAME*]
        r   r   r)   r)   r*   test_opt_sequence  s    zTestPegen.test_opt_sequencec                 C   sP   d}|  t.}t| | dt|jjv  W d    n1 sB0    Y  d S )Nz
        start: foo
        foo: bar '+' | baz '+' | '+'
        bar: baz '-' | foo '-' | '-'
        baz: foo '*' | bar '*' | '*'
        z	no leader)r`   
ValueErrorr   r1   r    	exceptionvalue)r%   r(   Zerrinfor)   r)   r*   test_left_recursion_too_complex  s    z)TestPegen.test_left_recursion_too_complexc                 C   sX   d}t |}td|}| |ttdddddttdddddgttd	dd
ddg d S )Nz<
        start: '(' ~ expr ')'
        expr: NUMBER
        z(1)(r6   rE   r:   rD   r8   )r?   )r   r   r   r   r	   r   rB   r)   r)   r*   test_cut  s    
zTestPegen.test_cutc                 C   s:   d}|  t t|}W d    n1 s,0    Y  d S )Nz<
        start: foo ENDMARKER
        foo: bar NAME
        r`   r   r   r%   r(   r3   r)   r)   r*   test_dangling_reference  s    z!TestPegen.test_dangling_referencec                 C   s:   d}|  t t|}W d    n1 s,0    Y  d S )Nz/
        start: foo
        foo: NAMEE
        r   r   r)   r)   r*   test_bad_token_reference&  s    z"TestPegen.test_bad_token_referencec                 C   s:   d}|  t t|}W d    n1 s,0    Y  d S )Nz
        foo: NAME
        r   r   r)   r)   r*   test_missing_start.  s    zTestPegen.test_missing_startc                 C   s<   d}|  td t|}W d    n1 s.0    Y  d S )Nz<
        start: _a b
        _a: 'a'
        b: 'b'
        z"cannot start with underscore: '_a'ZassertRaisesRegexr   r   r   r)   r)   r*   test_invalid_rule_name5  s    z TestPegen.test_invalid_rule_namec                 C   s<   d}|  td t|}W d    n1 s.0    Y  d S )Nz=
        start: a b
        a: _x='a'
        b: 'b'
        "cannot start with underscore: '_x'r   r   r)   r)   r*   test_invalid_variable_name>  s    z$TestPegen.test_invalid_variable_namec                 C   s<   d}|  td t|}W d    n1 s.0    Y  d S )NzK
        start: a b
        a: (_x='a' | 'b') | 'c'
        b: 'b'
        r   r   r   r)   r)   r*   +test_invalid_variable_name_in_temporal_ruleG  s    z5TestPegen.test_invalid_variable_name_in_temporal_rule)"__name__
__module____qualname__r+   r,   r-   r5   rC   rL   rM   rR   rU   r_   rb   rc   rd   rj   rp   rx   ry   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r)   r)   r)   r*   r      s>    ,1		r   c                   @   sb   e Zd ZG dd deZddddZddddZddd	d
ZddddZddddZ	dS )TestGrammarVisitorc                       s6   e Zd ZddddZeeedd fddZ  ZS )zTestGrammarVisitor.VisitorNr   c                 C   s
   d| _ d S )Nr   )n_nodes)r%   r)   r)   r*   __init__S  s    z#TestGrammarVisitor.Visitor.__init__)r4   argskwargsr   c                    s,   |  j d7  _ t j|g|R i | d S )Nr7   )r   supervisit)r%   r4   r   r   	__class__r)   r*   r   V  s    z TestGrammarVisitor.Visitor.visit)r   r   r   r   r   r   __classcell__r)   r)   r   r*   VisitorR  s   r   Nr   c                 C   s2   d}t |t}|  }|| | |jd d S )Nz
        start: 'a'
        rQ   r   r   r   r   r   r   r%   r(   r   Zvisitorr)   r)   r*   test_parse_trivial_grammarZ  s
    

z-TestGrammarVisitor.test_parse_trivial_grammarc                 C   s2   d}t |t}|  }|| | |jd d S )Nz5
        start: rule
        rule: 'a' | 'b'
           r   r   r)   r)   r*   test_parse_or_grammare  s
    

z(TestGrammarVisitor.test_parse_or_grammarc                 C   s2   d}t |t}|  }|| | |jd d S )Nz
        start: 'a'+
        rX   r   r   r)   r)   r*   test_parse_repeat1_grammarv  s
    

z-TestGrammarVisitor.test_parse_repeat1_grammarc                 C   s2   d}t |t}|  }|| | |jd d S )Nz
        start: 'a'*
        rX   r   r   r)   r)   r*   test_parse_repeat0_grammar  s
    

z-TestGrammarVisitor.test_parse_repeat0_grammarc                 C   s2   d}t |t}|  }|| | |jd d S )Nz"
        start: 'a' ['b']
           r   r   r)   r)   r*   test_parse_optional_grammar  s
    

z.TestGrammarVisitor.test_parse_optional_grammar)
r   r   r   r   r   r   r   r   r   r   r)   r)   r)   r*   r   Q  s   r   c                   @   s6   e Zd ZddddZddddZddddZdS )	TestGrammarVisualizerNr   c                 C   sL   d}t |t}t }g }|j||jd d|}td}| || d S )Nz 
        start: 'a' 'b'
        printerr>   u           └──Rule
           └──Rhs
              └──Alt
                 ├──NamedItem
                 │  └──StringLeaf("'a'")
                 └──NamedItem
                    └──StringLeaf("'b'")
        	r   r   r   Zprint_grammar_astappendjoinr!   r"   r   r%   r(   r   r   linesoutputZexpected_outputr)   r)   r*   test_simple_rule  s    

z&TestGrammarVisualizer.test_simple_rulec                 C   sL   d}t |t}t }g }|j||jd d|}td}| || d S )Nz:
        start: a b
        a: 'a'
        b: 'b'
        r   r>   u;          └──Rule
           └──Rhs
              └──Alt
                 ├──NamedItem
                 │  └──NameLeaf('a')
                 └──NamedItem
                    └──NameLeaf('b')

        └──Rule
           └──Rhs
              └──Alt
                 └──NamedItem
                    └──StringLeaf("'a'")

        └──Rule
           └──Rhs
              └──Alt
                 └──NamedItem
                    └──StringLeaf("'b'")
                        r   r   r)   r)   r*   test_multiple_rules  s    

z)TestGrammarVisualizer.test_multiple_rulesc                 C   sL   d}t |t}t }g }|j||jd d|}td}| || d S )Nz,
        start: 'a' ['b'['c'['d']]]
        r   r>   u          └──Rule
           └──Rhs
              └──Alt
                 ├──NamedItem
                 │  └──StringLeaf("'a'")
                 └──NamedItem
                    └──Opt
                       └──Rhs
                          └──Alt
                             ├──NamedItem
                             │  └──StringLeaf("'b'")
                             └──NamedItem
                                └──Opt
                                   └──Rhs
                                      └──Alt
                                         ├──NamedItem
                                         │  └──StringLeaf("'c'")
                                         └──NamedItem
                                            └──Opt
                                               └──Rhs
                                                  └──Alt
                                                     └──NamedItem
                                                        └──StringLeaf("'d'")
                                r   r   r)   r)   r*   test_deep_nested_rule  s    

z+TestGrammarVisualizer.test_deep_nested_rule)r   r   r   r   r   r   r)   r)   r)   r*   r     s   'r   )%rr   r!   Zunittesttestr   typingr   r   tokenizer   r   r   r   r	   Zskip_if_missingZimports_under_toolZpegen.grammar_parserr
   r   Zpegen.testutilr   r   r   Zpegen.grammarr   r   r   Zpegen.grammar_visualizerr   Zpegen.parserr   Zpegen.python_generatorr   ZTestCaser   r   r   r)   r)   r)   r*   <module>   s(   
*    >M