예제 #1
0
def first_follows():
    result = gp.load_grammar()
    if result[0]:
        st.error('No se ha definido una gramatica\
             o la gramatica definida no es correcta')
        st.error('Errors: ' + str(result[1]))
    else:
        G = result[1]

        firsts = compute_firsts(G)
        follows = compute_follows(G, firsts)

        st.subheader('Firsts:')

        st.write(
            pd.DataFrame({
                'keys': firsts.keys(),
                'values': firsts.values()
            }))

        st.subheader('Follows:')

        st.write(
            pd.DataFrame({
                'keys': follows.keys(),
                'values': follows.values()
            }))
예제 #2
0
    def _build_parsing_table(self):
        G = self.G.AugmentedGrammar(True)
        firsts = compute_firsts(G)
        follows = compute_follows(G, firsts)

        automaton = build_LR0_automaton(G).to_deterministic()
        for i, node in enumerate(automaton):
            if self.verbose:
                print(i, '\t', '\n\t '.join(str(x) for x in node.state), '\n')
            node.idx = i

        for node in automaton:
            idx = node.idx
            for state in node.state:
                item = state.state
                # Your code here!!!
                # - Fill `self.Action` and `self.Goto` according to `item`)
                # - Feel free to use `self._register(...)`)
                if item.IsReduceItem:
                    prod = item.production
                    if prod.Left == G.startSymbol:
                        self._register(self.action, (idx, G.EOF), (self.OK, None))
                    else:
                        for t in follows[prod.Left]:
                            self._register(self.action, (idx, t), (self.REDUCE, prod))
                else:
                    symbol = item.NextSymbol
                    goto_id = node.get(symbol.Name).idx
                    if goto_id is not None:
                        if symbol.IsTerminal:
                            self._register(self.action, (idx, symbol), (self.SHIFT, goto_id))
                        else:
                            self._register(self.goto, (idx, symbol), goto_id)
예제 #3
0
파일: parser.py 프로젝트: svex99/compilers1
def isLL1(G, M=None):
    if not M:
        firsts = compute_firsts(G)
        follows = compute_follows(G, firsts)
        M = build_parsing_table(G, firsts, follows)

    for cell in M:
        if len(M[cell]) > 1:
            return False
    return True
예제 #4
0
def build_parsing_table(G, firsts=None, follows=None):
    # init parsing table
    if firsts is None:
        firsts = compute_firsts(G)
    if follows is None:
        follows = compute_follows(G, firsts)
    M = {}

    # P: X -> alpha
    for production in G.Productions:
        X = production.Left
        alpha = production.Right

        ###################################################
        # working with symbols on First(alpha) ...
        ###################################################
        #                   <CODE_HERE>                   #
        ###################################################

        first = compute_local_first(firsts, alpha)

        for t in first:
            if M.get((X, t)):
                M[(X, t)].append(production)
            else:
                M[(X, t)] = [production]

        ###################################################
        # working with epsilon...
        ###################################################
        #                   <CODE_HERE>                   #
        ###################################################

        try:
            alpha_is_epsilon = alpha.IsEpsilon
        except:
            alpha_is_epsilon = False

        if alpha_is_epsilon:
            for t in follows[X]:
                if M.get((X, t)):
                    M[(X, t)].append(production)
                else:
                    M[(X, t)] = [production]

    # parsing table is ready!!!
    return M
예제 #5
0
def generate_lr_conflict_string(G, parser):
    automaton = build_LR1_automaton(G.AugmentedGrammar(True))
    states = {}

    for it, node in enumerate(automaton):
        states[it] = node

    # for conf in parser.conflicts:
    #     print(f'conf.key {conf.key}, conf.value {conf.value}')
    #     if conf.value[0][0] == 'REDUCE':
    #         st, symbol = conf.key
    #         production = conf.value[0][1]
    #         print(states[st])
    #     if conf.value[1][0] == 'REDUCE':
    #         st, symbol = conf.key
    #         production = conf.value[1][1]
    #         print(states[st])

    st, symbol = parser.conflicts.key
    _, production = parser.action[st, symbol].pop()
    print(f'state: {st}')
    print(f'symbol: {symbol}')

    assert (st is not None and production is not None and symbol is not None)

    print(production)
    input()
    path = sentence_path(automaton, states[st], symbol, production)

    for p in path:
        print(f'path: {p}')
    input()

    firsts = compute_firsts(G)
    follows = compute_follows(G, firsts)

    extended = expand_path(automaton, path, follows)

    return extended
예제 #6
0
def LL1_to_dataframe(G):
    firsts = compute_firsts(G)
    follows = compute_follows(G, firsts)
    M = build_parsing_table(G, firsts, follows)

    rows, columns = set(), set()
    matrix = []

    for item in M:
        rows.add(item[0])
        columns.add(item[1])

    for row in rows:
        matrix.append([])
        for column in columns:
            try:
                production = M[row, column][0]
                matrix[-1].append(
                    str(production.Left) + ' -> ' + str(production.Right))
            except KeyError:
                matrix[-1].append(' ')

    return pd.DataFrame(matrix, index=rows, columns=columns)
예제 #7
0
def LL1_to_dataframe(G):
    firsts = compute_firsts(G)
    follows = compute_follows(G, firsts)
    M = build_parsing_table(G, firsts, follows)

    rows, columns = set(), set()
    matrix = []

    for item in M:
        rows.add(item[0])
        columns.add(item[1])

    for row in rows:
        matrix.append([])
        for column in columns:
            try:
                productions = ""
                for prod in M[row, column]:
                    productions += f'{prod.Left} -> {prod.Right}\n'
                matrix[-1].append(productions)
            except KeyError:
                matrix[-1].append(' ')

    return pd.DataFrame(matrix, index=rows, columns=columns)
예제 #8
0
            st.success('La gramática transformada es LL(1).')
        else:
            st.error('La gramática transformada tampoco es LL(1).')

# Calcular Firsts & Follows
elif choice == choices[2]:
    result = gp.load_grammar()
    if result[0]:
        st.error('No se ha definido una gramatica\
             o la gramatica definida no es correcta')
        st.error('Errors: ' + str(result[1]))
    else:
        G = result[1]

        firsts = compute_firsts(G)
        follows = compute_follows(G, firsts)

        st.subheader('Firsts:')

        st.write(pd.DataFrame({
            'keys': firsts.keys(),
            'values': firsts.values()
        }))

        st.subheader('Follows:')

        st.write(pd.DataFrame({
            'keys': follows.keys(),
            'values': follows.values()
        }))
예제 #9
0
파일: parser.py 프로젝트: svex99/compilers1
def metodo_predictivo_no_recursivo(G, M=None, firsts=None, follows=None):

    # checking table...
    if M is None:
        if firsts is None:
            firsts = compute_firsts(G)
        if follows is None:
            follows = compute_follows(G, firsts)
        M = build_parsing_table(G, firsts, follows)
    
    
    # parser construction...
    def parser(w):
        
        ###################################################
        # w ends with $ (G.EOF)
        ###################################################
        # init:
        ### stack =  ????
        ### cursor = ????
        ### output = ????
        ###################################################
        stack = [G.startSymbol]
        cursor = 0
        output = []
        
        # parsing w...
        while len(stack) > 0 and cursor < len(w):
            top = stack.pop()
            a = w[cursor]
    
            ###################################################
            #                   <CODE_HERE>                   #
            ###################################################

            nextToken = cursor
            
            if top.IsTerminal:
                nextToken += 1
                
                if a != top:
                    # print(a, "!=", top)
                    return False
            
            elif top.IsNonTerminal:
                if not M.get((top, w[nextToken])):
                    return False
                production = M[ (top, w[nextToken]) ][0]
                prodRight = production.Right
                
                # if not production:
                #     return False
                
                output.append(production)
                
                for i in range(len(prodRight) - 1, -1, -1):
                    stack.append(prodRight[i])
                
            cursor = nextToken
        
        if len(stack) or cursor != len(w) - 1:
            # print("different size: ", len(stack), "!= 0 or", cursor, "!=", len(w))
            # print("the partial output is: ", output)
            return False
        # left parse is ready!!!
        return output
    
    # parser is ready!!!
    return parser