HyperDbg Debugger
Loading...
Searching...
No Matches
lalr_parsing.grammar.Grammar Class Reference

Public Member Functions

 __init__ (self, nonterms, start_nonterminal=None)
 
 first_set (self, x)
 
 stringify (self, indexes=True)
 
 __str__ (self)
 

Public Attributes

 nonterms
 
 terminals
 
 symbols
 
 productions
 
 nonterm_offset
 

Constructor & Destructor Documentation

◆ __init__()

lalr_parsing.grammar.Grammar.__init__ ( self,
nonterms,
start_nonterminal = None )
39 def __init__(self, nonterms, start_nonterminal=None):
40 # Grammar start symbol
41 if start_nonterminal is None or start_nonterminal not in nonterms:
42 start_nonterminal = nonterms[0]
43
44 # Tuple of non-terminals
45 self.nonterms = tuple([NonTerminal(START_SYMBOL, [[start_nonterminal.name]])] +
46 nonterms)
47 # Tuple of terminals
48 self.terminals = ()
49 # Tuple of symbols (non-terminals + terminals)
50 self.symbols = ()
51 # Tuple of enumerated NT's productions
52 self.productions = ()
53 # Enumeration offset for a given NT
54 self.nonterm_offset = {}
55 # First sets for every grammar symbol
56 self.__first_sets = {}
57
58 # Update the references of each production and, while at it, recognize terminal symbols
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 # Enumerate grammar productions
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

Member Function Documentation

◆ __str__()

lalr_parsing.grammar.Grammar.__str__ ( self)
153 def __str__(self):
154 return self.stringify()
155
156

◆ first_set()

lalr_parsing.grammar.Grammar.first_set ( self,
x )
88 def first_set(self, x):
89 result = set()
90
91 if isinstance(x, str):
92 result.add(x)
93 elif isinstance(x, NonTerminal):
94 result = self.__first_sets[x]
95 else:
96 skippable_symbols = 0
97 for sym in x:
98 fs = self.first_set(sym)
99 result.update(fs - {None})
100 if None in fs:
101 skippable_symbols += 1
102 else:
103 break
104
105 if skippable_symbols == len(x):
106 result.add(None)
107
108 return frozenset(result)
109

◆ stringify()

lalr_parsing.grammar.Grammar.stringify ( self,
indexes = True )
146 def stringify(self, indexes=True):
147 lines = '\n'.join(nt.stringify() for nt in self.nonterms)
148 if indexes:
149 lines = '\n'.join(RULE_INDEXING_PATTERN % (x, y)
150 for x, y in enumerate(lines.split('\n')))
151 return lines
152

Member Data Documentation

◆ nonterm_offset

lalr_parsing.grammar.Grammar.nonterm_offset

◆ nonterms

lalr_parsing.grammar.Grammar.nonterms

◆ productions

lalr_parsing.grammar.Grammar.productions

◆ symbols

lalr_parsing.grammar.Grammar.symbols

◆ terminals

lalr_parsing.grammar.Grammar.terminals

The documentation for this class was generated from the following file: