-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgrammar.gram
96 lines (74 loc) · 2.38 KB
/
grammar.gram
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
@class GrammarParser
@subheader """
from ast import literal_eval
from token import DEDENT, INDENT, OP
from search_parser.grammar import Grammar, Rule, Alt, NamedItem, Lookahead, Maybe, Loop, Cut
BaseParser = Parser
class Parser(BaseParser):
def __init__(self, tokenizer):
super().__init__(tokenizer)
self.extra_rules = []
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
"""
start: grammar ENDMARKER { grammar }
grammar:
| metas rules { Grammar(rules + self.extra_rules, metas) }
| rules { Grammar(rules + self.extra_rules, []) }
metas:
| meta metas { [meta] + metas }
| meta { [meta] }
meta:
| "@" NAME NEWLINE { (name.string, None) }
| "@" NAME NAME NEWLINE { (name.string, name1.string) }
| "@" NAME STRING NEWLINE { (name.string, literal_eval(string.string)) }
rules:
| rule rules { [rule] + rules }
| rule { [rule] }
rule:
| NAME ":" alts NEWLINE INDENT more_alts DEDENT { Rule(name.string, alts + more_alts) }
| NAME ":" NEWLINE INDENT more_alts DEDENT { Rule(name.string, more_alts) }
| NAME ":" alts NEWLINE { Rule(name.string, alts) }
more_alts:
| "|" alts NEWLINE more_alts { alts + more_alts }
| "|" alts NEWLINE { alts }
alts:
| alt "|" alts { [alt] + alts }
| alt { [alt] }
alt:
| items action { Alt(items, action) }
| items { Alt(items, None) }
items:
| item items { [item] + items }
| item { [item] }
item:
| NAME '=' molecule { NamedItem(name.string, molecule) }
| "&" atom { Lookahead(atom) }
| "!" atom { Lookahead(atom, False) }
| "~" { Cut() }
| molecule { molecule }
molecule:
| atom "?" { Maybe(atom) }
| atom "*" { Loop(atom) }
| atom "+" { Loop(atom, True) }
| atom { atom }
| "[" alts "]" { Maybe(self.synthetic_rule(alts)) }
atom:
| NAME { name.string }
| STRING {string.string }
| "(" alts ")" { self.synthetic_rule(alts) }
action: "{" stuffs "}" { stuffs }
stuffs:
| stuff stuffs { stuff + " " + stuffs }
| stuff { stuff }
stuff:
| "{" stuffs "}" { "{" + stuffs + "}" }
| NAME { name.string }
| NUMBER { number.string }
| STRING { string.string }
| !"}" OP { op.string }