예제 #1
0
def test_regex():
    assert (rload(r'A <- "a"') == grm({'A': Regex(r'a')}))
    assert (rload(r'A <- "a" [bc]') == grm({'A': Regex(r'a[bc]')}))
    assert (rload(r'A <- ~("a" [bc])') == grm({'A': Capture(Regex(r'a[bc]'))}))
    assert (rload(r'A <- "a" B  B <- [bc]') == grm({
        'A':
        Sequence(Regex('a'), Nonterminal('B')),
        'B':
        Regex('[bc]')
    }))
    assert (rload(r'A <- .* "a"') == grm(
        {'A': Regex(r'(?=(?P<_1>(?s:.)*))(?P=_1)a')}))
    assert (rload(r'A <- "a"* [bc]+') == grm(
        {'A': Regex(r'(?=(?P<_1>a*))(?P=_1)(?=(?P<_2>[bc]+))(?P=_2)')}))
    assert (rload(r'A <- "a" ~([bc] / "d")*') == grm({
        'A':
        Sequence(
            Regex(r'a'),
            Capture(
                Regex(r'(?=(?P<_2>(?:(?=(?P<_1>[bc]|d))(?P=_1))*))(?P=_2)')))
    }))
    assert (rload(r'A <- "ab" / "abc"') == grm(
        {'A': Regex(r'(?=(?P<_1>ab|abc))(?P=_1)')}))
    assert (rload(r'A <- "a"* / ~"b"') == grm(
        {'A': Choice(Regex(r'(?=(?P<_1>a*))(?P=_1)'), Capture(Regex(r'b')))}))
예제 #2
0
def test_loads_def():
    assert loads('A <- "a"') == ('A', {'A': Literal('a')})
    assert loads('A <- "a"  # comment') == ('A', {'A': Literal('a')})
    assert loads('A <- "a" "b"') == ('A', {'A': Sequence('a', 'b')})
    assert loads('A <- "a" B <- "b"') == ('A', {
        'A': Literal('a'),
        'B': Literal('b')
    })
    assert loads('''
        A   <- "a" Bee
        Bee <- "b"
    ''') == ('A', {
        'A': Sequence('a', Nonterminal('Bee')),
        'Bee': Literal('b')
    })
예제 #3
0
파일: _parse.py 프로젝트: goodmami/pe
def _make_sequential(exprs):
    if len(exprs) == 1:
        return exprs[0]
    elif len(exprs) > 1:
        return Sequence(*exprs)
    else:
        raise Error(f'empty sequence: {exprs}')
예제 #4
0
def test_Sequence():
    assert (Sequence(Literal('a'),
                     Dot()) == Def(Op.SEQ, ([Literal('a'), Dot()], )))
    assert Sequence('foo', 'bar') == Sequence(Literal('foo'), Literal('bar'))
    # simple optimizations
    assert Sequence(Dot()) == Dot()
    assert Sequence(Sequence('a', 'b'), 'c') == Sequence('a', 'b', 'c')
예제 #5
0
def _regex_sequence(defn, defs, grpid):
    _subdefs = [_regex(subdef, defs, grpid) for subdef in defn.args[0]]
    subdefs = []
    for k, grp in groupby(_subdefs, key=lambda d: d.op):
        # only join regexes in sequence if unstructured
        if k == RGX:
            subdefs.append(Regex(''.join(d.args[0] for d in grp)))
        else:
            subdefs.extend(grp)

    return Sequence(*subdefs)
예제 #6
0
def test_common():
    assert (cload(r'A <- "a"') == gload(r'A <- "a"'))
    assert (cload(r'A <- !"a"') == gload(r'A <- !"a"'))
    assert (cload(r'A <- !"a"') == gload(r'A <- !"a"'))
    # single-char classes to literals
    assert (cload(r'A <- [a]') == gload(r'A <- "a"'))
    # but not single-range
    assert (cload(r'A <- [a-c]') == gload(r'A <- [a-c]'))
    # add "b" to avoid dropping the sequence
    assert (cload(r'A <- !"a" . "b"') == cload(r'A <- ![a] . "b"') == grm(
        {'A': Sequence(Class('a', negate=True), Literal('b'))}))
    # now show the dropped sequence
    assert (cload(r'A <- !"a" .') == cload(r'A <- ![a] .') == grm(
        {'A': Class('a', negate=True)}))
    # sequence of literals to literal
    assert (cload(r'A <- "a" "bc" "d"') == gload(r'A <- "abcd"'))
    # but not sequence with classes
    assert (cload(r'A <- "a" [bc] "d"') == gload(r'A <- "a" [bc] "d"'))
    # choice of classes or single-char literals
    assert (cload(r'A <- [ab] / "m" / [yz]') == gload(r'A <- [abmyz]'))
    # not negated classes though
    assert (cload(r'A <- (![ab] .) / "m" / [yz]') == grm(
        {'A': Choice(Class('ab', negate=True), Class('myz'))}))
예제 #7
0
from pe import Match
from pe.operators import Literal, Sequence, Capture, Bind, Rule
from pe.actions import Pack

One = Literal('1')
CaptureOne = Capture(Literal('1'))
OneTwo = Sequence(Literal('1'), Literal('2'))
OneCaptureTwo = Sequence(Literal('1'), Capture(Literal('2')))
OneBindTwo = Sequence(Literal('1'), Bind(Literal('2'), name='x'))
OneBindCaptureTwo = Sequence(Literal('1'), Bind(Capture(Literal('2')),
                                                name='x'))
OneTwoRule = Rule(Sequence(Capture(Literal('1')), Capture(Literal('2'))),
                  action=Pack(list))


def test_Match_atom():
    m = Match('123', 0, 1, One, (), {})
    assert m.string == '123'
    assert m.start() == 0
    assert m.end() == 1
    assert m.span() == (0, 1)
    assert m.pe is One
    assert m.group(0) == '1'
    assert m.groups() == ()
    assert m.groupdict() == {}
    assert m.value() is None


def test_Match_capture_atom():
    m = Match('123', 0, 1, CaptureOne, ('1', ), {})
    assert m.string == '123'
예제 #8
0
def test_loads_sequence():
    assert eloads('"a" "b"') == Sequence('a', 'b')
    assert eloads('"a" "b"  # comment') == Sequence('a', 'b')
예제 #9
0
파일: _parse.py 프로젝트: goodmami/pe
        raise Error(f'empty sequence: {exprs}')


def _make_prioritized(exprs):
    if len(exprs) == 1:
        return exprs[0]
    elif len(exprs) > 1:
        return Choice(*exprs)
    else:
        raise Error(f'empty choice: {exprs}')


V = SymbolTable()

# Hierarchical syntax
V.Start = Sequence(V.Spacing, Choice(V.Grammar, V.Expression), V.EOF)
V.Grammar = Plus(V.Definition)
V.Definition = Sequence(V.Identifier, V.LEFTARROW, V.Expression)
V.Expression = Sequence(V.Sequence, Star(Sequence(V.SLASH, V.Sequence)))
V.Sequence = Plus(V.Valued)
V.Valued = Sequence(Optional(Bind(V.Prefix, name='prefix')), V.Quantified)
V.Prefix = Choice(V.AND, V.NOT, V.TILDE, V.Binding)
V.Binding = Sequence(V.Identifier, ':', V.Spacing)
V.Quantified = Sequence(V.Primary,
                        Optional(Bind(V.Quantifier, name='quantifier')))
V.Quantifier = Choice(V.QUESTION, V.STAR, V.PLUS)
V.Primary = Choice(V.Name, V.Group, V.Literal, V.Class, V.DOT)
V.Name = Sequence(V.Identifier, V.Spacing, Not(V.LEFTARROW))
V.Group = Sequence(V.OPEN, V.Expression, V.CLOSE)
V.Literal = Sequence(
    Choice(Capture(Sequence("'", Star(Sequence(Not("'"), V.Char)), "'")),