File: test_parse.py

package info (click to toggle)
pypy 7.0.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 107,216 kB
  • sloc: python: 1,201,787; ansic: 62,419; asm: 5,169; cpp: 3,017; sh: 2,534; makefile: 545; xml: 243; lisp: 45; awk: 4
file content (81 lines) | stat: -rw-r--r-- 3,556 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
from rpython.rlib.parsing.lexer import Token, SourcePos
from rpython.rlib.parsing.parsing import *

class EvaluateVisitor(object):
    def visit_additive(self, node):
        if len(node.children) == 1:
            return node.children[0].visit(self)
        else:
            return node.children[0].visit(self) + node.children[2].visit(self)
    def visit_multitive(self, node):
        if len(node.children) == 1:
            return node.children[0].visit(self)
        else:
            return node.children[0].visit(self) * node.children[2].visit(self)
    def visit_primary(self, node):
        if len(node.children) == 1:
            return node.children[0].visit(self)
        else:
            return node.children[1].visit(self)
    def visit_decimal(self, node):
        return int(node.children[0].symbol)

def test_simple_packrat():
    class ToAstVisistor(object):
        def visit_additive(self, node):
            if len(node.children) == 1:
                return node.children[0].visit(self)
            return Nonterminal(
                "additive", [node.children[0].visit(self),
                             node.children[2].visit(self)])
        def visit_multitive(self, node):
            if len(node.children) == 1:
                return node.children[0].visit(self)
            return Nonterminal(
                "multitive", [node.children[0].visit(self),
                              node.children[2].visit(self)])
        def visit_primary(self, node):
            if len(node.children) == 1:
                return node.children[0].visit(self)
            return node.children[1].visit(self)
        def visit_decimal(self, node):
            return Nonterminal(
                    "decimal",
                    [Symbol(int(node.children[0].symbol), "", None)])
    r1 = Rule("additive", [["multitive", "+", "additive"], ["multitive"]])
    r2 = Rule("multitive", [["primary", "*", "multitive"], ["primary"]])
    r3 = Rule("primary", [["(", "additive", ")"], ["decimal"]])
    r4 = Rule("decimal", [[symb] for symb in "0123456789"])
    p = PackratParser([r1, r2, r3, r4], "additive")
    print p.parse([Token(c, c, SourcePos(i, 0, i)) for i, c in enumerate("2*(3+4)")])
    tree = p.parse([Token(c, c, SourcePos(i, 0, i)) for i, c in enumerate("2*2*2*(7*3+4+5*6)")])
    ast = tree.visit(ToAstVisistor())
    tree = p.parse([Token(c, c, SourcePos(i, 0, i)) for i, c in enumerate("2*(3+4)")])
    r = tree.visit(EvaluateVisitor())
    assert r == 14
    tree = p.parse([Token(c, c, SourcePos(i, 0, i)) for i, c in enumerate("2*(3+5*2*(2+6))")])
    print tree
    r = tree.visit(EvaluateVisitor())
    assert r == 166

def test_bad():
    r1 = Rule("S", [["x", "S", "x"], ["x"]])
    p = PackratParser([r1], "S")
    assert p.parse([Token(c, c, SourcePos(i, 0, i)) for i, c in enumerate("xxxxxxxxxxxxxxx")]) is not None
    
def test_leftrecursion_detection():
    r1 = Rule("A", [["A"]])
    py.test.raises(AssertionError, PackratParser, [r1], "A")
    r1 = Rule("A", [["B"]])
    r2 = Rule("B", [["A"]])
    py.test.raises(AssertionError, PackratParser, [r1, r2], "B")

def test_epsilon():
    r1 = Rule("S", [["x", "S", "x"], ["y"], []])
    p = PackratParser([r1], "S")
    assert p.parse([Token(c, i, SourcePos(i, 0, i))
                        for i, c, in enumerate("xyx")]) is not None
    assert p.parse([Token(c, i, SourcePos(i, 0, i))
                        for i, c, in enumerate("xx")]) is not None
    t = p.parse([Token(c, i, SourcePos(i, 0, i))
                     for i, c, in enumerate("xxxxxx")])