示例#1
0
    def testDeleteMissingVertices(self):
        # lhs has no vertices(!). Nothing done.
        g = Graph()
        lhs = Graph()
        rhs = Graph()
        p = Production(lhs, rhs)
        gen = Generator()
        gen._deleteMissingVertices(g, p, {})
        self.assertEqual(len(g._vertices), 0)

        # lhs has vertices, but they all appear in the rhs. Nothing done.
        g.addVertex(Vertex('g0', 'A', 1))
        lhs.addVertex(Vertex('l0', 'A', 1))
        rhs.addVertex(Vertex('r0', 'A', 1))
        p = Production(lhs, rhs)
        gen._deleteMissingVertices(g, p, {'l0':'g0'})
        self.assertEqual(len(g._vertices), 1)

        # lhs has a vertex (A2) that don't appear in the rhs. It should be
        # deleted from g.
        g.addVertex(Vertex('g1', 'A', 2))
        lhs.addVertex(Vertex('l1', 'A', 2))
        p = Production(lhs, rhs)
        self.assertEqual(len(g._vertices), 2)
        gen._deleteMissingVertices(g, p, {'l0':'g0', 'l1':'g1'})
        self.assertEqual(len(g._vertices), 1)
示例#2
0
    def init_grammar(self, filepath):
        flag = 0
        with open(filepath, 'r') as grammar_input:

            for line in grammar_input:
                print line
                tmp_split = line.rsplit("->", 1)
                left_part = tmp_split[0].replace("\n", "").strip()

                if flag == 0:
                    self.initial = left_part.replace("\n", "").strip()
                    flag = 1

                right_part = tmp_split[1].rsplit("|")

                self.non_terminals.append(left_part.strip())

                for item in right_part:

                    production = Production()

                    each_right_part = item.split(",")

                    for subitem in each_right_part:
                        production.body.append(subitem.replace("\n", "").strip())
                        production.name = left_part.strip()

                    self.productions.append(production)

            for p in self.productions:
                for item in p.body:
                    if(item not in self.non_terminals) and (item not in self.terminals) and (item != '@'):
                        self.terminals.append(item)
示例#3
0
    def testFindMatchingProductions(self):
        # Providing no productions should result in no matches.
        gen = Generator()
        g = Graph()
        self.assertEquals( len(gen._findMatchingProductions(g, [])), 0)        
        
        # We have a production, but the LHS can't be found in the graph.
        # No solutions.
        g = Graph()
        g.addEdge(Vertex('g0', 'A'), Vertex('g1', 'B'))
        lhs = Graph()
        lhs.addEdge(Vertex('g0', 'C'), Vertex('g1', 'D'))
        rhs = Graph()
        p1 = Production(lhs, rhs)
        gen = Generator()
        self.assertEquals( len(gen._findMatchingProductions(g, [p1])), 0)        

        # One matching production, a simple vertex "A".
        g = Graph()
        g.addEdge(Vertex('g0', 'A'), Vertex('g1', 'B'))
        lhs = Graph()
        lhs.addVertex(Vertex('g0', 'A', '1'))
        rhs = Graph()
        p1 = Production(lhs, rhs)
        self.assertEquals( len(gen._findMatchingProductions(g, [p1])), 1)

        # Two matching productions.
        g = Graph()
        g.addEdge(Vertex('g0', 'A'), Vertex('g1', 'B'))
        lhs = Graph()
        lhs.addVertex(Vertex('g0', 'A', '2'))
        rhs = Graph()
        p1 = Production(lhs, rhs)
        p2 = Production(lhs, rhs)
        self.assertEquals( len(gen._findMatchingProductions(g, [p1, p2])), 2)
示例#4
0
    def remove_left_recursion(self):
        non_terminals = list(self.prods.keys())
        for i, non_terminal in enumerate(non_terminals):
            grammar_changed = True
            while grammar_changed:
                grammar_changed = False
                rhs_i = self.prods[non_terminal].rhses
                for rhs in rhs_i:
                    for A_j in non_terminals[:i]:
                        if rhs[0] == A_j:
                            rhs_revised = rhs[1:]
                            self.prods[non_terminal].rhses.remove(rhs)
                            grammar_changed = True
                            for prod in self.prods[A_j].rhses:
                                self.prods[non_terminal].rhses.append(prod + rhs_revised)

            alpha_set = [prod[1:] for prod in self.prods[non_terminal].rhses if prod[0] == non_terminal]
            beta_set = [prod for prod in self.prods[non_terminal].rhses if prod[0] != non_terminal]
            if len(alpha_set) > 0:
                self.prods.pop(non_terminal)
                non_terminal_new = non_terminal + '.new'
                self.prods[non_terminal] = Production(non_terminal, [
                    beta_i + [non_terminal_new] if beta_i != epsilon else [non_terminal_new] for beta_i in beta_set])
                self.prods[non_terminal_new] = Production(non_terminal_new,
                                                          [alpha_i + [non_terminal_new] for alpha_i in alpha_set])
                self.prods[non_terminal_new].rhses += [epsilon]
示例#5
0
 def left_factorize_prods(self):
     grammar_changed = True
     unchecked_prods = list(self.prods.values())
     new_prods = []
     while grammar_changed:
         grammar_changed = False
         for prod in list(unchecked_prods):
             index = 0
             prefix = []
             while True:
                 if any((len(rhs) <= index or rhs == epsilon) for rhs in prod.rhses):
                     break
                 if all(ith_term == prod.rhses[0][index] for ith_term in list(rhs[index] for rhs in prod.rhses)):
                     prefix.append(prod.rhses[0][index])
                     index += 1
                 else:
                     break
             unchecked_prods.remove(prod)
             if index > 0:
                 prefix_name = reduce(lambda str1, str2: str(str1) + str(str2), prefix)
                 suffix_name = prod.non_terminal + "." + str(prefix_name)
                 new_prods.append(Production(prod.non_terminal, [prefix + [suffix_name]]))
                 new_rhses = list((epsilon if len(rhs) <= index else rhs[index:]) for rhs in prod.rhses)
                 unchecked_prods.append(Production(suffix_name, new_rhses))
                 grammar_changed = True
             else:
                 groups = dict()
                 for rhs in prod.rhses:
                     if rhs != epsilon:
                         if not (rhs[0] in groups):
                             groups[rhs[0]] = []
                         groups[rhs[0]].append(rhs)
                     else:
                         groups[epsilon[0]] = [epsilon]
                 if len(groups) == len(prod.rhses):
                     new_prods.append(prod)
                 else:
                     new_rhses = []
                     for term in groups:
                         if term == epsilon[0]:
                             new_rhses.append(epsilon)
                         elif len(groups[term]) == 1:
                             new_rhses.append(groups[term][0])
                         else:
                             new_prod_name = prod.non_terminal + "." + str(term)
                             new_rhses.append([new_prod_name])
                             unchecked_prods.append(Production(new_prod_name, groups[term]))
                     unchecked_prods.append(Production(prod.non_terminal, new_rhses))
                     grammar_changed = True
     self.make_prods(new_prods)
示例#6
0
    def testApplyProductions(self):
        # Start graph already has the minimum number of vertices. Nothing done.
        g = Graph()
        c = {'min_vertices':0}
        gen = Generator()
        gen.applyProductions(g, None, c)
        self.assertEqual(len(g._vertices), 0)

        # No matching productions raises an error.
        c = {'min_vertices':1}
        self.assertRaises(RuntimeError, gen.applyProductions, g, [], c)

        # When we're done, g has more at least min_vertices.
        g.addEdge(Vertex('g0', 'A'), Vertex('g1', 'A'))
        c = {'min_vertices':10}
        # Production is A1->A2 ==> A1->A->A2
        lhs = Graph()
        lhs.addEdge(Vertex('l0', 'A', 1), Vertex('l1', 'A', 2))
        rhs = Graph()
        rhs.addEdge(Vertex('r0', 'A', 1), Vertex('r1', 'A'))
        rhs.addEdge('r1', Vertex('r2', 'A', 2))
        p = Production(lhs, rhs)
        gen.applyProductions(g, [p], c)
        logging.debug(g)
        self.assertEqual(len(g._vertices), 10)
示例#7
0
    def testAddNewVertices(self):
        # Production rhs has no vertices, so nothing done.
        g = Graph()
        lhs = Graph()
        rhs = Graph()
        p = Production(lhs, rhs)
        gen = Generator()
        self.assertEqual(len(g._vertices), 0)
        gen._addNewVertices(g, p, {})
        self.assertEqual(len(g._vertices), 0)
        
        # Production rhs has vertices, but they all appear in the LHS. Hence
        # they aren't new and nothing is done.
        lhs.addVertex(Vertex('l1', 'A', 1))
        rhs.addVertex(Vertex('r1', 'A', 1))
        self.assertEqual(len(g._vertices), 0)
        gen._addNewVertices(g, p, {})
        self.assertEqual(len(g._vertices), 0)

        # rhs has one new vertex not in the lhs.
        rhsMapping = {}
        rhs.addVertex(Vertex('r2', 'B', 2))
        self.assertEqual(len(g._vertices), 0)
        gen._addNewVertices(g, p, rhsMapping)
        self.assertEqual(len(g._vertices), 1)
        self.assertIn('v0', g._vertices)               # new vertex is v0
        self.assertEqual(g._vertices['v0'].label, 'B') # with label B
        self.assertEqual(g._vertices['v0'].number, 2)  # with number 2
        self.assertIn('r2', rhsMapping)                # now appears in rhsMapping
        self.assertEqual(rhsMapping['r2'], 'v0')       # r2 mapped to v0 (the newly added vertex) in graph
示例#8
0
 def make_grammar(compressed_prods):
     start = compressed_prods[0][0]
     productions = []
     for c_prod in compressed_prods:
         r = Production(c_prod[0], c_prod[1:])
         productions.append(r)
     return Grammar(productions, start)
示例#9
0
    def testApplyProduction(self):
        # A basic test that tests all four cases: add and remove vertex,
        # and add and remove edge.

        # Graph starts with A->B
        g = Graph()
        g.addEdge(Vertex('g0', 'A'), Vertex('g1', 'B'))
        g1 = g._vertices['g1']

        # Production lhs matches A->B
        lhs = Graph()
        lhs.addEdge(Vertex('l0', 'A', 1), Vertex('l1', 'B', 1))

        # Production rhs transforms that to A->C
        rhs = Graph()
        rhs.addEdge(Vertex('r0', 'A', 1), Vertex('r1', 'C'))
        p = Production(lhs,rhs)

        gen = Generator()
        gen._applyProduction(g, p, {'l0':'g0','l1':'g1'})

        # g has a new vertex, <v2,C>.
        self.assertEqual(len(g._vertices), 2)
        self.assertEqual(g._vertices['v1'].label, 'C')

        # <g0,A> points to <v2,C>
        self.assertEqual(len(g._edges['g0']), 1)
        self.assertEqual(g._edges['g0'][0].id, 'v1')
        self.assertEqual(g._vertices['v1'].label, 'C')

        # <g0,A> no longer points to <g1,B>
        self.assertNotIn(g1, g._edges['g0'])

        # Vertex <g1,B> has been deleted.
        self.assertNotIn('g1', g._vertices)
示例#10
0
    def _parseProduction(self):
        """
        prod -> graph '==>' graph

        A production defines a transformation taking one graph (on the LHS)
        and transforming it to a different graph (RHS).
        """
        lhs = self._parseGraph()
        self._match(TokenTypes.DOUBLEARROW)
        rhs = self._parseGraph()
        self.productions.append(Production(lhs, rhs))
示例#11
0
    def testApplyProduction_Blackbox2(self):
        # Another black-box test of _applyProduction this time with
        # numbered vertices.

        # Graph is A0->A1,A0->D
        g = Graph()
        g.addEdge(Vertex('g0', 'A'), Vertex('g1', 'A'))
        g.addEdge('g0', Vertex('g2', 'D'))

        # Production is A1->A2 ==> A1->A->A2.
        # This production adds a new vertex "A" between the existing As,
        # leaving the first A still pointing to D.
        # Resulting graph: A1->A3->A2; A1->D
        lhs = Graph()
        lhs.addEdge(Vertex('l0', 'A', 1), Vertex('l1', 'A', 2))
        rhs = Graph()
        rhs.addEdge(Vertex('r0', 'A', 1), Vertex('r1', 'A'))
        rhs.addEdge('r1', Vertex('r2', 'A', 2))
        p = Production(lhs, rhs)

        gen = Generator()
        gen._applyProduction(g, p, {'l0':'g0','l1':'g1'})

        # Result has 4 vertices.
        self.assertEqual(len(g._vertices), 4)

        # <g0,A> is still in the graph.
        self.assertIn('g0', g._vertices)
        self.assertEqual(g._vertices['g0'].label, 'A')

        # <v3,A> has been added.
        self.assertIn('v3', g._vertices)
        self.assertEqual(g._vertices['v3'].label, 'A')
        
        # g0->v3
        self.assertIn(g._vertices['v3'], g._edges['g0'])

        # <g1,A> is still in the graph.
        self.assertIn('g1', g._vertices)
        self.assertEqual(g._vertices['g1'].label, 'A')

        # <g2,D> is still in the graph.
        self.assertIn('g2', g._vertices)
        self.assertEqual(g._vertices['g2'].label, 'D')

        # <g0,A>-><g2,D>
        self.assertIn(g._vertices['g2'], g._edges['g0'])

        # g0->v3
        self.assertIn(g._vertices['v3'], g._edges['g0'])

        # Output looks fine: A1->A->A, A1->D
        self.assertEqual(str(g), 'digraph {\nA_v3->A_g1;\nA_g0->D_g2;\nA_g0->A_v3;\n\n}')
示例#12
0
def makeNodes():

    parent = Production("S")
    parent.childrens.append("z")
    parent.childrens.append(Production(parent, "M"))
    parent.childrens.append(Production(parent, "N"))
    parent.childrens.append("z")

    children = parent.childrens[1]
    children.childrens.append("a")
    children.childrens.append(Production(children, "M"))
    children.childrens.append("a")

    children2 = parent.childrens[2]
    children2.childrens.append("b")
    children2.childrens.append(Production(children2, "N"))
    children2.childrens.append("b")

    children3 = children.childrens[1]
    children3.childrens.append("z")
    children3.childrens.append(Production(children3, "M"))

    children4 = children3.childrens[1]
    children4.childrens.append("z")

    generateTree()
示例#13
0
def read_Production(name):
    """
    Read a production from 'productions\name.dot'
    :param name: name of production to read
    :return: Production object
    """
    filename = "productions\\" + name + ".dot"
    left_p = pydot.graph_from_dot_file(filename)[0]
    right_p = pydot.graph_from_dot_file(filename)[1]
    l = graph_to_graph_transformation(pydot_graph_to_graph(left_p, name))
    r = graph_to_graph_transformation(pydot_graph_to_graph(right_p, name))
    e = read_embed_transformation(filename)
    return Production(l, r, e)
示例#14
0
    def testAddNewEdges(self):
        # rhs has no edges, so nothing changes.
        g = Graph()
        lhs = Graph()
        rhs = Graph()
        p = Production(lhs,rhs)
        rhsMapping = {}
        gen = Generator()
        self.assertEqual(len(g._edges), 0)
        gen._addNewEdges(g, p, rhsMapping)
        self.assertEqual(len(g._edges), 0)

        # rhs has an edge, but it already exists in the graph.
        g = Graph()
        g.addEdge(Vertex('g0', 'A'), Vertex('g1', 'B'))
        lhs = Graph()
        rhs = Graph()
        rhs.addEdge(Vertex('r0', 'A', 1), Vertex('r1', 'B', 1))
        p = Production(lhs,rhs)
        rhsMapping = {'r0':'g0', 'r1':'g1'}
        gen = Generator()
        self.assertEqual(len(g._edges['g0']), 1)
        gen._addNewEdges(g, p, rhsMapping)
        self.assertEqual(len(g._edges['g0']), 1)

        # rhs has a new edge not in graph.
        g = Graph()
        g.addVertex(Vertex('g0', 'A'))
        g.addVertex(Vertex('g1', 'B'))
        lhs = Graph()
        rhs = Graph()
        rhs.addEdge(Vertex('r0', 'A', 1), Vertex('r1', 'B', 1))
        p = Production(lhs,rhs)
        rhsMapping = {'r0':'g0', 'r1':'g1'}
        gen = Generator()
        self.assertEqual(len(g._edges['g0']), 0)
        gen._addNewEdges(g, p, rhsMapping)
        self.assertEqual(len(g._edges['g0']), 1)
        self.assertEqual(g._edges['g0'][0].id, 'g1')
示例#15
0
 def readProductions(self):
     try:
         file = open("file/grammar.txt")
         for line in file.readlines():
             if line[-1] == "\n":
                 line = line[:-1]
             left = line.split("->")[0].strip()
             right = line.split("->")[1].strip()
             production = Production(left, right.split(" "))
             self.__productions.append(production)
         file.close()
     except Exception:
         print("打开文件时出错")
示例#16
0
def get_productions_from_xml(path):
    tree = ElementTree.parse(path)
    root = tree.getroot()

    prods = root.find('m_Production')
    production_sym_count = []

    for prod in prods.findall('Production'):
        count = prod.attrib['SymbolCount']
        rule  = prod.attrib['NonTerminalIndex']
        production_sym_count.append(Production(count, rule))

    return production_sym_count
示例#17
0
    def buildProList(self):

        for p in self.InputPro:
            self.pList.add(Production(p[0], p[1]))
            if p[0] not in self.Virables:
                self.Virables.append(p[0])

        for p in self.InputPro:
            for t in p[1]:
                if t not in self.Virables and t not in self.Terminals and t != 'NULL':
                    self.Terminals.append(t)

        self.TerAndEnd = self.Terminals.copy()
        self.TerAndEnd.append('#')
示例#18
0
 def delDirectRecur(self, p):
     v = p
     vPList = self.pList.getVirablePro(v)
     isLeftRecur = False
     for p in vPList:
         if p.left == p.right[0]:
             isLeftRecur = True
     if isLeftRecur == True:
         new_v = v + '1'
         assert new_v not in self.Virables
         self.Virables.append(new_v)
         for p in vPList:
             if p.left == p.right[0]:
                 self.pList.delete(p)
                 p.right.remove(p.left)
                 p.right.append(new_v)
                 self.pList.add(Production(new_v, p.right))
             else:
                 if p.right == ['NULL']:
                     p.right = [new_v]
                 else:
                     p.right.append(new_v)
                 self.pList.add(Production(v, p.right))
         self.pList.add(Production(new_v, ['NULL']))
示例#19
0
    def get_join_production(self, prod_name):
        new_production = Production()

        productions = self.get_production(prod_name)

        new_production.name = prod_name
        for p in productions:
            p.define_first_set(self)
            new_production.first_union(p.first_set)
            new_production.follow_union(p.follow_set)

        return new_production
示例#20
0
    def get_production_grammar_file(gram):
        fin = open(gram)
        start = None
        production = []
        for line in fin:
            l, r = line.split("->")
            l = l.strip()
            if l == "root":
                if start != None:
                    raise Exception("too Many root symbol")
                start = 'root'

            for rule in r.split("|"):
                production.append(Production(l, rule, None))

        if start == None:
            raise Exception("did you forget root symbol?")
        return production
示例#21
0
    def testApplyProduction_Blackbox(self):
        # Black-box test of _applyProduction.

        # Graph is A->C,D
        g = Graph()
        g.addEdge(Vertex('g0', 'A'), Vertex('g1', 'C'))
        g.addVertex(Vertex('g2', 'D'))

        # Production is A->C,D ==> A->B,C.
        # This adds vertex B, adds edge from A->B, deletes edge from A->C,
        # and deletes vertex D.
        lhs = Graph()
        lhs.addEdge(Vertex('l0', 'A'), Vertex('l1', 'C'))
        lhs.addVertex(Vertex('l2', 'D'))
        rhs = Graph()
        rhs.addEdge(Vertex('r0', 'A'), Vertex('r1', 'B'))
        rhs.addVertex(Vertex('r2', 'C'))
        p = Production(lhs, rhs)

        gen = Generator()
        gen._applyProduction(g, p, {'l0':'g0','l1':'g1','l2':'g2'})

        self.assertEqual(len(g._vertices), 3)

        # <g0,A> is still in the graph.
        self.assertIn('g0', g._vertices)
        self.assertEqual(g._vertices['g0'].label, 'A')
        # <v3,B> has been added.
        self.assertIn('v2', g._vertices)
        self.assertEqual(g._vertices['v2'].label, 'B')
        # A->B
        self.assertIn(g._vertices['v2'], g._edges['g0'])
        # <g1,C> is still in the graph.
        self.assertIn('g1', g._vertices)
        self.assertEqual(g._vertices['g1'].label, 'C')
        # A->C has been removed.
        self.assertNotIn(g._vertices['g1'], g._edges['g0'])
        # <g2,D> has been removed.
        self.assertNotIn('g2', g._vertices)

        # Output looks fine.
        self.assertEqual(str(g), 'digraph {\nA_g0->B_v2;\n\n}')
示例#22
0
    def get_production_semantic_file(self, gram):
        mod = imp.load_source("*", gram)
        for x in dir(mod):
            if not x.startswith("sem_"):
                continue

            obj = getattr(mod, x)
            if isinstance(obj, types.FunctionType):
                line = obj.__doc__

                sp = line.split("->")

                l, r = sp
                l = l.strip()
                self.nonterminal.add(l)
                if l == "root":
                    self.start = "root"

                p = Production(l, r, obj)
                self.production.append(p)
示例#23
0
    def testMapRHSToGraph(self):
        # No vertices in rhs. Mapping returned is empty.
        g = Graph()
        lhs = Graph()
        rhs = Graph()
        p = Production(lhs, rhs)
        gen = Generator()
        rhsMapping = gen._mapRHSToGraph(g, p, {})
        self.assertEqual(len(rhsMapping), 0)

        # rhs has vertex r1, but it doesn't appear in the lhs. Mapping returned
        # is empty.
        rhs.addVertex(Vertex('r1', 'A', '1'))
        rhsMapping = gen._mapRHSToGraph(g, p, {})
        self.assertEqual(len(rhsMapping), 0)

        # rhs vertex r1 also appears in lhs as l1, which is mapped to g1. 
        # r1 should appear in rhsMapping mapped to g1.
        lhs.addVertex(Vertex('l1', 'A', '1'))
        rhsMapping = gen._mapRHSToGraph(g, p, {'l1':'g1'})
        self.assertEqual(len(rhsMapping), 1)
        self.assertIn('r1', rhsMapping)
        self.assertEqual(rhsMapping['r1'], 'g1')
示例#24
0
 def parsePhrasalGrammar(self, source):
     while not source.eos():
         self.addProduction(Production.parse(source))
示例#25
0
from Production import Production

production = [('E', 'TA'), ('A', '+TA'), ('A', '#'), ('T', 'FB'), ('B', '*FB'),
              ('B', '#'), ('F', '(E)'), ('F', 'i')]

prod = Production(production)

print(prod.showFirstAndFollow())
示例#26
0
文件: main.py 项目: pawlo555/TIAG

# end def


def get_productions(production_paths):
    productions = [[None] * 3 for _ in production_paths]
    for i, production in enumerate(production_paths):
        productions[i][0] = graph_to_graph_transformation(
            str(i) + "L", read_Graph(str(i) + "L", production[0]))
        productions[i][1] = graph_to_graph_transformation(
            str(i) + "R", read_Graph(str(i) + "R", production[1]))
        productions[i][2] = embed_transformation(production[2])
    return productions


# end def

hello_main()
name = get_name()
g_path = graph_path()
p_paths = production_paths()
graph = get_graph(name, g_path)
prod_args = get_productions(p_paths)
for prod_arg in prod_args:
    production = Production(prod_arg[0], prod_arg[1], prod_arg[2])
    print(prod_arg[2])
    graph = production.produce(graph, name)
graph.view(cleanup=True)
graph.render(filename="graph_photos\\" + name + ".dot", cleanup=True)
示例#27
0
    def testDeleteMissingEdges(self):
        # If lhs has no edges, then there's nothing missing from the rhs.
        # Nothing is done to the graph.
        g = Graph()
        g.addEdge(Vertex('g0', 'A', 1), Vertex('g1', 'B', 1))
        lhs = Graph()
        rhs = Graph()
        p = Production(lhs,rhs)
        lhsMapping = {}
        rhsMapping = {}
        gen = Generator()
        self.assertEqual(len(g._edges['g0']), 1)
        gen._deleteMissingEdges(g, p, lhsMapping, rhsMapping)
        self.assertEqual(len(g._edges['g0']), 1)

        # lhs has an edge, but it also appears on the rhs. Nothing done.
        g = Graph()
        g.addEdge(Vertex('g0', 'A', 1), Vertex('g1', 'B', 1))
        lhs = Graph()
        lhs.addEdge(Vertex('l0', 'A', 1), Vertex('l1', 'B', 1))
        rhs = Graph()
        rhs.addEdge(Vertex('r0', 'A', 1), Vertex('r1', 'B', 1))
        p = Production(lhs,rhs)
        lhsMapping = {'l0':'g0', 'l1':'g1'}
        rhsMapping = {'r0':'g0', 'r1':'g1'}
        gen = Generator()
        self.assertEqual(len(g._edges['g0']), 1)
        gen._deleteMissingEdges(g, p, lhsMapping, rhsMapping)
        self.assertEqual(len(g._edges['g0']), 1)

        # lhs has an edge, but the starting vertex doesn't appear in the RHS.
        # The edge should be deleted from the graph.
        g = Graph()
        g.addEdge(Vertex('g0', 'A', 1), Vertex('g1', 'B', 1))
        lhs = Graph()
        lhs.addEdge(Vertex('l0', 'A', 1), Vertex('l1', 'B', 1))
        rhs = Graph()
        rhs.addVertex(Vertex('r0', 'A', 2))
        rhs.addVertex(Vertex('r1', 'B', 1))
        p = Production(lhs,rhs)
        lhsMapping = {'l0':'g0', 'l1':'g1'}
        rhsMapping = {'r1':'g1'}
        gen = Generator()
        self.assertEqual(len(g._edges['g0']), 1)
        gen._deleteMissingEdges(g, p, lhsMapping, rhsMapping)
        self.assertEqual(len(g._edges['g0']), 0)

        # lhs has an edge, but the ending vertex doesn't appear in the RHS.
        # The edge should be deleted from the graph.
        g = Graph()
        g.addEdge(Vertex('g0', 'A', 1), Vertex('g1', 'B', 1))
        lhs = Graph()
        lhs.addEdge(Vertex('l0', 'A', 1), Vertex('l1', 'B', 1))
        rhs = Graph()
        rhs.addVertex(Vertex('r0', 'A', 1))
        rhs.addVertex(Vertex('r1', 'B', 2))
        p = Production(lhs,rhs)
        lhsMapping = {'l0':'g0', 'l1':'g1'}
        rhsMapping = {'r0':'g0'}
        gen = Generator()
        self.assertEqual(len(g._edges['g0']), 1)
        gen._deleteMissingEdges(g, p, lhsMapping, rhsMapping)
        self.assertEqual(len(g._edges['g0']), 0)

        # lhs has an edge, but it's gone from the rhs. It should be deleted
        # from the graph.
        g = Graph()
        g.addEdge(Vertex('g0', 'A', 1), Vertex('g1', 'B', 1))
        lhs = Graph()
        lhs.addEdge(Vertex('l0', 'A', 1), Vertex('l1', 'B', 1))
        rhs = Graph()
        rhs.addVertex(Vertex('r0', 'A', 1))
        rhs.addVertex(Vertex('r1', 'B', 1))
        p = Production(lhs,rhs)
        lhsMapping = {'l0':'g0', 'l1':'g1'}
        rhsMapping = {'r0':'g0', 'r1':'g1'}
        gen = Generator()
        self.assertEqual(len(g._edges['g0']), 1)
        gen._deleteMissingEdges(g, p, lhsMapping, rhsMapping)
        self.assertEqual(len(g._edges['g0']), 0)
示例#28
0
    def recursive_descent_run(self):
        state = State(self.__grammar.getStartSymbol())
        while state.type != StateType.FINAL and state.type != StateType.ERROR:
            print(state)
            if state.type == StateType.NORMAL:
                if len(state.input_stack) == 0 and state.index == len(
                        self.__input):
                    state.type = StateType.FINAL
                elif len(state.input_stack) == 0:
                    state.type = StateType.BACK
                else:
                    if state.input_stack[0] in self.__grammar.getNonTerminals(
                    ):
                        non_term = state.input_stack[0]
                        first_prod = self.__grammar.getProdForNT(non_term)[0]
                        state.work_stack.append((first_prod.getLeftSide(),
                                                 first_prod.getRightSide()))
                        state.input_stack = first_prod.getRightSide(
                        ) + state.input_stack[1:]
                    else:
                        if state.index == len(self.__input):
                            state.type = StateType.BACK
                        elif state.input_stack[0] == StateType.ERROR:
                            state.work_stack.append(StateType.ERROR)
                            state.input_stack = state.input_stack[1:]
                        elif state.input_stack[0] == self.__input[state.index]:
                            state.index += 1
                            state.work_stack.append(state.input_stack[0])
                            state.input_stack = state.input_stack[1:]
                        else:
                            state.type = StateType.BACK
            else:
                if state.type == StateType.BACK:
                    if state.work_stack[-1] in self.__grammar.getTerminals():
                        if state.work_stack[-1] == StateType.ERROR:
                            state.work_stack.pop(-1)
                        else:
                            state.index -= 1
                            terminal = state.work_stack.pop(-1)
                            state.input_stack = [terminal] + state.input_stack
                    else:
                        last_production = state.work_stack[-1]
                        productions = self.__grammar.getProdForNT(
                            last_production[0])
                        productions = [(prod.getLeftSide(),
                                        prod.getRightSide())
                                       for prod in productions]
                        next_prod = self.__get_next_prod(
                            last_production, productions)
                        if next_prod:
                            state.type = StateType.NORMAL
                            state.work_stack.pop(-1)
                            state.work_stack.append(
                                (next_prod[0], next_prod[1]))
                            state.input_stack = state.input_stack[
                                len(last_production[1]):]
                            state.input_stack = next_prod[1] + state.input_stack
                        elif state.index == 0 and last_production[
                                0] == self.__grammar.getStartSymbol():
                            state.type = StateType.ERROR
                        else:
                            state.work_stack.pop(-1)
                            if last_production[1] == [StateType.ERROR]:
                                state.input_stack = [last_production[0]
                                                     ] + state.input_stack
                            else:
                                state.input_stack = [
                                    last_production[0]
                                ] + state.input_stack[len(last_production[1]):]

        prod_rules = []
        if state.type == StateType.ERROR:
            return False, []
        else:
            for prod in state.work_stack:
                if len(prod) > 1:
                    if Production(prod[0],
                                  prod[1]) in self.__grammar.getProductions():
                        prod_rules.append(prod)

        return True, prod_rules
 def __init__(self, grammar_num=1):
     # Grammar from task 1 used by default not LL1
     if grammar_num == 1:
         self.grammar_productions = [
             Production(20, [21, 99]),
             Production(21, [23, 22]),
             Production(22, [5, 21]),
             Production(22, [6, 21]),
             Production(22, [26]),
             Production(23, [24]),
             Production(23, [7, 23]),
             Production(24, [3, 21, 4]),
             Production(24, [25]),
             Production(24, [2, 10, 1]),
             Production(24, [2, 12, 1]),
             Production(24, [2, 11, 1]),
             Production(24, [2]),
             Production(25, [8]),
             Production(25, [9]),
             Production(26, [])
         ]
     # if any argument but 1 is passed to grammar will use this LL1 grammar developed in task 3
     else:
         self.grammar_productions = [
             Production(20, [21, 99]),
             Production(21, [23, 22]),
             Production(22, [5, 21]),
             Production(22, [6, 21]),
             Production(22, [26]),
             Production(23, [24]),
             Production(23, [7, 23]),
             Production(24, [3, 21, 4]),
             Production(24, [25]),
             Production(24, [2, 27]),
             Production(25, [8]),
             Production(25, [9]),
             Production(26, []),
             Production(27, [10, 1]),
             Production(27, [12, 1]),
             Production(27, [11, 1]),
             Production(27, [26])
         ]
示例#30
0
 def makeCuteProduction(self):
     for key, value in self.Prod.items():
         newVals = []
         for v in value:
             newVals.append(v.split())
         self.cuteProductions.append(Production(key, newVals))
示例#31
0
from Production import Production

p = Production()
p.run()