-
Notifications
You must be signed in to change notification settings - Fork 3
/
parglare_adapter.py
68 lines (59 loc) · 2.11 KB
/
parglare_adapter.py
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
import parglare
def to_parglare_grammar(productions_dict, terminals_dict, start):
"""Make parglare Grammar object from plain description dicts.
* productions_dict is a dictionary mapping nonterminal names into list of alternative productions equences
* terminals_dict is a dictionary mapping terminal names into their definition
Example. A grammar for strings containg a, b and c multiple times:
to_parglare_grammar(
{
'start': [['start', 'a'], ['start', 'b_or_c'], []],
},
{
'a': ('string', 'a'),
'b_or_c': ('regexp', 'b|c'),
},
'start',
)
"""
def make_terminal(name, t):
typ, val = t
if typ == 'string':
recognizer_class = parglare.StringRecognizer
elif typ == 'regexp':
recognizer_class = parglare.RegExRecognizer
else:
assert False
return parglare.Terminal(recognizer=recognizer_class(val), name=name)
terminals = {
name: make_terminal(name, value)
for name, value in terminals_dict.items()
}
non_terminals = {
name: parglare.NonTerminal(name)
for name in productions_dict.keys()
}
def get_symbol(name):
if name in terminals:
assert name not in non_terminals
return terminals[name]
else:
return non_terminals[name]
productions = []
for name, alternatives in productions_dict.items():
for alternative in alternatives:
symbol = non_terminals[name]
rhs = parglare.grammar.ProductionRHS([get_symbol(s) for s in alternative])
productions.append(parglare.grammar.Production(
symbol,
rhs,
))
start_non_terminal = parglare.NonTerminal('__start')
productions.append(parglare.grammar.Production(
start_non_terminal,
parglare.grammar.ProductionRHS([non_terminals[start], parglare.EOF]),
))
return parglare.Grammar(
productions=productions,
terminals=terminals.values(),
start_symbol=start_non_terminal,
), '__start'