예제 #1
0
def test_maybe_2():
    program = ("start: [foo]\n" "foo: NAME\n")
    rules = start(program).rules
    assert rules == [
        Rule('start', [Alt([Maybe('foo')])]),
        Rule('foo', [Alt(['NAME'])])
    ]
예제 #2
0
def test_grammar():
    program = ("stmt: asmt | expr\n" "asmt: NAME '=' expr\n" "expr: NAME\n")
    rules = start(program).rules
    assert rules == [
        Rule('stmt', [Alt(['asmt']), Alt(['expr'])]),
        Rule('asmt', [Alt(['NAME', "'='", 'expr'])]),
        Rule('expr', [Alt(['NAME'])])
    ]
예제 #3
0
def test_maybe_3():
    program = ("start: [foo foo | foo]\n" "foo: NAME\n")
    rules = start(program).rules
    assert rules == [
        Rule('start', [Alt([Maybe('_synthetic_rule_0')])]),
        Rule('foo', [Alt(['NAME'])]),
        Rule('_synthetic_rule_0',
             [Alt(['foo', 'foo']), Alt(['foo'])])
    ]
예제 #4
0
def test_group():
    program = ("start: (foo foo | foo)\n" "foo: NAME\n")
    rules = start(program).rules
    assert rules == [
        Rule('start', [Alt(['_synthetic_rule_0'])]),
        Rule('foo', [Alt(['NAME'])]),
        Rule('_synthetic_rule_0',
             [Alt(['foo', 'foo']), Alt(['foo'])])
    ]
예제 #5
0
def test_named_item():
    program = ("start: f=foo\n" "foo: n=NAME\n")
    file = StringIO(program)
    tokengen = generate_tokens(file.readline)
    tok = Tokenizer(tokengen)
    p = GrammarParser(tok)
    rules = p.start().rules
    assert rules == [
        Rule('start', [Alt([NamedItem('f', 'foo')])]),
        Rule('foo', [Alt([NamedItem('n', 'NAME')])])
    ]
예제 #6
0
def test_action():
    program = "start: NAME { foo + bar } | NUMBER { -baz }\n"
    rules = start(program).rules
    assert rules == [
        Rule("start", [Alt(["NAME"], "foo + bar"),
                       Alt(["NUMBER"], "- baz")])
    ]
    assert rules != [
        Rule("start", [Alt(["NAME"], "foo + bar"),
                       Alt(["NUMBER"], "baz")])
    ]
예제 #7
0
 def synthetic_rule(self, alts):
     if len(alts) == 1 and len(alts[0].items) == 1:
         return alts[0].items[0]
     name = f"_synthetic_rule_{len(self.extra_rules)}"
     rule = Rule(name, alts)
     self.extra_rules.append(rule)
     return rule.name
예제 #8
0
def test_indents2():
    program = ("stmt:\n"
               "    | foo | bar\n"
               "    | baz\n"
               "    | booh | bah\n"
               "foo: bar\n")
    rules = start(program).rules
    assert rules == [
        Rule('stmt', [
            Alt(['foo']),
            Alt(['bar']),
            Alt(['baz']),
            Alt(['booh']),
            Alt(['bah'])
        ]),
        Rule('foo', [Alt(['bar'])])
    ]
예제 #9
0
 def rule(self):
     self.show_rule('rule', [[
         'NAME', '":"', 'alts', 'NEWLINE', 'INDENT', 'more_alts', 'DEDENT'
     ], ['NAME', '":"', 'NEWLINE', 'INDENT', 'more_alts', 'DEDENT'],
                             ['NAME', '":"', 'alts', 'NEWLINE']])
     pos = self.mark()
     if (True and self.show_index(0, 0)
             and (name := self.expect(NAME)) is not None
             and self.show_index(0, 1) and self.expect(":") is not None
             and self.show_index(0, 2) and (alts := self.alts()) is not None
             and self.show_index(0, 3)
             and (newline := self.expect(NEWLINE)) is not None
             and self.show_index(0, 4)
             and (indent := self.expect(INDENT)) is not None
             and self.show_index(0, 5)
             and (more_alts := self.more_alts()) is not None
             and self.show_index(0, 6)
             and (dedent := self.expect(DEDENT)) is not None):
         self.show_index(0, 0, 7)
         retval = Rule(name.string, alts + more_alts)
         if retval is not None:
             return retval
예제 #10
0
     retval = Rule(name.string, alts + more_alts)
     if retval is not None:
         return retval
 self.reset(pos)
 if (True and self.show_index(1, 0) and
     (name := self.expect(NAME)) is not None and self.show_index(1, 1)
         and self.expect(":") is not None and self.show_index(1, 2)
         and (newline := self.expect(NEWLINE)) is not None
         and self.show_index(1, 3)
         and (indent := self.expect(INDENT)) is not None
         and self.show_index(1, 4)
         and (more_alts := self.more_alts()) is not None
         and self.show_index(1, 5)
         and (dedent := self.expect(DEDENT)) is not None):
     self.show_index(1, 0, 6)
     retval = Rule(name.string, more_alts)
     if retval is not None:
         return retval
 self.reset(pos)
 if (True and self.show_index(2, 0)
         and (name := self.expect(NAME)) is not None
         and self.show_index(2, 1) and self.expect(":") is not None
         and self.show_index(2, 2) and (alts := self.alts()) is not None
         and self.show_index(2, 3)
         and (newline := self.expect(NEWLINE)) is not None):
     self.show_index(2, 0, 4)
     retval = Rule(name.string, alts)
     if retval is not None:
         return retval
 self.reset(pos)
 self.show_index(0, 0, 0)
예제 #11
0
def test_meta():
    program = ("@start 'start'\n" "@foo bar\n" "@bar\n" "stmt: foo\n")
    grammar = start(program)
    assert grammar
    assert grammar.rules == [Rule('stmt', [Alt(["foo"])])]
    assert grammar.metas == [('start', 'start'), ('foo', 'bar'), ('bar', None)]
예제 #12
0
def test_cut():
    program = "start: NAME ~ NAME\n"
    rules = start(program).rules
    assert rules == [Rule('start', [Alt(['NAME', Cut(), 'NAME'])])]
예제 #13
0
def test_lookahead_negative():
    program = "start: !NUMBER NAME\n"
    rules = start(program).rules
    assert rules == [
        Rule('start', [Alt([Lookahead('NUMBER', False), 'NAME'])])
    ]
예제 #14
0
def test_lookahead():
    program = "start: &NUMBER NAME\n"
    rules = start(program).rules
    assert rules == [Rule('start', [Alt([Lookahead('NUMBER'), 'NAME'])])]
예제 #15
0
def test_plus():
    program = "start: NAME+\n"
    rules = start(program).rules
    assert rules == [Rule('start', [Alt([Loop('NAME', True)])])]
예제 #16
0
def test_star():
    program = "start: NAME*\n"
    rules = start(program).rules
    assert rules == [Rule('start', [Alt([Loop('NAME')])])]