def test_closure_recursion(): pytest.skip("what is this supposed to test?") s1 = StateSet() s1.add(LR1Element(Production(Z, [E]), 0, set([finish])), [finish]) closure = helper1.closure_1(s1) assert len(closure.elements) == 4 assert LR1Element(Production(Z, [E]), 0, set([finish])) in closure assert LR1Element(Production(E, [P]), 0, set([plus, finish])) in closure assert LR1Element(Production(E, [E, plus, P]), 0, set([plus, finish])) in closure assert LR1Element(Production(P, [a]), 0, set([plus, finish])) in closure
def test_goto_0(): ss = StateSet([State(Production(Z, [S]), 0)]) closure = helper1.closure_0(ss) g1 = helper1.goto_0(closure, b) expected = helper1.closure_0(StateSet([State(Production(S, [b, A, a]), 1)])) assert expected.elements == g1.elements g2 = helper1.goto_0(closure, a) assert set([State(Production(S, [a]), 1)]) == g2.elements assert helper1.goto_0(closure, c) == StateSet() assert helper1.goto_0(closure, d) == StateSet() assert helper1.goto_0(closure, f) == StateSet()
def test_closure_1(): s1 = StateSet() s1.add(LR1Element(Production(Z, [S]), 0, set([finish])), [finish]) closure = helper1.closure_1(s1) assert len(closure.elements) == 4 assert LR1Element(Production(Z, [S]), 0, set([finish])) in closure assert LR1Element(Production(S, [S, b]), 0, set([b, finish])) in closure assert LR1Element(Production(S, [b, A, a]), 0, set([b, finish])) in closure assert LR1Element(Production(S, [a]), 0, set([b, finish])) in closure s2 = StateSet() s2.add(LR1Element(Production(F, [C, D, f]), 0, set([finish])), [finish]) closure = helper1.closure_1(s2) assert len(closure.elements) == 4 assert LR1Element(Production(F, [C, D, f]), 0, set([finish])) in closure assert LR1Element(Production(C, [D, A]), 0, set([d, f])) in closure assert LR1Element(Production(D, [d]), 0, set([a])) in closure assert LR1Element(Production(D, [epsilon]), 1, set([a])) in closure
def parse_rule(self, node): name = node.children[0].symbol.name self.current_rulename = name alternatives = self.parse_alternatives(node.children[4]) symbol = Nonterminal(name) if self.start_symbol is None: self.start_symbol = symbol if self.change_startrule and symbol.name == self.change_startrule: self.start_symbol = symbol r = Rule(symbol) for a in alternatives: r.add_alternative(a[0], a[1], a[2]) self.prod_ids[Production(symbol, a[0])] = len(self.prod_ids) # add additional alternatives to the grammar (grammar extension feature, e.g. languageboxes) if self.extra_alternatives.has_key(symbol.name): for n in self.extra_alternatives[symbol.name]: a = [MagicTerminal(n), Nonterminal("WS")] r.add_alternative(a) self.prod_ids[Production(symbol, a)] = len(self.prod_ids) self.rules[symbol] = r
S ::= "b" A "d" A ::= "c" | """ p = Parser(grammar) p.parse() r = p.rules b = Terminal("b") c = Terminal("c") d = Terminal("d") S = Nonterminal("S") A = Nonterminal("A") S_bAd = Production(S, [b, A, d]) A_c = Production(A, [c]) A_None = Production(A, [Epsilon()]) syntaxtable = { (0, b): Shift(2), (0, S): Goto(1), (1, FinishSymbol()): Accept(), (2, c): Shift(4), (2, A): Goto(3), (2, d): Reduce(A_None), (3, d): Shift(5), (4, d): Reduce(A_c), (5, FinishSymbol()): Reduce(S_bAd), }
def create_parser(self, pickle_id=None): self.all_terminals.update(self.terminals) for fname, terminals, parentrule in self.functions: if fname.startswith("*match_until"): if Nonterminal(fname) not in self.rules: r = Rule(Nonterminal(fname)) for t in self.all_terminals: if t not in terminals: r.add_alternative( [Nonterminal(fname), Terminal(t)], None, t) r.add_alternative([]) self.rules[r.symbol] = r # remove whitespace before special rule from parent rule, e.g. # multistring ::= "MLS" WS *match_until "MLS" WS # ^ this WS causes shift/reduce conflicts prule = self.rules[Nonterminal(parentrule)] for a in prule.alternatives: for i in range(len(a)): sym = a[i] if sym.name == "WS": if len(a) > i + 1 and a[i + 1].name.startswith( "*match_until"): a.pop(i) break if self.implicit_ws(): ws_rule = Rule() ws_rule.symbol = Nonterminal("WS") ws_rule.add_alternative([Nonterminal("WS"), Terminal("<ws>")]) # get comment rule if self.options.has_key('comment_rule'): cmt_rules = self.options['comment_rule'] for cmt_rule in cmt_rules: if Nonterminal(cmt_rule) in self.rules: ws_rule.add_alternative( [Nonterminal("WS"), Nonterminal("comment")]) if self.implicit_newlines(): ws_rule.add_alternative( [Nonterminal("WS"), Terminal("<return>")]) ws_rule.add_alternative([ Nonterminal("WS"), Terminal("<backslash>"), Terminal("<return>") ]) ws_rule.add_alternative([]) # or empty self.rules[ws_rule.symbol] = ws_rule for a in ws_rule.alternatives: self.prod_ids[Production(ws_rule.symbol, a)] = len(self.prod_ids) # allow whitespace/comments at beginning of file start_rule = Rule() start_rule.symbol = Nonterminal("Startrule") start_rule.add_alternative([Nonterminal("WS"), self.start_symbol]) self.rules[start_rule.symbol] = start_rule self.prod_ids[Production(start_rule.symbol, start_rule.alternatives[0])] = len( self.prod_ids) self.start_symbol = start_rule.symbol incparser = IncParser() incparser.from_dict(self.rules, self.start_symbol, self.lr_type, self.implicit_ws(), pickle_id, self.precedences, self.prod_ids) incparser.init_ast() self.incparser = incparser
| "a" | "a" S "b" """ p = Parser(grammar) p.parse() r = p.rules a = Terminal("a") b = Terminal("b") c = Terminal("c") Z = Nonterminal("Z") S = Nonterminal("S") A = Nonterminal("A") None_S = State(Production(None, [S]), 0) S_Sb = State(Production(S, [S, b]), 0) S_bAa = State(Production(S, [b, A, a]), 0) A_aSc = State(Production(A, [a, S, c]), 0) A_a = State(Production(A, [a]), 0) A_aSb = State(Production(A, [a, S, b]), 0) graph = StateGraph(p.start_symbol, p.rules, 1) graph.build() def move_dot(state, i): temp = state.clone() temp.d += i return temp
def test_graph(): pytest.skip("conversion is not working yet") graph = StateGraph(p.start_symbol, p.rules, 1) graph.build() s0 = StateSet([ LR1Element(Production(None, [S]), 0, set([f])), LR1Element(Production(S, [b, A, c]), 0, set([f])), ]) s1 = StateSet([ LR1Element(Production(S, [b, A, c]), 1, set([f])), LR1Element(Production(A, [S]), 0, set([c])), LR1Element(Production(A, [a]), 0, set([c])), LR1Element(Production(S, [b, A, c]), 0, set([c])), ]) s2 = StateSet([ LR1Element(Production(S, [b, A, c]), 1, set([c])), LR1Element(Production(A, [S]), 0, set([c])), LR1Element(Production(A, [a]), 0, set([c])), LR1Element(Production(S, [b, A, c]), 0, set([c])), ]) s3 = StateSet([ LR1Element(Production(A, [a]), 1, set([c])), ]) s4 = StateSet([ LR1Element(Production(None, [S]), 1, set([f])), ]) s5 = StateSet([ LR1Element(Production(S, [b, A, c]), 2, set([f])), ]) s6 = StateSet([ LR1Element(Production(S, [b, A, c]), 2, set([c])), ]) s7 = StateSet([ LR1Element(Production(A, [S]), 1, set([c])), ]) s8 = StateSet([ LR1Element(Production(S, [b, A, c]), 3, set([f])), ]) s9 = StateSet([ LR1Element(Production(S, [b, A, c]), 3, set([c])), ]) assert len(graph.state_sets) == 10 assert s0 in graph.state_sets assert s1 in graph.state_sets assert s2 in graph.state_sets assert s3 in graph.state_sets assert s4 in graph.state_sets assert s6 in graph.state_sets assert s7 in graph.state_sets assert s8 in graph.state_sets assert s9 in graph.state_sets graph.convert_lalr() s0 = StateSet([ LR1Element(Production(None, [S]), 0, set([f])), LR1Element(Production(S, [b, A, c]), 0, set([f])), ]) s1 = StateSet([ LR1Element(Production(S, [b, A, c]), 1, set([f, c])), LR1Element(Production(A, [S]), 0, set([c])), LR1Element(Production(A, [a]), 0, set([c])), LR1Element(Production(S, [b, A, c]), 0, set([c])), ]) s2 = StateSet([ LR1Element(Production(A, [a]), 1, set([c])), ]) s3 = StateSet([ LR1Element(Production(None, [S]), 1, set([f])), ]) s4 = StateSet([ LR1Element(Production(S, [b, A, c]), 2, set([f, c])), ]) s5 = StateSet([ LR1Element(Production(A, [S]), 1, set([c])), ]) s6 = StateSet([ LR1Element(Production(S, [b, A, c]), 3, set([f, c])), ]) assert len(graph.state_sets) == 7 assert s0 in graph.state_sets assert s1 in graph.state_sets assert s2 in graph.state_sets assert s3 in graph.state_sets assert s4 in graph.state_sets assert s6 in graph.state_sets
def test_goto_1(): lre = LR1Element(Production(Z, [S]), 0, set([finish])) clone = lre.clone() assert lre == clone
def test_closure_0(): s1 = StateSet() s = State(Production(Nonterminal("Z"), [Nonterminal("S")]), 0) # first state Z ::= .S s1.add(s) closure = helper1.closure_0(s1) assert len(closure.elements) == 4 assert State(Production(Z, [S]), 0) in closure assert State(Production(S, [S, b]), 0) in closure assert State(Production(S, [b, A, a]), 0) in closure assert State(Production(S, [a]), 0) in closure s2 = StateSet() s = State(Production(F, [C, D, f]), 0) s2.add(s) closure = helper1.closure_0(s2) assert len(closure.elements) == 4 assert State(Production(F, [C, D, f]), 0) in closure assert State(Production(C, [D, A]), 0) in closure assert State(Production(D, [d]), 0) in closure assert State(Production(D, [Epsilon()]), 1) in closure s3 = StateSet() s = State(Production(C, [D, A]), 1) s3.add(s) closure = helper1.closure_0(s3) assert len(closure.elements) == 4 assert State(Production(C, [D, A]), 1) in closure assert State(Production(A, [a, S, c]), 0) in closure assert State(Production(A, [a, S, b]), 0) in closure assert State(Production(A, [a]), 0) in closure