Mayerber Carvalho Neto

Slides:



Advertisements
Apresentações semelhantes
Software Básico Silvio Fernandes
Advertisements

Tópicos em Compiladores
Capítulo II – Algoritmos e Programas
Compiladores Claudio Benossi
II – Análise léxica DEI lex: linguagem de especificação para analisadores léxicos Implementação de simuladores de autómatos finitos Bibliografia aconselhada:
III – Análise sintáctica Geradores de parsers Bibliografia aconselhada: –Aho, Sethi e Ullman – secção 4.9 LFA 1999/ Jorge Morais.
Compiladores I Cristiano Damiani Vasconcellos
Deyvisson, Rafael M.P., Renato, Robson C.F., Rodolfo
Análise Léxica (Parte 2)
Software Básico Silvio Fernandes
JavaCC e JJTree Geração de compiladores implementados em Java
YACC.
Lex e Yacc.
Universidade Federal do Espírito Santo Programação II Professora: Norminda Luiza.
Análise Léxica Supondo o trecho de programa abaixo:
Construção de Compiladores
Construção de Compiladores
5.6 – Complementos de Yacc – Usando Yacc com gramáticas ambíguas
Tecnologia para Web JavaScript
Prof. Msc. Raul Paradeda Aula 3 Fundamentos
Classes e objetos P. O. O. Prof. Grace.
Introdução a Programação JAVA
JAVA: Conceitos Iniciais
Ameliara Freire O comando de entrada de dados é utilizado quando desejamos fornecer um valor para um nosso programa. Os dispositivos.
Ferramentas para a Construção de Compiladores: Lex & Yacc
Compiladores, Aula Nº 5 João M. P. Cardoso
Prof. Daniel Aula 03.  Criar Projeto  Criar Pacote  Criando classes  Meu primeiro programa  Compilar  Comentários  Variáveis.
Análise Léxica Primeira fase de um compilador
Classes, Objetos, Atributos e Métodos JAVA
Algoritmo e Programação
Técnicas de Desenvolvimento de Programas
Análise Léxica.
Capítulo II Gramáticas e Linguagens
Analise sintática aula-07-analise-sintática.pdf.
Faculdade Talentos Humanos - FACTHUS - Algoritmo I - Rogério Rodrigues
Analisador Léxico Prof. Alexandre Monteiro
Linguagem de Programação C#
Compiladores Análise Léxica
Programação I Aula 3 (Entrada de Dados) Prof. Gilberto Irajá Müller Última atualização 11/3/2009.
Aula 12 1 Análise Sintáctica Compiladores, Aula Nº 12 João M. P. Cardoso.
Análise Léxica Prof. Alexandre Monteiro
Linguagem de Programação JAVA
CES-41 COMPILADORES Aulas Práticas Capítulo II A Ferramenta Yacc.
Analisador Léxico.
JAVA Sintaxe.
Aula Prática 1 Monitoria IP/CC (~if669) (A partir do slide elaborado por Luís Gabriel)
CES-41 COMPILADORES Aulas Práticas
Faculdade Pernambucana - FAPE Setembro/2007
COMPILADORES 04 Prof. Marcos.
Fundamentos de linguagens de programação
Linguagem C.
Geradores de analisadores léxicos
CES-10 INTRODUÇÃO À COMPUTAÇÃO
JavaCC.
Programação Computacional Aula 8: Entrada e Saída pelo Console Prof a. Madeleine Medrano
Sintaxe de uma Linguagem
PLP – JavaCC Java Compiler Compiler
Shell Script Parte 2.
Analisador sintático: Tipos de análises sintáticas
Paradigmas das Linguagens de Programação - História
Compilador Software que traduz o texto (linguagem fonte) que representa um programa para código máquina(linguagem alvo) capaz de ser executado pelo.
Array e ArrayList LPOO – 01/09/14.
Faculdade Pernambuca - FAPE Compiladores Abril/2007 Compiladores Abril/2007.
Informática Teórica Engenharia da Computação. Teoria da Computação Contexto do que vamos começar a estudar As linguagens também podem ser definidas formalmente.
COMPILADORES 03 Prof. Marcos.
Java Como Programar, 8/E Deitel/Deitel, 8e. Java – Como programar Copyright © 2010 Pearson Education Slide 1.
SOCKET - É um canal de comunicação entre processos que estabelece uma conexão entre eles na forma de cliente-servidor. Por meio de sockets, os computadores.
Java Básico Lab Ruddá Beltrão | Cristian Costa.
Laboratório de Computação Aula 06 e 07 – Implementação de classes Prof. Fábio Dias
FUNÇÕES Dilvan Moreira (baseado em material de Z. Liang)
Transcrição da apresentação:

Mayerber Carvalho Neto JLex e JCup Mayerber Carvalho Neto

JLex: A lexical analyzer generator for Java™ Gerador de analisadores léxicos (scanners) Baseado no ‘lex’ do UNIX Por que usar uma ferramenta do tipo JLex?

JLex: Arquivo de Especificação O arquivo de especificação (.lex) é dividido em três seções: Código do usuário Diretivas Regras de Expressões Regulares Cada seção é separada da seção seguinte por uma linha contendo apenas ‘%%’

JLex: código do usuário O código escrito nessa seção é copiado diretamente no topo do arquivo do scanner. Útil para declarar “imports”, classes e métodos auxiliares.

JLex: diretivas Nessa seção são declarados macros e nomes de estados. Diretivas disponíveis: %{...%} Permite que sejam declaradas variáveis e métodos do scanner. Por exemplo, você pode declarar uma variável ‘int num_de_comentarios’. Evitar nomes de variáveis e métodos que comecem com ‘yy’ para não dar conflito com as variáveis internas do scanner.

JLex: diretivas (cont.) %init{...%init} Tudo que você escrever entre as chaves vai ser copiado diretamente para o método construtor da classe do scanner. %eof{...%eof} Permite declarar código que vai ser executado quando o scanner encontrar o fim do arquivo de entrada. %char Ativa o contador de caracteres através da variável inteira yychar (útil para mensagens de erro). %line Ativa o contador de linhas através da variável inteira yyline (útil para mensagens de erro).

JLex: diretivas (cont.) %cup Ativa a compatibilidade com o JCup. Isso significa que a classe gerada do scanner vai implementar a interface java_cup.runtime.Scanner %class <nome> Muda o nome da classe do scanner (default = Yylex). %function <nome> Muda o nome do método de “tokenização” (default = yylex). %type <nome_do_tipo> Muda o tipo retornado pelo método de “tokenização” (default = Yytoken).

JLex: diretivas (cont.) %notunix Se você for usar o JLex no Windows, utilize essa diretiva para que o scanner gerado trate a seqüência “\r\n” como “\n”. %eofval{...%eofval} O código escrito entre as chaves deve retornar um valor cujo tipo é o mesmo que aquele retornado pelo método de “tokenização”. Esse valor vai ser retornado sempre que o método de “tokenização” for chamado e o scanner tenha encontrado EOF. Há mais diretivas no manual do JLex.

JLex: diretivas (cont.) Macros Cada macro deve estar contida numa única linha. Formato: <nome> = <definição> O nome da macro deve começar com uma letra ou ‘_’. A definição da macro é uma expressão regular.

JLex: diretivas (cont.) Macros podem conter outras macros. Exemplos: DIGITO = [0-9] ALFA = [A-Za-z] ESPACO_EM_BRANCO = [\n\r\x20\t] NUM_NATURAL = {DIGITO}+

JLex: diretivas (cont.) Estados Permite implementar uma máquina de estados no scanner. Todo scanner tem pelo menos um estado (declarado internamente) chamado YYINITIAL. Exemplo: %state COMMENT

JLex: regras de expressões regulares Formato das regras: [<estados>] <expressão> { <ação> } [<estados>] – opcional. Formato: <estado0, estado1, ..., estadoN> Se uma regra for precedida por uma lista de estados, o scanner só tentará aplicar a regra se ele estiver em um dos estados listados. Se uma lista de estados não for especificada para uma regra, o scanner sempre tentará aplicar a regra independentemente do seu estado atual.

JLex: regras de expressões regulares (cont.) <expressão> – obrigatório. baseado em expressões regulares. Símbolos especiais: | - representa uma opção. Exemplo: e|f significa que a expressão pode casar com e ou f. . (ponto) – casa com qualquer caráter, exceto o ‘\n’. * - fecho de Kleene. Casa com zero ou mais repetições da expressão regular precedente. Exemplo: [a-z]* casa com {ε, a, aa, ab, ...} + - casa com uma ou mais repetições da expressão regular precedente. Exemplo: [0-9]+ casa com qualquer número natural.

JLex: regras de expressões regulares (cont.) Símbolos especiais (cont.): ? – casa com zero ou uma ocorrência da expressão regular precedente. Exemplo: [+-]?[0-9]+ casa com números naturais precedidos ou não por um sinal de ‘-’ ou ‘+’  {0, 1, -1, +1, -123, +456, ...} (...) – os parênteses são usados para agrupar expressões regulares. Exemplo: (ab)*  {ε, ab, abab, ababac, ...} enquanto que ab*  {a, ab, abb, abbb, ...}

JLex: regras de expressões regulares (cont.) Símbolos especiais (cont.): [...] – usado para denotar uma classe de caracteres. Exemplo: [a-z] casa com qualquer letra de ‘a’ até ‘z’. Se o símbolo seguinte ao ‘[‘ for o circunflexo (^), o conteúdo do [...] é negado. Exemplo: [^0-9] casa com tudo exceto dígitos.

JLex: regras de expressões regulares (cont.) Expressões podem conter macros desde que essas sejam escritas entre chaves. Exemplos: {DIGITO}+ representa uma expressão que casa com os números naturais. {ALFA}({ALFA}|{DIGITO}|_)* é a expressão que casa com nomes de variáveis na maioria das linguagens de programação.

JLex: regras de expressões regulares (cont.) <ação> - obrigatório. Uma ação é o trecho de código que deve ser executado quando uma regra for aplicada pelo scanner. Esse trecho de código deve retornar um valor equivalente àquele retornado pelo método de “tokenização”. É possível trocar o estado do scanner dentro de uma ação através de chamada ao método interno yybegin(nome_do_estado). Você pode fazer uso das variáveis yytext (String), yychar (int) e yyline (int) dentro do código de suas ações.

JLex: regras de expressões regulares (cont.) Observações: Se mais de uma regra casar com a string de entrada, o scanner escolhe a regra que casa com a maior substring da string. Exemplo: String: abcd Regra 1: “ab” { acao1(); } Regra 2: [a-z]+ { acao2(); } O scanner vai escolher a regra 2. Todas as seqüências de caracteres passadas como entrada para o scanner devem casar com alguma das regras. Caso isso não ocorra, o scanner vai gerar um erro.

JCup: Constructor of Useful Parsers Gerador de analisadores sintáticos (parsers) Baseado no ‘yacc’ do UNIX

JCup: arquivo de especificação (.cup) Dividido em quatro seções: Seção 1: declaração de “packages” e “imports” que serão inseridos no topo do arquivo gerado pelo JCup (similar à primeira seção do arq. de especificação do JLex) e diretivas do JCup. Seção 2: declaração de terminais e não-terminais. Seção 3: precedência e associatividade de terminais. Seção 4: gramática.

JCup: primeira seção Especificação de “packages” e “imports”. Exemplo: package compilador.parser; import compilador.scanner; Diretivas parser code {: ... :}; Permite que você declare variáveis e métodos na classe do parser. Similar à diretiva %{...%} do JLex. init with {: ... :}; O código entre chaves vai ser executado antes que o parser peça o primeiro token ao scanner. Bom lugar para inicializar o scanner. scan with {: ... :}; Serve para que você escreva o código que o parser vai executar sempre que ele quiser pedir um token ao scanner. Se essa diretiva não for utilizada, o parser chama scanner.next_token() para receber tokens.

JCup: segunda seção Lista de símbolos terminal [classe] nome0, nome1, ...; non terminal [classe] nome0, nome1, ...; Em tempo de execução, os símbolos são representados por objetos da classe java_cup.runtime.Symbol. Essa classe possui uma variável chamada “value” que contém o valor do símbolo. Exemplo: terminal Integer NUMERO; quando o parser recebe do scanner um NUMERO, ele cria um objeto da classe Symbol. A variável “value” será um objeto da classe Integer. Assim, o valor do número pode ser obtido através de simbolo.value.intValue(); Se não for fornecida uma classe na declaração do (non) terminal, a variável “value” ficará com valor null. Os nomes dos (non) terminais não podem ser palavras reservadas do JCup: "code", "action", "parser", "terminal", "non", "nonterminal", "init", "scan", "with", "start", "precedence", "left", "right", "nonassoc", "import", e "package"

JCup: terceira seção Precedência e Associatividade precedence left terminal[, terminal...]; precedence right terminal[, terminal...]; precedence nonassoc terminal[, terminal...]; A precedência cresce de cima para baixo, por exemplo: precedence left ADD, SUBTRACT; precedence left TIMES, DIVIDE; significa que a multiplicação e a divisão têm maior precedência.

JCup: quarta seção Gramática especifica as produções da gramática da linguagem. start with non-terminal; (diretiva opcional) indica qual é o não-terminal inicial da gramática. Se essa diretiva for omitida, o parser assume o primeiro não-terminal declarado nas produções da gramática.

JCup: quarta seção (cont.) As produções têm o formato: não-terminal ::= <símbolos e ações> Os símbolos à direita de “::=“ podem ser terminais ou não-terminais. As ações correspondem ao código que é executado quando a regra de produção é aplicada.

JCup: quarta seção (cont.) Exemplo: expr ::= NUMBER:n {: RESULT=n; :} | expr:r PLUS expr:s RESULT=new Integer(r.intValue() + s.intValue()); Observe que pode-se especificar várias produções para um mesmo não terminal através do uso da barra “|”. Pode-se nomear símbolos para poder referenciá-los no código da ação. O resultado da produção deve ser armazenado na variável implícita “RESULT”. O tipo de “RESULT” é o mesmo que foi declarado na seção 2.

Links, Manuais e Exemplos JLex http://www.cs.princeton.edu/~appel/modern/java/JLex/ JCup http://www.cs.princeton.edu/~appel/modern/java/CUP/