예제 #1
0
    def imprt(self, im):
        self.automata = NFA(
            set(im['sigma']),
            set(im['Q']),
            im['q0'],
            im['delta'],
            set(im['F']),
        )

        self.automata.addtoken(im['token'])
예제 #2
0
def union(nfa1, nfa2):
    last1 = len(nfa1.Q) - 1
    last2 = len(nfa1.Q) + len(nfa2.Q) - 1

    d1 = copy.deepcopy(nfa1.delta)
    d1.append({'$': last2 + 2})

    d2 = copy.deepcopy(nfa2.delta)
    for k, elm in enumerate(d2):
        for key in elm:
            if type(d2[k][key]) == type(1):
                d2[k][key] = d2[k][key] + last1 + 1
            else:
                d2[k][key] = [elem + last1 + 1 for elem in d2[k][key]]

    d2.append({'$': last2 + 2})

    d3 = d1 + d2
    d3.append({'$': [nfa1.q0, nfa2.q0 + last1 + 1]})

    sigma = nfa1.sigma.union(nfa2.sigma)
    Q = nfa1.Q.union([elem + last1 + 1 for elem in nfa2.Q])
    Q = Q.union({last2 + 1, last2 + 2})
    q0 = last2 + 1
    F = {last2 + 2}

    nfa3 = NFA(sigma, Q, q0, d3, F)
    return nfa3
예제 #3
0
def nfa_dfa(nfa):
    dn = copy.deepcopy(nfa.delta)

    Q = set({})
    d = {}

    start = e_cl(nfa, nfa.q0)
    xtr = {str(start)}
    visited = set({})

    q0 = str(start)

    F = set({})
    f1 = nfa.F

    while len(xtr):
        xtr.remove(str(start))

        for fnl in f1:
            if fnl in start:
                F.add(str(start))

        if str(start) not in visited:
            visited.add(str(start))
            if len(start):
                Q.add(str(start))

            for k in nfa.sigma:
                e = set({})

                for elm in start:
                    if elm < len(nfa.delta) and k in nfa.delta[elm]:
                        dlt = nfa.delta[elm][k]
                        if type(dlt) == type(1):
                            e = e.union(e_cl(nfa, dlt))
                        else:
                            for itm in dlt:
                                e = e.union(e_cl(nfa, itm))

                if len(e):
                    if str(start) not in d:
                        d[str(start)] = {}
                    d[str(start)][k] = str(e)

                xtr.add(str(e))

        start = '' if len(xtr) < 1 else eval(list(xtr)[0])

    dfa = NFA(nfa.sigma, Q, q0, d, F)
    return dfa
예제 #4
0
def kleene(nfa1):
    last = len(nfa1.Q) - 1

    d1 = copy.deepcopy(nfa1.delta)
    d1.append({'$': [nfa1.q0, last + 2]})
    d1.append({'$': [nfa1.q0, last + 2]})

    sigma = copy.deepcopy(nfa1.sigma)
    Q = nfa1.Q.union([last + 1, last + 2])
    q0 = last + 1
    F = {last + 2}

    nfa3 = NFA(sigma, Q, q0, d1, F)
    return nfa3
예제 #5
0
def parser(expresion, nfa):
    c = expresion[0]
    c1 = expresion[1]

    op = {'(', '*', '|'}

    if c not in op:
        ax = NFA({c}, {0, 1}, 0, [{c: 1}], [1])

        if len(nfa.Q):
            nfa = conc(nfa, ax)

            if len(expresion) > 1:
                return parser(expresion[1::], nfa)

        else:
            return ax

    return nfa
예제 #6
0
def conc(nfa1, nfa2):
    last = len(nfa1.Q)

    d1 = copy.deepcopy(nfa1.delta)
    d2 = copy.deepcopy(nfa2.delta)

    d1.append({'$': nfa2.q0 + last})

    for k, elm in enumerate(d2):
        for key in elm:
            if type(d2[k][key]) == type(1):
                d2[k][key] = d2[k][key] + last
            else:
                d2[k][key] = [nm + last for nm in d2[k][key]]
    d3 = d1 + d2

    nfa3 = NFA(nfa1.sigma.union(nfa2.sigma),
               nfa1.Q.union([elm + last for elm in nfa2.Q]), nfa1.q0, d3,
               set([elm + last for elm in nfa2.F]))

    return nfa3
예제 #7
0
 def preorder(self, root, vl):
     child = root.children[::-1]
     if root.name == 'a':
         var = vl.pop()
         return NFA({var}, {0, 1}, 0, [{var: 1}], [1])
     elif root.name == 'A':
         return self.preorder(child[0], vl)
     elif root.name == 'K':
         if child[1].children[0].name == '*':
             return kleene(self.preorder(child[0], vl))
         else:
             return self.preorder(child[0], vl)
     elif root.name == 'C' or root.name == 'CP':
         if len(child) > 1:
             l = self.preorder(child[0], vl)
             r = self.preorder(child[1], vl)
             if l == '':
                 return r
             elif r == '':
                 return l
             else:
                 return conc(l, r)
         else:
             return ''
     elif root.name == 'U' or root.name == 'UP':
         if len(child) > 1:
             l = self.preorder(child[0], vl)
             r = self.preorder(child[1], vl)
             if l == '':
                 return r
             elif r == '':
                 return l
             else:
                 return union(l, r)
         else:
             return ''
     else:
         return ''
예제 #8
0
class RGXGRMM():
    terminal = {'|', '*', '(', ')', 'a', '$'}
    non_terminal = {'U', 'UP', 'C', 'CP', 'K', 'KP', 'A'}
    ll1_Table = {
        'U': {
            '|': None,
            '*': None,
            '(': ['C', 'UP'],
            ')': None,
            'a': ['C', 'UP'],
            '$': None
        },
        'UP': {
            '|': ['|', 'C', 'UP'],
            '*': None,
            '(': None,
            ')': [''],
            'a': None,
            '$': ['']
        },
        'C': {
            '|': None,
            '*': None,
            '(': ['K', 'CP'],
            ')': None,
            'a': ['K', 'CP'],
            '$': None
        },
        'CP': {
            '|': [''],
            '*': None,
            '(': ['K', 'CP'],
            ')': [''],
            'a': ['K', 'CP'],
            '$': ['']
        },
        'K': {
            '|': None,
            '*': None,
            '(': ['A', 'KP'],
            ')': None,
            'a': ['A', 'KP'],
            '$': None
        },
        'KP': {
            '|': [''],
            '*': ['*'],
            '(': [''],
            ')': [''],
            'a': [''],
            '$': ['']
        },
        'A': {
            '|': None,
            '*': None,
            '(': ['(', 'U', ')'],
            ')': None,
            'a': ['a'],
            '$': None
        }
    }

    def reco(self, inpt):
        inpt = inpt + '$'
        stack = ['$', 'U']
        p_stack = []

        idx = 0

        root = Node('U')
        p_stack.append(root)

        while True:
            crr = stack.pop()

            if crr in self.non_terminal or crr == '':
                if crr != '':
                    if self.ll1_Table[crr][inpt[idx]] is None:
                        return 'error token: ' + str(
                            inpt[idx]) + ' rule: ' + crr
                    stack = stack + self.ll1_Table[crr][inpt[idx]][::-1]
                    ft = p_stack.pop()
                    while ft.name in self.terminal:
                        ft = p_stack.pop()
                    for nt in self.ll1_Table[crr][inpt[idx]][::-1]:
                        if nt not in {'|', '(', ')'}:
                            if nt != '':
                                p_stack.append(Node(nt, parent=ft))
                            else:
                                Node(nt, parent=ft)

            elif crr in self.terminal:
                if crr == '$':
                    break
                elif crr == inpt[idx]:
                    idx += 1
                else:
                    return 'error token: ' + str(inpt[idx]) + ' rule: ' + crr

            else:
                return 'error token: ' + str(inpt[idx]) + ' rule: ' + crr

        if inpt[idx] == '$':
            return root
        else:
            return 'error, final token: ' + str(inpt[idx])

    def preorder(self, root, vl):
        child = root.children[::-1]
        if root.name == 'a':
            var = vl.pop()
            return NFA({var}, {0, 1}, 0, [{var: 1}], [1])
        elif root.name == 'A':
            return self.preorder(child[0], vl)
        elif root.name == 'K':
            if child[1].children[0].name == '*':
                return kleene(self.preorder(child[0], vl))
            else:
                return self.preorder(child[0], vl)
        elif root.name == 'C' or root.name == 'CP':
            if len(child) > 1:
                l = self.preorder(child[0], vl)
                r = self.preorder(child[1], vl)
                if l == '':
                    return r
                elif r == '':
                    return l
                else:
                    return conc(l, r)
            else:
                return ''
        elif root.name == 'U' or root.name == 'UP':
            if len(child) > 1:
                l = self.preorder(child[0], vl)
                r = self.preorder(child[1], vl)
                if l == '':
                    return r
                elif r == '':
                    return l
                else:
                    return union(l, r)
            else:
                return ''
        else:
            return ''

    def reg_lex(self, expresion):
        fn = ''
        var = []
        for x in expresion:
            if x == ' ':
                continue
            if x == '(' or x == ')' or x == '*' or x == '|':
                fn += x
            elif x == '$':
                return 'error, unexpected token: ' + x
            else:
                fn += 'a'
                var.append(x)

        return var, fn

    def regular_expresion(self, expresion):
        vL, tokens = self.reg_lex(expresion)
        x = self.reco(tokens)

        return nfa_dfa(self.preorder(x, vL[::-1]))

    def evaluar(self, cadena):
        return self.automata.reco(cadena)

    def export(self):
        return self.automata.export()

    def imprt(self, im):
        self.automata = NFA(
            set(im['sigma']),
            set(im['Q']),
            im['q0'],
            im['delta'],
            set(im['F']),
        )

        self.automata.addtoken(im['token'])

    def __init__(self, expresion, token):
        self.token = token
        if (type(expresion) == type('')):
            self.automata = self.regular_expresion(expresion)
            self.automata.addtoken(token)
        else:
            self.imprt(expresion)