A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

JLex e JCup Mayerber Carvalho Neto. JLex: A lexical analyzer generator for Java™ Gerador de analisadores léxicos (scanners) Gerador de analisadores léxicos.

Apresentações semelhantes


Apresentação em tema: "JLex e JCup Mayerber Carvalho Neto. JLex: A lexical analyzer generator for Java™ Gerador de analisadores léxicos (scanners) Gerador de analisadores léxicos."— Transcrição da apresentação:

1 JLex e JCup Mayerber Carvalho Neto

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

3 JLex: Arquivo de Especificação O arquivo de especificação (.lex) é dividido em três seções: 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 ‘%’ Cada seção é separada da seção seguinte por uma linha contendo apenas ‘%’

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

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

6 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. 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. 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). 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). Ativa o contador de linhas através da variável inteira yyline (útil para mensagens de erro).

7 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 Ativa a compatibilidade com o JCup. Isso significa que a classe gerada do scanner vai implementar a interface java_cup.runtime.Scanner –%class –%class Muda o nome da classe do scanner (default = Yylex). Muda o nome da classe do scanner (default = Yylex). –%function –%function Muda o nome do método de “tokenização” (default = yylex). Muda o nome do método de “tokenização” (default = yylex). –%type –%type Muda o tipo retornado pelo método de “tokenização” (default = Yytoken). Muda o tipo retornado pelo método de “tokenização” (default = Yytoken).

8 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”. 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. 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. Há mais diretivas no manual do JLex.

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

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

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

12 JLex: regras de expressões regulares Formato das regras: Formato das regras: –[ ] { } [ ] – opcional. Formato: [ ] – opcional. Formato: – – –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.

13 JLex: regras de expressões regulares (cont.) – obrigatório. – 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. | - 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’.. (ponto) – casa com qualquer caráter, exceto o ‘\n’. * - fecho de Kleene. Casa com zero ou mais repetições da expressão regular precedente. * - 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. + - casa com uma ou mais repetições da expressão regular precedente. Exemplo: [0-9]+ casa com qualquer número natural.

14 JLex: regras de expressões regulares (cont.) –Símbolos especiais (cont.): ? – casa com zero ou uma ocorrência da expressão regular precedente. ? – 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. (...) – os parênteses são usados para agrupar expressões regulares. Exemplo: (ab)*  {ε, ab, abab, ababac,...} enquanto que ab*  {a, ab, abb, abbb,...}

15 JLex: regras de expressões regulares (cont.) –Símbolos especiais (cont.): [...] – usado para denotar uma classe de caracteres. [...] – 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.

16 JLex: regras de expressões regulares (cont.) Expressões podem conter macros desde que essas sejam escritas entre chaves. 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. {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. {ALFA}({ALFA}|{DIGITO}|_)* é a expressão que casa com nomes de variáveis na maioria das linguagens de programação.

17 JLex: regras de expressões regulares (cont.) - obrigatório. - 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.

18 JLex: regras de expressões regulares (cont.) Observações: 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 String: abcd Regra 1: “ab” { acao1(); } Regra 1: “ab” { acao1(); } Regra 2: [a-z]+ { acao2(); } Regra 2: [a-z]+ { acao2(); } O scanner vai escolher a regra 2. 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.

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

20 JCup: arquivo de especificação (.cup) Dividido em quatro seções: 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.

21 JCup: primeira seção Especificação de “packages” e “imports”. Exemplo: Especificação de “packages” e “imports”. Exemplo: package compilador.parser; import compilador.scanner; Diretivas Diretivas –parser code {:... :}; Permite que você declare variáveis e métodos na classe do parser. Similar à diretiva %{...%} do JLex. 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. 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. 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.

22 JCup: segunda seção Lista de símbolos 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: 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. 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" 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"

23 JCup: terceira seção Precedência e Associatividade 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: 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.

24 JCup: quarta seção Gramática Gramática especifica as produções da gramática da linguagem. start with non-terminal; (diretiva opcional) 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.

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

26 JCup: quarta seção (cont.) Exemplo: Exemplo: expr ::= NUMBER:n {: {:RESULT=n; :} :} | expr:r PLUS expr:s | expr:r PLUS expr:s {: {: RESULT=new Integer(r.intValue() + s.intValue()); 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. 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.

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


Carregar ppt "JLex e JCup Mayerber Carvalho Neto. JLex: A lexical analyzer generator for Java™ Gerador de analisadores léxicos (scanners) Gerador de analisadores léxicos."

Apresentações semelhantes


Anúncios Google