|
|
@@ -109,7 +109,8 @@ class GrammarAnalyzer(object): |
|
|
|
def __init__(self, parser_conf, debug=False): |
|
|
|
self.debug = debug |
|
|
|
|
|
|
|
rules = parser_conf.rules + [Rule(NonTerminal('$root'), [NonTerminal(parser_conf.start), Terminal('$END')])] |
|
|
|
root_rule = Rule(NonTerminal('$root'), [NonTerminal(parser_conf.start), Terminal('$END')]) |
|
|
|
rules = parser_conf.rules + [root_rule] |
|
|
|
self.rules_by_origin = classify(rules, lambda r: r.origin) |
|
|
|
|
|
|
|
if len(rules) != len(set(rules)): |
|
|
@@ -121,7 +122,10 @@ class GrammarAnalyzer(object): |
|
|
|
if not (sym.is_term or sym in self.rules_by_origin): |
|
|
|
raise GrammarError("Using an undefined rule: %s" % sym) # TODO test validation |
|
|
|
|
|
|
|
self.start_state = self.expand_rule(NonTerminal('$root')) |
|
|
|
self.start_state = self.expand_rule(root_rule.origin) |
|
|
|
|
|
|
|
end_rule = RulePtr(root_rule, len(root_rule.expansion)) |
|
|
|
self.end_state = fzset({end_rule}) |
|
|
|
|
|
|
|
self.FIRST, self.FOLLOW, self.NULLABLE = calculate_sets(rules) |
|
|
|
|
|
|
|