39 def __init__(self, nonterms, start_nonterminal=None):
40
41 if start_nonterminal is None or start_nonterminal not in nonterms:
42 start_nonterminal = nonterms[0]
43
44
45 self.nonterms = tuple([NonTerminal(START_SYMBOL, [[start_nonterminal.name]])] +
46 nonterms)
47
48 self.terminals = ()
49
50 self.symbols = ()
51
52 self.productions = ()
53
54 self.nonterm_offset = {}
55
56 self.__first_sets = {}
57
58
59 nonterminal_by_name = {nt.name: nt for nt in self.nonterms}
60 for nt in self.nonterms:
61 for prod in nt.productions:
62 for idx in range(len(prod)):
63 symbol = prod[idx]
64
65 if isinstance(symbol, str):
66 if symbol in nonterminal_by_name:
67 prod[idx] = nonterminal_by_name[symbol]
68 else:
69 self.terminals += tuple([symbol])
70 elif isinstance(symbol, NonTerminal):
71 if symbol not in self.nonterms:
72 msg = 'Non-terminal %s is not in the grammar' % repr(symbol)
73 raise KeyError(msg)
74 else:
75 msg = "Unsupported type '%s' inside of production" % type(symbol).__name__
76 raise TypeError(msg)
77
78 self.terminals = tuple(
set(self.terminals))
79 self.symbols = self.nonterms + self.terminals
80
81
82 for nt in self.nonterms:
83 self.nonterm_offset[nt] = len(self.productions)
84 self.productions += tuple((nt.name, prod) for prod in nt.productions)
85
86 self.__build_first_sets()
87
set(SourceFiles "hyperdbg-cli.cpp" "../include/platform/user/header/Environment.h") include_directories("../include" "../dependencies") add_executable(hyperdbg-cli $
Definition CMakeLists.txt:1