Aula sobre JavaCC Parsing Tarciana Dias tds@cin.ufpe.br Abril 2013.

Slides:



Advertisements
Apresentações semelhantes
Programação em Java Prof. Maurício Braga
Advertisements

Programação em Java Prof. Maurício Braga
Software Básico Silvio Fernandes
Avaliador de Expressões
Programação em Java Prof. Maurício Braga
Estruturas de Repetição
Tratamento de Exceções
Software Básico Silvio Fernandes
Padrão de Projeto Interpreter
Java: Pacotes e Modificadores de Visibilidade
Java: Pacotes e Modificadores de Visibilidade
Compiladores Prof. Yandre Maldonado Compiladores - Prof. Yandre - 1.
Programação Básica em Java
Árvores.
April 05 Prof. Ismael H. F. Santos - 1 Modulo II CheckStyle Professor Ismael H F Santos –
April 05 Prof. Ismael H. F. Santos - 1 Modulo II Findbugs Professor Ismael H F Santos –
JavaCC e JJTree Geração de compiladores implementados em Java
Curso Sistemas de Informação Disciplina: Arquitetura de Software
Wagner Santos C. de Jesus
YACC.
Análise Sintática Ascendente
Relações em uma Gramática
Construção de Compiladores
9 Controle de fluxo Seqüenciadores. Jumps. Escapes. Exceções.
Construção de Compiladores
André Luis Meneses Silva
Uso do Eclipse/SourceForge Paradigmas de Linguagem de Programação
Classes e objetos Arrays e Sobrecarga
Introdução a Programação JAVA
Análise léxica e sintática
Árvores binárias de pesquisa com balanceamento
Ferramentas para a Construção de Compiladores: Lex & Yacc
Compiladores, Aula Nº 19 João M. P. Cardoso
Streams –input e output
Aula 17 1 Análise Sintáctica Compiladores, Aula Nº 17 João M. P. Cardoso.
Análise Sintática – Parte 1
Teoria e Implementação de Linguagens Computacionais – IF688
Sintaxe e Semântica Prof.: Gláucya Carreiro Boechat
Semântica de Linguagens de Programação
Análises léxica e sintática
Mayerber Carvalho Neto
Análise Léxica e Sintática
1 JavaCC Prof. Alexandre Monteiro Baseado em material cedido pelo Prof. Euclides Arcoverde Recife.
Curso de Aprendizado Industrial Desenvolvedor WEB Disciplina: Programação Orientada a Objetos I Professora: Cheli Mendes Costa This.
Analise sintática aula-07-analise-sintática.pdf.
FORMATANDO O TRABALHO NO WORD 2007
Aulas 2 e 3 – Java – Prof. Marcelo Heitor # O método main e argumentos na linha de comando; # Fluxo padrão de entrada e saída; # A classe JOptionPane;
Listas Simplesmente Encadeadas
Wagner Santos C. de Jesus
Análises léxica e sintática
Laboratório I Mateus Raeder Material baseado nos originais da Profa. Denise Bandeira.
Compiladores.
Análise Sintática Prof. Alexandre Monteiro
Aula Prática 4 Monitoria IP/CC (~if669).
Análise Léxica Prof. Alexandre Monteiro
Tradução Dirigida por Sintaxe
Coleções, Genéricos, Threads Marco Antonio. Collection Principais métodos da interface Collection.
Certificação Marco Antonio. Introdução A compreensão desse capítulo é muito importante pois trata de um assunto essencial em qualquer linguagem de programação,
Revisão Compiladores – AP2
Análise Sintática de Descida Recursiva
Um Tradutor Dirigido por Sintaxe Simples
1 CIn / UFPE Parsing Tarciana Dias / Gustavo Carvalho / Março 2012.
JavaCC.
Sintaxe de uma Linguagem
PLP – JavaCC Java Compiler Compiler
Analisador sintático: Tipos de análises sintáticas
1 CIn / UFPE Algoritmos de Parsing Gustavo Carvalho Março 2011.
Faculdade Pernambuca - FAPE Compiladores Abril/2007 Compiladores Abril/2007.
PROGRAMAÇÃO ORIENTADA A OBJETOS Carlos Marques
1 CIn / UFPE Introdução a Parsing Gustavo Carvalho Abril 2015.
Transcrição da apresentação:

Aula sobre JavaCC Parsing Tarciana Dias tds@cin.ufpe.br Abril 2013

Roteiro Sobre o JavaCC – forma de especificação das gramáticas Instalando o plugin do JavaCC no eclipse Análise da gramática default gerada pelo JavaCC Analisando a linguagem de expressões 1 Revisando conceitos básicos de gramáticas LL Aplicando os conceiros na gramática do exp1 Referências

Exemplo 1 Gramática Start := NUMBER ( “+” NUMBER )

Classe do parser parser = new Adder(new FileInputStream("input.txt")); options { STATIC = false ; } PARSER BEGIN(Adder) public class Adder { static void main( String[] args ) throws ParseException, TokenMgrError { Adder parser = null; try { parser = new Adder(new FileInputStream("input.txt")); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); System.out.println(parser.start());} PARSER END(Adder)

Analisador léxico SKIP : { ” ” } SKIP : { ”\n” | ”\r” | ”\r\n” } TOKEN : { < PLUS : ”+” > } TOKEN : { < NUMBER : ([”0”-”9”])+ > }

Gramática “EBNF” void Start() : {} { <NUMBER> ( <PLUS> )* <EOF> }

Possiveis saidas Entrada válida: 1 + 5 Token inválido: 1 – 3 ( Exceção) Erro sintático: 1 ++ 5 (Exceção)

Código gerado final public void start() throws ParseException { jj_consume_token(NUMBER); label_1: while (true) { switch ((jj_ntk==-1)? jj_ntk() : jj_ntk) { case PLUS: ;break; default: jj_la1[0] = jj_gen; break label_1; } jj_consume_token(PLUS); jj_consume_token(0); }

Adicionando ações int Start() throws NumberFormatException : { Token t ; int i ; int value ; } { t = <NUMBER> { i = Integer.parseInt( t.image ) ; } { value = i ; } (<PLUS> { value += i ; } )* <EOF> { return value ; }}

Roteiro Sobre o JavaCC – forma de especificação das gramáticas Instalando o plugin do JavaCC no eclipse Análise da gramática default gerada pelo JavaCC Analisando a linguagem de expressões 1 Revisando conceitos básicos de gramáticas LL Aplicando os conceiros na gramática do exp1 Referências

Plugin Eclipse Baixar o plugin: Pagina do plugin: http://eclipse-javacc.sourceforge.net/ Para atualizar o eclipse com o plugin: Pegar a pasta ...\sf.eclipse.javacc-1.5.27-plugin\plugins\sf.eclipse.javacc_1.5.27 e copiá-la para o caminho do eclipse ...\eclipse\plugins Fazer o mesmo para a pasta ...\sf.eclipse.javacc-1.5.27-plugin\features\sf.eclipse.javacc.feature_1.5.27 só que para o caminho ...\eclipse\features

Quick start plugin eclipse Criar um projeto Java no eclipse Criar uma pasta foo submissa à pasta do projeto Em seguida, criar um novo projeto só que selecionando a opção Other, escolhendo a pasta JavaCC e a opção JavaCCTemplateFile, conforme mostrado a seguir: New->Other, ir na opção javaCC-> JavaCC Template File

Quick start plugin eclipse [2]

Quick start plugin eclipse [3] Ao clicar em Next, a tela seguinte aparece. Observe que se deve indicar a gramática utilizada como referência. No caso default, ele utiliza MyNewGrammar.jj Mas podemos colocar uma das gramáticas disponíveis na página da disciplina /~in101 e vistas até então (iremos fazer depois): Expressoes1.jj ou Expressoes2.jj ou Funcional1.jj

Quick start plugin eclipse [4]

Quick start plugin eclipse [5] Após escolhida a gramática, clica-se em Finish:

Arquivos gerados EG1 EG1Constants EG1TokenManager MyNewGrammar.jj ParserException SimpleCharStream Token TokenMgrError Parei na página 7 do tutorial.

Roteiro Sobre o JavaCC – forma de especificação das gramáticas Instalando o plugin do JavaCC no eclipse Análise da gramática default gerada pelo JavaCC Analisando a linguagem de expressões 1 Revisando conceitos básicos de gramáticas LL Aplicando os conceiros na gramática do exp1 Referências

Outro Exemplo Gramática Vide MyNewGrammar.jj

Roteiro Sobre o JavaCC – forma de especificação das gramáticas Instalando o plugin do JavaCC no eclipse Análise da gramática default gerada pelo JavaCC Analisando a linguagem de expressões 1 Revisando conceitos básicos de gramáticas LL Aplicando os conceiros na gramática do exp1 Referências

Vamos agora analisar a gramática da linguagem de expressões 1 Antes disso, vamos revisar as técnicas de fatorar uma gramática à esquerda e eliminar recursões à esquerda

Conceitos Básicos Transformações de Gramática Fatoração à esquerda Ex;: XY | XZ equivale à X (Y | Z) single-Command ::= V-name := Expression | if Expression then single-Command else single-Command ( ε | else single-Command)

Conceitos Básicos Transformações de Gramática Eliminação de recursão à esquerda N ::= X | NY, onde N é um símbolo não-terminal e X e Y são REs estendidas. Esta produção é recursiva à esquerda. N ::= X(Y)* Substituindo por uma regra EBNF equivalente

Eliminando recursão à esquerda Conceitos Básicos Transformações de Gramática Identifier ::= Letter | Identifier Letter | Identifier Digit | Identifier (Letter | Digit) Identifier ::= Letter (Letter | Digit)* Fatorando à esquerda Eliminando recursão à esquerda

Conceitos Básicos A necessidade da eliminação de recursão à esquerda é melhor entendida depois que se vai usar a abordagem top-down;

Estratégias de Parsing Objetivo Reconhecimento de uma string de entrada (seqüência de tokens) e decisão se esta é ou não uma sentença de G Determinação de sua estrutura de frases (pode ser representada por uma árvore sintática) Gramática não ambígua: cada sentença tem exatamente uma syntax tree Top-Down Examina os símbolos terminais da esquerda para a direita Forma a ST (syntax tree) de cima para baixo Parsing ok: string de entrada totalmente conectada à ST L(eft-to-right) L(eft-most-derivation) => LL Bottom-Up Forma a ST (syntax tree) de baixo (nós terminais) para cima(nó raiz) Parsing ok: string de entrada reduzida a uma S-tree S(imple) L(eft-to-right) R(ight-most-derivation) => SLR L(eft-to-right) R(ight-most-derivation) => LR L(ook) A(head) L(eft-to-right) R(ight-most-derivation) => LALR ESTUDAR ESSE SLIDE NO LIVRO DO AHOA

Aqui ele não poderia ter escolhido um Subject? Estratégia Bottom-Up Exemplo: Sentence ::= Subject Verb Object Subject ::= I | a Noun | the Noun Object ::= me | a Noun | the Noun Noun ::= cat | mat | rat Verb ::= like | is | see | sees the cat sees a rat . Sentence Aqui ele não poderia ter escolhido um Subject? Object Subject O que diferencia ele ter escolhido um Object e não um Subject? O fato de antes ele já ter um Object e um Verb. Assim, parsers seguindo essa estratégia devem levar em conta os passos do parsing anteriores. Verb Noun Noun

Estratégia Top-Down the cat sees a rat . Exemplo: Sentence ::= Subject Verb Object Subject ::= I | a Noun | the Noun Object ::= me | a Noun | the Noun Noun ::= cat | mat | rat Verb ::= like | is | see | sees the cat sees a rat . Sentence Object Subject O que diferencia ele ter escolhido um Object e não um Subject? O fato de antes ele já ter um Object e um Verb. Assim, parsers seguindo essa estratégia devem levar em conta os passos do parsing anteriores. Verb Noun Noun

Estratégias de Parsing Qual estratégia de parsing devemos usar? Isso vai depender do tipo de gramática ! Sempre é necessário escolher qual regra de produção aplicar Isto é feito de acordo com o algoritmo de Parsing Recursive Descent é um algoritmo de parsing top-down Consiste de um grupo de métodos parseN, um para cada símbolo não-terminal N de G. Estes métodos cooperam para fazer o parse das sentenças completas parseSentence parseSubject parseVerb parseObject parseNoun parseNoun the cat sees a rat .

Gramáticas LL(1) Deve-se expressar a gramática em EBNF, com uma regra de produção simples para cada símbolo não-terminal, e realizar as transformações de gramática necessárias, por exemplo, sempre eliminar recursão à esquerda e fatorizar à esquerda sempre que possível Gramáticas LL(1): Se a gramática contém X | Y, starters[[ X ]] e starters[[ Y ]] devem ser disjuntos Se a gramática contém X* , starters[[ X ]] deve ser disjunto do conjunto de tokens que podem seguir X* Na prática quase toda gramática de uma linguagem de programação pode ser transformada em LL(1), sem mudar a linguagem que a gramática gera Recursive-descent parsing é somente adequado para gramáticas LL(1) Em geral, o projetista da linguagem projeta a sua sintaxe para ser adequada à um parsing recursive-descent.

Gramáticas não-LL(1) Exemplo de uma Gramáticas não LL(1): Program ::= single-Command Command ::= single-Command (; single-Command)* V-name ::= Identifier single-Command ::= V-name := Expression | Identifier ( Expression ) | if Expression then single-Command else single-Command … Expression ::= primary-Expression (Operator primary-Expression)* primary-Expression ::= Integer-Literal | Identifier

Uma simples fatoração à esquerda resolve o problema! Gramáticas não-LL(1) Desenvolvimento do método parseSingleCommand: Uma simples fatoração à esquerda resolve o problema! private void parseSingleCommand(){ switch(currentToken.kind){ case Token.IDENTIFIER: { parseVname(); accept(Token.BECOMES); parseExpression(); } break; parseIdentifier (); accept(Token.LPAREN); accept(Token.RPAREN); … V-name ::= Identifier single-Command ::= V-name := Expression | Identifier ( Expression ) | … … single-Command ::= Identifier (:= Expression | ( Expression ) )

Gramáticas não-LL(1) Exemplo de uma Gramáticas não LL(1): … Aqui, starters[[ ;Declaration ]] = {;} e o conjunto de terminais que seguem (; Declaration)* neste contexto também é {;} Como não são disjuntos, então a gramática não é LL(1) … Block::= begin Declaration (; Declaration)* ; Command end Declaration ::= integer Identifier (, Identifier)* Como resolver? private void parseBlock(){ accept(Token.BEGIN){ parseDeclaration(); while (currentToken.kind == Token.SEMICOLON) acceptIt(); } accept(Token.SEMICOLON); parseCommand(); accept(Token.END); … Block::= begin Declaration ; (Declaration;)* Command end Assumindo que starters[[(Declaration)*]] é disjunto de starters[[Command]]

Recursive Descent Parser Algoritmo de parsing para gramáticas LL Visão geral Para cada produção N, crie um método parseN Crie uma classe parser com um atributo currentToken E os métodos parseN E os métodos auxiliares: accept e acceptIt E um método público parse que chama parseS O código de cada método parseN depende da produção N A árvore é dada implicitamente pela chamada dos métodos Pode ser criada explicitamente

Roteiro Sobre o JavaCC – forma de especificação das gramáticas Instalando o plugin do JavaCC no eclipse Análise da gramática default gerada pelo JavaCC Analisando a linguagem de expressões 1 Revisando conceitos básicos de gramáticas LL Aplicando os conceiros na gramática do exp1 Referências

Criando a estrutura para a linguagem exp1 Baixar a gramática Expressoes1.jj contida em http://www.cin.ufpe.br/~in1007/linguagens/Expressoes1/expressao1.html Observar no início do arquivo que: PARSER_BEGIN(Exp1Parser) package plp.expressions1.parser; import plp.expressions1.*; import plp.expressions1.expression.*; import plp.expressions1.util.*; Logo devemos criar o projeto java seguindo a estrutura plp.expressions1 etc etc !

Criando a estrutura para a linguagem exp1 Criar um projeto java comum Em seguida criar um pacote chamado plp e em seguida um chamado expressions1, submisso à plp Em seguida criar uma pasta/pacote parser dentro de expressions1 Selecione a pasta parser e repita o processo anterior de criar um projeto JavaCC

Criando a estrutura para a linguagem exp1 File-> New->Other, ir na opção javaCC-> JavaCC Template File

Criando a estrutura para a linguagem exp1

Criando a estrutura para a linguagem exp1 Vá até a pasta onde os arquivos foram gerados, pasta parser, apague todos e coloque na pasta apenas o arquivo da gramática Expressoes1.jj Você vai notar que o eclipse gera todos os arquivos novamente, de forma automática, só que agora tendo como referência a nova gramática.

Criando a estrutura para a linguagem exp1 Dois dos arquivos gerados, Exp1Parser e Exp1ParserTokenManager apresentarão erros de compilação. Isto porque estão faltando ainda algumas classes básicas como por exemplo Valor, ValorInteiro, etc, mencionadas no arquivo .jj por isso referenciadas pelo Exp1Parser.java gerado pelo JavaCC. Além desta a classe Programa também é referenciada.

Criando a estrutura para a linguagem exp1 Baixar da página da disciplina as classe listadas abaixo

Criando a estrutura para a linguagem exp1 Criar o pacote expression no mesmo nível do pacote parser e colocar as classes listadas anteriormente no pacote expression Ainda, classe Programa também é referenciada nas classes geradas. Baixar a mesma na página da disciplina e colocá-la no pacote expressions1 Ainda, as classes Tipo e TipoPrimitivo também são referenciadas. Baixá-las e colocá-las dentro do pacote util, a ser criado no mesmo nível do pacote parser e do pacote expression.

Referências WATT, D.; BROWN, D. Programming Language Processors in Java. Capítulo 4 Foco maior na abordagem LL Site do plugin JavaCC para eclipse: http://eclipse-javacc.sourceforge.net/ Tutorial JavaCC: http://www.engr.mun.ca/~theo/JavaCC-Tutorial Site do JavaCC: http://javacc.java.net/

Aula sobre JavaCC Parsing Tarciana Dias tds@cin.ufpe.br Abril 2013