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() }))
def parser_LL1(): """ LL(1) Subsection """ st.title('Parser LL(1)') result = gp.load_grammar() if result[0]: st.error('No se ha definido una gramatica\ o la gramatica definida no es correcta') return G = result[1] if not isLL1(G): st.error('La gramática definida no es LL(1)\ , no se puede aplicar este algoritmo de parsing') return options = ['Tabla de Parsing', 'Parsear Cadena'] selected = st.multiselect('', options) if options[0] in selected: st.title('Tabla LL(1)') frame = LL1_to_dataframe(G) st.write(frame) if options[1] in selected: parser = metodo_predictivo_no_recursivo(G) render_parser(G, 'método predictivo no recursivo', parser)
def parser_LALR1(): """ LALR(1) Subsection """ st.title('Parser LALR(1)') result = gp.load_grammar() if result[0]: st.error('No se ha definido una gramatica\ o la gramatica definida no es correcta') return options = ['Tabla de parsing', 'Autómata LALR(1)', 'Parsear cadena'] G = result[1] lalr1_parser = LALR1Parser(G) if len(lalr1_parser.conflicts) > 0: options.remove('Parsear cadena') if lalr1_parser.conflicts[0].type == SHIFT_REDUCE: st.error('La gramática definida tiene conflictos\ Shift-Reduce') if lalr1_parser.conflicts[0].type == REDUCE_REDUCE: st.error('La gramática definida tiene conflictos\ Reduce-Reduce') for conf in lalr1_parser.conflicts: st.code(f'{conf.value[0]}\n{conf.value[1]}') # TODO Report conflict string... # r1, r2 = generate_lr_conflict_string(G, lalr1_parser) # st.subheader('Cadenas de conflicto:') # st.code(f'{r1}\n{r2}') selected = st.multiselect('', options) if 'Tabla de parsing' in selected: lalr1_parser._build_parsing_table() goto = LR_table_to_dataframe(lalr1_parser.goto) action = LR_table_to_dataframe(lalr1_parser.action) st.title('GOTO') st.write(goto) st.title('Action') st.write(action) if 'Autómata LALR(1)' in selected: st.title('Automata LALR(1)') automaton = build_LALR1_automaton( lalr1_parser.G.AugmentedGrammar(True)) st.graphviz_chart(str(automaton.graph())) if 'Parsear cadena' in selected: render_parser(G, 'método LALR(1)', lalr1_parser)
def grammar_details(): 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])) return G = result[1] st.header('Detalles de la gramatica:') options = [ 'Gramática', 'Gramática simplificada', ] selected = st.selectbox('', options) if options[0] == selected: st.markdown('# Gramática original') render_grammar(G) elif options[1] == selected: st.markdown('# Gramática simplificada\n\ * Sin recursión izquierda inmediata\n\ * Sin producciones innecesarias\n\ * Sin prefijos comunes') new_G = G.copy() pipeline = GrammarPipeline(new_G, [ remove_epsilon, remove_unit, remove_vars_nothing, remove_unreachable, remove_left_recursion, remove_ambiguity ]) pipeline.run() render_grammar(new_G) if options[0] == selected: lr_result = gp.has_left_recursion(G) if lr_result: st.warning('La gramática tiene recursión izquierda:\ {} -> {}'.format(lr_result.Left, lr_result.Right)) if st.checkbox('Autómata Regular'): render_regular_automaton(G)
def parser_LL1(): """ LL(1) Subsection """ st.title('Parser LL(1)') result = gp.load_grammar() if result[0]: st.error('No se ha definido una gramatica\ o la gramatica definida no es correcta') return G = result[1] options = ['Tabla de Parsing', 'Parsear Cadena'] M = build_parsing_table(G) if not isLL1(G, M): st.error('La gramática definida no es LL(1)') options.remove('Parsear Cadena') # Get conflicts pair = get_ll1_conflict(M) c1, c2 = M[pair[0], pair[1]][:2] st.subheader('Producciones de conflicto:') st.code(f'{c1}\n{c2}') s1, s2 = generate_ll1_conflict_string(G, M, pair) st.subheader('Cadenas de conflicto') st.code(f'{s1}\n{s2}') selected = st.multiselect('', options) if options[0] in selected: st.title('Tabla LL(1)') frame = LL1_to_dataframe(G) st.write(frame) if len(options) > 1 and options[1] in selected: parser = metodo_predictivo_no_recursivo(G) render_parser(G, 'método predictivo no recursivo', parser, is_ll1=True)
def parser_LALR1(): """ LALR(1) Subsection """ st.title('Parser LALR(1)') result = gp.load_grammar() if result[0]: st.error('No se ha definido una gramatica\ o la gramatica definida no es correcta') return G = result[1] lalr1_parser = LALRParser(G) # try: # lalr1_parser = LALRParser(G) # except Exception: # st.error('La gramática definida tiene conflictos\ # Shift-Reduce o Reduce-Reduce') # return options = ['Tabla de parsing', 'Autómata LALR(1)', 'Parsear cadena'] selected = st.multiselect('', options) if options[0] in selected: lalr1_parser._build_parsing_table() goto = LR_table_to_dataframe(lalr1_parser.goto) action = LR_table_to_dataframe(lalr1_parser.action) st.title('GOTO') st.write(goto) st.title('Action') st.write(action) if options[1] in selected: st.title('Automata LR(0)') automaton = build_lalr_automaton(lalr1_parser.G.AugmentedGrammar(True)) st.graphviz_chart(str(automaton.graph())) if options[2] in selected: render_parser(G, 'método LALR(1)', lalr1_parser)
if st.button('Insertar gramatica'): # Basic parsing if initial and terminals and productions: initial = gp.normalize(initial) terminals = gp.normalize(terminals) non_terminals = gp.normalize(non_terminals) productions = gp.normalize(productions) gp.insert_grammar(initial, terminals, non_terminals, productions) st.success('Gramatica definida') else: st.error('Quedan parametros por definir') # Detalles de la gramatica elif choice == choices[1]: 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] st.header('Detalles de la gramatica:') render_grammar(G, 'G') lr_result = gp.has_left_recursion(G) if lr_result: st.warning('La gramática tiene recursión izquierda:\ {} -> {}'.format(lr_result.Left, lr_result.Right)) elif (not isLL1(G)):
""" For debug & testing """ import pandas as pd from utils import grammar_processing as gp from utils.first_follow import compute_firsts, compute_follows from utils.grammar_cleaner import (GrammarPipeline, remove_ambiguity, remove_epsilon, remove_left_recursion, remove_unit, remove_unreachable, remove_vars_nothing) from utils.tokenizer import tokenize from utils.Parsers.parserLR1 import LR1Parser from utils.conflicts.lr_conflict import generate_lr_conflict_string G = gp.load_grammar()[1] lr1_parser = LR1Parser(G) assert len(lr1_parser.conflicts) > 0, "Grammar has no conflicts" r1, r2 = generate_lr_conflict_string(G, lr1_parser) st.subheader('Cadenas de conflicto:') st.code(f'{r1}\n{r2}')