JLex e JCup Mayerber Carvalho Neto. JLex: A lexical analyzer generator for Java™ Gerador de...

27
JLex e JCup JLex e JCup Mayerber Carvalho Neto Mayerber Carvalho Neto

Transcript of JLex e JCup Mayerber Carvalho Neto. JLex: A lexical analyzer generator for Java™ Gerador de...

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

JLex e JCupJLex e JCup

Mayerber Carvalho NetoMayerber Carvalho Neto

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

JLex: JLex: A lexical analyzer A lexical analyzer generator for Java™generator for Java™ Gerador de analisadores léxicos Gerador de analisadores léxicos

(scanners)(scanners)

Baseado no ‘lex’ do UNIXBaseado no ‘lex’ do UNIX

Por que usar uma ferramenta do Por que usar uma ferramenta do tipo JLex?tipo JLex?

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

JLex: Arquivo de JLex: Arquivo de EspecificaçãoEspecificação O arquivo de especificação (.lex) O arquivo de especificação (.lex)

é dividido em três seções:é dividido em três seções:– Código do usuárioCódigo do usuário– DiretivasDiretivas– Regras de Expressões RegularesRegras de Expressões Regulares

Cada seção é separada da seção Cada seção é separada da seção seguinte por uma linha contendo seguinte por uma linha contendo apenas ‘%%’apenas ‘%%’

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

JLex: código do usuárioJLex: código do usuário

O código escrito nessa seção é O código escrito nessa seção é copiado diretamente no topo do copiado diretamente no topo do arquivo do scanner.arquivo do scanner.

Útil para declarar “imports”, Útil para declarar “imports”, classes e métodos auxiliares.classes e métodos auxiliares.

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

JLex: diretivasJLex: diretivas

Nessa seção são declarados macros e Nessa seção são declarados macros e nomes de estados.nomes de estados.

Diretivas disponíveis:Diretivas disponíveis:– %{...%}%{...%}

Permite que sejam declaradas variáveis e Permite que sejam declaradas variáveis e métodos do scanner.métodos do scanner.

Por exemplo, você pode declarar uma variável Por exemplo, você pode declarar uma variável ‘‘int num_de_comentariosint num_de_comentarios’.’.

Evitar nomes de variáveis e métodos que Evitar nomes de variáveis e métodos que comecem com ‘yy’ para não dar conflito com as comecem com ‘yy’ para não dar conflito com as variáveis internas do scanner.variáveis internas do scanner.

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

JLex: diretivas (cont.)JLex: diretivas (cont.)

– %init{...%init}%init{...%init} Tudo que você escrever entre as chaves vai ser Tudo que você escrever entre as chaves vai ser

copiado diretamente para o método construtor da copiado diretamente para o método construtor da classe do scanner.classe do scanner.

– %eof{...%eof}%eof{...%eof} Permite declarar código que vai ser executado Permite declarar código que vai ser executado

quando o scanner encontrar o fim do arquivo de quando o scanner encontrar o fim do arquivo de entrada.entrada.

– %char%char Ativa o contador de caracteres através da variável Ativa o contador de caracteres através da variável

inteira inteira yychar yychar (útil para mensagens de erro)(útil para mensagens de erro)..– %line%line

Ativa o contador de linhas através da variável Ativa o contador de linhas através da variável inteira inteira yyline yyline (útil para mensagens de erro)(útil para mensagens de erro)..

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

JLex: diretivas (cont.)JLex: diretivas (cont.)

– %cup%cup Ativa a compatibilidade com o JCup. Isso significa Ativa a compatibilidade com o JCup. Isso significa

que a classe gerada do scanner vai implementar a que a classe gerada do scanner vai implementar a interface interface java_cup.runtime.Scannerjava_cup.runtime.Scanner

– %class <nome>%class <nome> Muda o nome da classe do scanner (default = Muda o nome da classe do scanner (default =

Yylex).Yylex).

– %function <nome>%function <nome> Muda o nome do método de “tokenização” (default Muda o nome do método de “tokenização” (default

= yylex).= yylex).

– %type <nome_do_tipo>%type <nome_do_tipo> Muda o tipo retornado pelo método de Muda o tipo retornado pelo método de

“tokenização” (default = Yytoken).“tokenização” (default = Yytoken).

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

JLex: diretivas (cont.)JLex: diretivas (cont.)

– %notunix%notunix Se você for usar o JLex no Windows, utilize essa Se você for usar o JLex no Windows, utilize essa

diretiva para que o scanner gerado trate a diretiva para que o scanner gerado trate a seqüência “\r\n” como “\n”.seqüência “\r\n” como “\n”.

– %eofval{...%eofval}%eofval{...%eofval} O código escrito entre as chaves deve retornar O código escrito entre as chaves deve retornar

um valor cujo tipo é o mesmo que aquele um valor cujo tipo é o mesmo que aquele retornado pelo método de “tokenização”. Esse retornado pelo método de “tokenização”. Esse valor vai ser retornado sempre que o método de valor vai ser retornado sempre que o método de “tokenização” for chamado e o scanner tenha “tokenização” for chamado e o scanner tenha encontrado EOF.encontrado EOF.

Há mais diretivas no manual do JLex.Há mais diretivas no manual do JLex.

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

JLex: diretivas (cont.)JLex: diretivas (cont.)

MacrosMacros– Cada macro deve estar contida Cada macro deve estar contida

numa única linha.numa única linha.– Formato:Formato:

<nome> = <definição><nome> = <definição>

– O nome da macro deve começar O nome da macro deve começar com uma letra ou ‘_’.com uma letra ou ‘_’.

– A definição da macro é uma A definição da macro é uma expressão regular.expressão regular.

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

JLex: diretivas (cont.)JLex: diretivas (cont.)

Macros podem conter outras Macros podem conter outras macros.macros.

Exemplos:Exemplos:– DIGITO = [0-9]DIGITO = [0-9]– ALFA = [A-Za-z]ALFA = [A-Za-z]– ESPACO_EM_BRANCO = [\n\r\x20\t]ESPACO_EM_BRANCO = [\n\r\x20\t]– NUM_NATURAL = {DIGITO}+NUM_NATURAL = {DIGITO}+

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

JLex: diretivas (cont.)JLex: diretivas (cont.)

EstadosEstados– Permite implementar uma máquina Permite implementar uma máquina

de estados no scanner.de estados no scanner.– Todo scanner tem pelo menos um Todo scanner tem pelo menos um

estado (declarado internamente) estado (declarado internamente) chamado YYINITIAL.chamado YYINITIAL.

– Exemplo:Exemplo: %state COMMENT%state COMMENT

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

JLex: regras de JLex: regras de expressões regularesexpressões regulares Formato das regras:Formato das regras:

– [<estados>] <expressão> { <ação> }[<estados>] <expressão> { <ação> }

[<estados>] – opcional. Formato:[<estados>] – opcional. Formato:– <estado0, estado1, ..., estadoN><estado0, estado1, ..., estadoN>– Se uma regra for precedida por uma lista de Se uma regra for precedida por uma lista de

estados, o scanner só tentará aplicar a regra se ele estados, o scanner só tentará aplicar a regra se ele estiver em um dos estados listados.estiver em um dos estados listados.

– Se uma lista de estados não for especificada para Se uma lista de estados não for especificada para uma regra, o scanner sempre tentará aplicar a uma regra, o scanner sempre tentará aplicar a regra independentemente do seu estado atual.regra independentemente do seu estado atual.

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

JLex: regras de JLex: regras de expressões regulares expressões regulares (cont.)(cont.) <expressão> – obrigatório.<expressão> – obrigatório.

– baseado em expressões regulares.baseado em expressões regulares.– Símbolos especiais:Símbolos especiais:

| - representa uma opção. Exemplo: | - representa uma opção. Exemplo: ee||ff significa que significa que a expressão pode casar com a expressão pode casar com ee ou ou ff..

. (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 * - fecho de Kleene. Casa com zero ou mais

repetições da expressão regular precedente.repetições da expressão regular precedente.Exemplo: [a-z]* casa com {Exemplo: [a-z]* casa com {εε, a, aa, ab, ...}, a, aa, ab, ...}

+ - casa com uma ou mais repetições da expressão + - casa com uma ou mais repetições da expressão regular precedente.regular precedente.Exemplo: [0-9]+ casa com qualquer número Exemplo: [0-9]+ casa com qualquer número natural.natural.

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

JLex: regras de JLex: regras de expressões regulares expressões regulares (cont.)(cont.)

– Símbolos especiais (cont.):Símbolos especiais (cont.): ? – casa com zero ou uma ocorrência da ? – casa com zero ou uma ocorrência da

expressão regular precedente.expressão regular precedente.

Exemplo: [+-]?[0-9]+ casa com números Exemplo: [+-]?[0-9]+ casa com números naturais precedidos ou não por um sinal de naturais precedidos ou não por um sinal de ‘-’ ou ‘+’ ‘-’ ou ‘+’ {0, 1, -1, +1, -123, +456, ...} {0, 1, -1, +1, -123, +456, ...}

(...) – os parênteses são usados para (...) – os parênteses são usados para agrupar expressões regulares.agrupar expressões regulares.

Exemplo: (ab)* Exemplo: (ab)* { {εε, ab, abab, , ab, abab, ababac, ...} enquanto que ab* ababac, ...} enquanto que ab* {a, ab, {a, ab, abb, abbb, ...}abb, abbb, ...}

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

JLex: regras de JLex: regras de expressões regulares expressões regulares (cont.)(cont.)

– Símbolos especiais (cont.):Símbolos especiais (cont.): [...] – usado para denotar uma classe de [...] – usado para denotar uma classe de

caracteres.caracteres.– Exemplo: [a-z] casa com qualquer letra de Exemplo: [a-z] casa com qualquer letra de

‘a’ até ‘z’.‘a’ até ‘z’.– Se o símbolo seguinte ao ‘[‘ for o circunflexo Se o símbolo seguinte ao ‘[‘ for o circunflexo

(^), o conteúdo do [...] é negado.(^), o conteúdo do [...] é negado.– Exemplo: [^0-9] casa com tudo exceto Exemplo: [^0-9] casa com tudo exceto

dígitos.dígitos.

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

JLex: regras de JLex: regras de expressões regulares expressões regulares (cont.)(cont.) Expressões podem conter macros Expressões podem conter macros

desde que essas sejam escritas desde que essas sejam escritas entre chaves.entre chaves.– Exemplos:Exemplos:

{DIGITO}+ representa uma expressão {DIGITO}+ representa uma expressão que casa com os números naturais.que casa com os números naturais.

{ALFA}({ALFA}|{DIGITO}|_)* é a {ALFA}({ALFA}|{DIGITO}|_)* é a expressão que casa com nomes de expressão que casa com nomes de variáveis na maioria das linguagens de variáveis na maioria das linguagens de programação.programação.

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

JLex: regras de JLex: regras de expressões regulares expressões regulares (cont.)(cont.) <ação> - obrigatório.<ação> - obrigatório.

– Uma ação é o trecho de código que deve ser Uma ação é o trecho de código que deve ser executado quando uma regra for aplicada executado quando uma regra for aplicada pelo scanner. Esse trecho de código deve pelo scanner. Esse trecho de código deve retornar um valor equivalente àquele retornar um valor equivalente àquele retornado pelo método de “tokenização”.retornado pelo método de “tokenização”.

– É possível trocar o estado do scanner dentro É possível trocar o estado do scanner dentro de uma ação através de chamada ao de uma ação através de chamada ao método interno yybegin(nome_do_estado).método interno yybegin(nome_do_estado).

– Você pode fazer uso das variáveis Você pode fazer uso das variáveis yytextyytext (String), (String), yycharyychar (int) e (int) e yylineyyline (int) dentro do (int) dentro do código de suas ações.código de suas ações.

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

JLex: regras de JLex: regras de expressões regulares expressões regulares (cont.)(cont.) Observações:Observações:

– Se mais de uma regra casar com a string de Se mais de uma regra casar com a string de entrada, o scanner escolhe a regra que casa com a entrada, o scanner escolhe a regra que casa com a maior substring da string. Exemplo:maior substring da string. Exemplo:

String: abcdString: 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 Todas as seqüências de caracteres passadas como entrada para o scanner devem casar com alguma entrada para o scanner devem casar com alguma das regras. Caso isso não ocorra, o scanner vai das regras. Caso isso não ocorra, o scanner vai gerar um erro.gerar um erro.

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

JCup: JCup: CConstructor of onstructor of UUseful seful PParsersarsers Gerador de analisadores Gerador de analisadores

sintáticos (parsers)sintáticos (parsers)

Baseado no ‘yacc’ do UNIXBaseado no ‘yacc’ do UNIX

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

JCup: arquivo de JCup: arquivo de especificação (.cup)especificação (.cup) Dividido em quatro seções:Dividido em quatro seções:

– Seção 1: declaração de “packages” e Seção 1: declaração de “packages” e “imports” que serão inseridos no topo do “imports” que serão inseridos no topo do arquivo gerado pelo JCup (similar à primeira arquivo gerado pelo JCup (similar à primeira seção do arq. de especificação do JLex) e seção do arq. de especificação do JLex) e diretivas do JCup.diretivas do JCup.

– Seção 2: declaração de terminais e não-Seção 2: declaração de terminais e não-terminais.terminais.

– Seção 3: precedência e associatividade de Seção 3: precedência e associatividade de terminais.terminais.

– Seção 4: gramática.Seção 4: gramática.

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

JCup: primeira seçãoJCup: primeira seção

Especificação de “packages” e “imports”. Exemplo:Especificação de “packages” e “imports”. Exemplo:package compilador.parser;package compilador.parser;import compilador.scanner;import compilador.scanner;

DiretivasDiretivas– parser code {: ... :};parser code {: ... :};

Permite que você declare variáveis e métodos na classe do Permite que você declare variáveis e métodos na classe do parser. Similar à diretiva %{...%} do JLex.parser. Similar à diretiva %{...%} do JLex.

– init with {: ... :};init with {: ... :}; O código entre chaves vai ser executado antes que o parser O código entre chaves vai ser executado antes que o parser

peça o primeiro token ao scanner. Bom lugar para inicializar peça o primeiro token ao scanner. Bom lugar para inicializar o scanner.o scanner.

– scan with {: ... :};scan with {: ... :}; Serve para que você escreva o código que o parser vai Serve para que você escreva o código que o parser vai

executar sempre que ele quiser pedir um token ao scanner. executar sempre que ele quiser pedir um token ao scanner. Se essa diretiva não for utilizada, o parser chama Se essa diretiva não for utilizada, o parser chama scanner.next_token() para receber tokens.scanner.next_token() para receber tokens.

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

JCup: segunda seçãoJCup: segunda seção

Lista de símbolosLista de símbolos

– terminal [classe] nome0, nome1, ...;terminal [classe] nome0, nome1, ...;– non terminal [classe] nome0, nome1, ...;non terminal [classe] nome0, nome1, ...;

Em tempo de execução, os símbolos são representados por objetos Em tempo de execução, os símbolos são representados por objetos da classe da classe java_cup.runtime.Symboljava_cup.runtime.Symbol. Essa classe possui uma variável . Essa classe possui uma variável chamada “value” que contém o valor do símbolo. Exemplo:chamada “value” que contém o valor do símbolo. Exemplo:– terminal Integer NUMERO;terminal Integer NUMERO;– quando o parserquando o parser recebe do scanner um NUMERO, ele cria um objeto da recebe do scanner um NUMERO, ele cria um objeto da

classe Symbol. A variável “value” será um objeto da classe Integer. classe Symbol. A variável “value” será um objeto da classe Integer. Assim, o valor do número pode ser obtido através de Assim, o valor do número pode ser obtido através de simbolo.value.intValue();simbolo.value.intValue();

Se não for fornecida uma classe na declaração do (non) terminal, a Se não for fornecida uma classe na declaração do (non) terminal, a variável “value” ficará com valor variável “value” ficará com valor null.null.

Os nomes dos (non) terminais não podem ser palavras reservadas Os nomes dos (non) terminais não podem ser palavras reservadas do JCup: do JCup: "code", "action", "parser", "terminal", "non", "nonterminal", "code", "action", "parser", "terminal", "non", "nonterminal", "init", "scan", "with", "start", "precedence", "left", "right", "init", "scan", "with", "start", "precedence", "left", "right", "nonassoc", "import", e "package""nonassoc", "import", e "package"

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

JCup: terceira seçãoJCup: terceira seção

Precedência e AssociatividadePrecedência e Associatividade– precedence left precedence left terminalterminal[, [, terminalterminal...];...];– precedence right precedence right terminalterminal[, [, terminalterminal...];...];– precedence nonassoc precedence nonassoc terminalterminal[, [, terminalterminal...];...];

A precedência cresce de cima para baixo, por A precedência cresce de cima para baixo, por exemplo:exemplo:– precedence left ADD, SUBTRACT;precedence left ADD, SUBTRACT;– precedence left TIMES, DIVIDE;precedence left TIMES, DIVIDE;

significa que a multiplicação e a divisão têm significa que a multiplicação e a divisão têm maior precedência.maior precedência.

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

JCup: quarta seçãoJCup: quarta seção

GramáticaGramáticaespecifica as produções da gramática da especifica as produções da gramática da linguagem.linguagem.

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

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

JCup: quarta seção JCup: quarta seção (cont.)(cont.) As produções têm o formato:As produções têm o formato:

não-terminal ::= <símbolos e não-terminal ::= <símbolos e ações>ações>

Os símbolos à direita de “::=“ podem Os símbolos à direita de “::=“ podem ser terminais ou não-terminais.ser terminais ou não-terminais.

As ações correspondem ao código As ações correspondem ao código que é executado quando a regra de que é executado quando a regra de produção é aplicada.produção é aplicada.

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

JCup: quarta seção JCup: quarta seção (cont.)(cont.) Exemplo:Exemplo:

expr ::= NUMBER:nexpr ::= NUMBER:n {:{:

RESULT=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 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 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 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 produção deve ser armazenado na variável implícita “RESULT”. O tipo de “RESULT” é o mesmo que foi declarado na seção 2.tipo de “RESULT” é o mesmo que foi declarado na seção 2.

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

Links, Manuais e Links, Manuais e ExemplosExemplos JLexJLex

– http://www.cs.princeton.edu/~appel/modern/java/http://www.cs.princeton.edu/~appel/modern/java/JLex/JLex/

JCupJCup– http://www.cs.princeton.edu/~appel/modern/java/http://www.cs.princeton.edu/~appel/modern/java/

CUP/CUP/