240 likes | 385 Views
Parser LexML. João Lima. Tópicos. Parser Aplicações Tipos Ferramentas ANTLR Implementação Próximos passos. Parser - Aplicações. Filtros Traduz uma entrada em uma saída sem considerar uma gramática Validadores Verifica se uma entrada obedece a uma gramática Processadores
E N D
Parser LexML João Lima
Tópicos • Parser • Aplicações • Tipos • Ferramentas • ANTLR • Implementação • Próximos passos
Parser - Aplicações • Filtros • Traduz uma entrada em uma saída • sem considerar uma gramática • Validadores • Verifica se uma entrada obedece a uma gramática • Processadores • Valida e Processa (sem re-escrita) • Ações: cálculos, atualizar banco de dados, etc. • Tradutores • Valida e Traduz • a entrada em outro formato
Parser - Tipos • LL(k) • Top-down parser • Left-to-right • Derivação à esquerda (da entrada) • Impossibilita regras com recursividade à esquerda • Mais fácil para entender e depurar • LR(k) • Bottom-up parser • Left-to-right • Derivação à direita (da entrada)
Ferramentas • Qual ferramenta utilizar? • Perl, awk? • Tradução léxica (não gramatical) • Lexer/Parser • YACC/Bison, Lex, GOLD, Grammatica, Spirit • ANTLR • ANother Tool for Language Recognition
Etapas básicas Lexer caracteres Tabela de Símbolos tokens Parser Árvore sintática
Código aberto - Licença BSD LL(*) extensão LL(k) Predicados semânticos e sintáticos Memoized Backtracking Otimiza a performance do lookahead Unicode Lexer Hierárquico Regras hierarquizadas Target Languages Java, C, C++, C#, Objective-C, Ruby, Python EBNF Sintaxe mais concisa que BNF AST Abstract Syntax Tree Tipos adicionais de Gramática Tree Grammar Lexer Grammar (filtro=true) ANTLRWorks IDE para criação de gramáticas Syntax Diagram Error Detection ANTLR v. 3.0.1
Etapas (ANTLR) Lexer caracteres Tabela de Símbolos tokens Parser AST P(Tree) Saída (XML)
ANTLR – como codificar e executar • Codifica gramática utilizando a IDE (ANTLRWorks) • Gera código na linguagem destino (Java) • Normaliza.g • LexML.g • GeraXML.g • Linguistico.g • Cria programa para efetuar as chamadas aos parser • PipeLexML.java • Funções estáticas auxiliares • UtilLexml • Executa “PipeLexML lei8112.txt”
Passos • java -ms64m -mx1G org.antlr.Tool Normaliza.g • java -ms64m -mx1G org.antlr.Tool LexML.g • java -ms64m -mx1G org.antlr.Tool GeraXML.g • java -ms64m -mx1G org.antlr.Tool Linguistico.g • javac *.java • java PipeLexML %1
Parser LexML (atual) Normaliza.g Lexer Parser Arq.txt Arq_Normal.txt LexML.g Lingüístico.g GeraXML.g Arq_LexML.xml Arq_LexML Lang.xml
Normaliza • Trata espaços, tabs, quebras de linhas repetidos • Trata caracteres especiais • Ordinal / Grau / “o” sobre-escrito
Normaliza.g lexer grammar Normaliza; options { filter=true; } WSinterno : (' '|'\t')(' '|'\t')+ {setText(" ");}; Normaliza : ( WS* '\r'? '\n' )+ WS* // normaliza final(is) de linha(s) {setText("\r\n");} | ('\t') // troca tab por branco {setText(" ");} | ('\u0096') // troca travessao pequeno por hifen {setText("-");} | ('0'..'9') ('o'|'°') (' '|','|';'|'.') // acerta ordinal 9o {String termo = getText(); setText(termo.substring(0, 1)+"º"+termo.substring(2));} ; Resto : .; fragment WS : (' '|'\t')+;
Programa “PipeLexML arq.txt” //FASE NORMALIZACAO //arquivo de entrada FileInputStream fstream = new FileInputStream(args[0]); // Filtro de Normalização ANTLRInputStream input = new ANTLRInputStream(fstream); NormalizaLexer lexFiltro = new NormalizaLexer(input); TokenStream tokensFiltro = new CommonTokenStream(lexFiltro); System.err.println("Fase Normalização - OK"); System.setOut(new PrintStream(new FileOutputStream(args[0]+"_Normal.txt"))); System.out.println(tokensFiltro.toString());
LexMLLexer - exemplo TITULOROT : {getCharPositionInLine()==0}? ('Título'|'TÍTULO') | ('Título'|'TÍTULO') {$type = PALAVRA;} ; CAPITULOROT : {getCharPositionInLine()==0}? ('Capítulo'|'CAPÍTULO') | ('Capítulo'|'CAPÍTULO') {$type = PALAVRA;} ; SECAOROT : {getCharPositionInLine()==0}? ('Seção'|'SEÇÃO') | ('Seção'|'SEÇÃO') {$type = PALAVRA;} ; SUBSECAOROT : {getCharPositionInLine()==0}? ('Subseção'|'SUBSEÇÃO') | ('Subseção'|'SUBSEÇÃO') {$type = PALAVRA;} ; PARTEROT : {getCharPositionInLine()==0}? ('Parte'|'PARTE') | ('Parte'|'PARTE') {$type = PALAVRA;} ; PALAVRA : ('a'..'z'|'A'..'Z'|'Ç'|'ç'|'Ã'|'ã'|'Â'|'À'|'à'|'â'|'á'|'é'|'í'|'ó'|'ô'|'ú'|'Ü'|'ü'|'Á'|'É'|'Í'|'Ó'|'Ô'|'Ú'|'ê'|'Ê'|'õ'|'Õ'|'\'')+;
LexMLLexer e Parser // Parser do Texto Normalizado e criação de Árvore em Memória LexMLLexer lexer = new LexMLLexer(new ANTLRStringStream(tokensFiltro.toString())); TokenRewriteStream tokens = new TokenRewriteStream(lexer); LexMLParser parser = new LexMLParser(tokens); LexMLParser.lexml_return r = parser.lexml(); System.err.println("Fase Parser - OK"); // arquivo de saída (básico) System.setOut(new PrintStream(new FileOutputStream(args[0]+"_LexML.xml"), true, "UTF-8")); // Passeio na árvore, externalizando o XML CommonTree t = (CommonTree)r.getTree(); CommonTreeNodeStream nodes = new CommonTreeNodeStream(t); nodes.setTokenStream(tokens); GeraXML walker = new GeraXML(nodes); // cria a árvore Walker GeraXML.lexml_return r2 = walker.lexml(); System.err.println("Fase Geração do LexXML - OK");
Linguistico.g lexer grammar Linguistico; options { filter=true; } //{System.err.println(" Achei "+getText() );} LinguaLa : // latin (' '|','|';'|'.'|'(') 'caput' (' '|','|';'|'.'|')') {setText(getText().substring(0, 1)+"<span lang=\"la\">"+getText().substring(1, getText().length() -1)+"</span>"+getText().substring(getText().length()-1));} ; LinguaEn : // ingles (' '|','|';'|'.'|'(') 'leasing' (' '|','|';'|'.'|')') {setText(getText().substring(0, 1)+"<span lang=\"en\">"+getText().substring(1, getText().length() -1)+"</span>"+getText().substring(getText().length()-1));} ; Resto : . ;
Parser LexML(final) Normaliza.g Lexer Lexer Lexer Parser Parser Parser LexML.g LexMLFlex.g Links.g Não GeraXMLF.g Ok? Lingüístico.g GeraXML.g Sim
Próximos passos • Considerar Alteração de Norma • Reconhecer entrada html • Analisador de Remissões • LexML Flexível • Parser • Decisão Monocrática, Acórdãos • Parser Semântico