• Nenhum resultado encontrado

Como construir um compilador utilizando ferramentas Java

N/A
N/A
Protected

Academic year: 2021

Share "Como construir um compilador utilizando ferramentas Java"

Copied!
61
0
0

Texto

(1)

Como construir um compilador utilizando

ferramentas Java

Aula 5 – Análise Léxica com JavaCC

Prof. M ´arcio Delamaro

(2)

O que é o JavaCC

Ambiente ou ferramenta que permite a geração de um analisador sintático completo

(3)

O que é o JavaCC

Ambiente ou ferramenta que permite a geração de um analisador sintático completo

(4)

O que é o JavaCC

Ambiente ou ferramenta que permite a geração de um analisador sintático completo

A partir de uma descrição de alto nível gera código Java Dentro de um só arquivo permite definir AL e AS

(5)

O que é o JavaCC

Ambiente ou ferramenta que permite a geração de um analisador sintático completo

A partir de uma descrição de alto nível gera código Java Dentro de um só arquivo permite definir AL e AS

(6)

Como funciona

(7)

Como funciona

langx.jj JavaCC sort.x

(8)
(9)

Partes do arquivo jj

Opções

Declaração da classe principal

Declarações do AL

(10)

Partes do arquivo jj

options {

STATIC = false; }

PARSER_BEGIN(Test)

public class Test { } PARSER_END(Test) SKIP : { " " }

JAVACODE void program() {

(11)

A classe principal

tests2.jj

PARSER_BEGIN(Test)

public class Test {

static public void main(String args[]) { System.out.printf("Hello world!"); }

}

(12)
(13)

A classe principal: langx++.jj

PARSER_BEGIN(langX)

package parser; /* declarac¸˜ao de pacote */ import java.io.*; /* imports necess´arios */

public class langX { ...

}

(14)

Variáveis da classe

...

public class langX {

final static String Version = "X++ Compiler - Version 1.0 - 2004"; boolean Menosshort = false; // sa´ıda resumida = falso

... }

(15)

Método principal: variáveis locais

...

public class langX {

// Define o m´etodo "main" da classe langX.

public static void main(String args[]) throws ParseException {

String filename = ""; // nome do arquivo a ser analisado langX parser; // analisador l´exico/sint´atico

int i;

boolean ms = false;

System.out.println(Version); ...

(16)

Método principal: ler argumentos

public class langX {

public static void main(String args[]) throws ParseException {

...

// lˆe os parˆametros passados para o compilador for (i = 0; i < args.length - 1; i++)

{

if ( args[i].toLowerCase().equals("-short") ) ms = true;

else {

System.out.println("Usage is: java langX [-short] " + "inputfile");

System.exit(0); }

}

(17)

Método principal: ler nome arquivo

public static void main(String args[]) throws ParseException {

...

if (args[i].equals("-")) { // lˆe da entrada padr˜ao

System.out.println("Reading from standard input . . ."); parser = new langX(System.in);

}

else { // lˆe do arquivo

filename = args[args.length-1];

System.out.println("Reading from file " + filename + " . . ."); try {

parser = new langX(new java.io.FileInputStream(filename)); }

catch (java.io.FileNotFoundException e) {

System.out.println("File " + filename + " not found."); return;

} }

... }

(18)

Criação do AS

if (args[i].equals("-")) { // lˆe da entrada padr˜ao

System.out.println("Reading from standard input . . ."); parser = new langX(System.in);

}

else { // lˆe do arquivo

filename = args[args.length-1];

System.out.println("Reading from file " + filename + " . . ."); try {

parser = new langX(new java.io.FileInputStream(filename)); }

catch (java.io.FileNotFoundException e) {

System.out.println("File " + filename + " not found."); return;

} }

(19)

Execução e finalização

public static void main(String args[]) throws ParseException {

...

parser.Menosshort = ms;

parser.program(); // chama o m´etodo que faz a an´alise // verifica se houve erro l´exico

if ( parser.token_source.foundLexError() != 0 )

System.out.println(parser.token_source.foundLexError() + " Lexical Errors found");

else

System.out.println("Program successfully analyzed."); }

O AS “possui” um AL. O AL é definido pelo usuário

(algumas coisas).

(20)

Classe principal: outros métodos

public class langX {

public static void main(String args[]) throws ParseException {

... }

static public String im(int x) { int k; String s; s = tokenImage[x]; k = s.lastIndexOf("\""); try {s = s.substring(1,k);} catch (StringIndexOutOfBoundsException e) {} return s; }

(21)

Descrição do AL

A descrição do analisador léxico é dividida em duas partes: código Java a ser inserido na classe do AL;

(22)

Código Java

TOKEN_MGR_DECLS : {

int countLexError = 0;

public int foundLexError() {

return countLexError; }

(23)

SKIP

Todas as definições nesta seção utilizam a representação de expressões regulares. A palavra SKIP indica ao JavaCC que desejamos definir quais são as cadeias que devem ser ignoradas. SKIP : { " " | "\t" | "\n" | "\r" | "\f" }

(24)

TOKEN: palavras reservadas

TOKEN é utilizada para definir, por meio de expressões

regulares, quais as cadeias a serem reconhecidas e quais os tipos de tokens que a elas correspondem.

TOKEN : { < BREAK: "break" > | < CLASS: "class" > | < CONSTRUCTOR: "constructor" > | < ELSE: "else" > | < EXTENDS: "extends" > | < FOR: "for" > ... | < PRINT: "print" > | < READ: "read" > | < RETURN: "return" > | < STRING: "string" > | < SUPER: "super" >

(25)

Conflitos

AL é construído de modo que a maior cadeia possível seja reconhecida. Por isso não há nenhum problema quanto a uma Expressão Regular poder gerar subcadeias de outra Expressão Regular. Sempre será considerada a maior

cadeia da entrada que casar com alguma expressão

regular. Isso acontece, por exemplo, a seguir com os tokens

GT e GE. Se a entrada possuir um string >=, este será

identificado como um GE, mas se possuir um > apenas,

(26)

TOKEN: operadores

TOKEN : { < ASSIGN: "=" > | < GT: ">" > | < LT: "<" > | < EQ: "==" > | < LE: "<=" > | < GE: ">=" > | < NEQ: "!=" > | < PLUS: "+" > | < MINUS: "-" > | < STAR: "*" > | < SLASH: "/" > | < REM: "%" > }

(27)

TOKEN: outros símbolos

TOKEN : { < LPAREN: "(" > | < RPAREN: ")" > | < LBRACE: "{" > | < RBRACE: "}" > | < LBRACKET: "[" > | < RBRACKET: "]" > | < SEMICOLON: ";" > | < COMMA: "," > | < DOT: "." > }

(28)

TOKEN: constantes inteiras

TOKEN :

{ // n´umeros decimais, octais, hexadecimais ou bin´arios < int_constant:( (["0"-"9"] (["0"-"9"])* ) | (["0"-"7"] (["0"-"7"])* ["o", "O"] ) | (["0"-"9"] (["0"-"7","A"-"F","a"-"f"])* ["h", "H"] ) | (["0"-"1"] (["0"-"1"])* ["b", "B"]) ) > }

(29)

Constantes inteiras

(30)

Constantes inteiras

123afhoje

(31)

Constantes inteiras

123afhoje

constante inteira 123afh seguida de um identificador oje;

(32)

Constantes inteiras

123afhoje

constante inteira 123afh seguida de um identificador oje;

0baCh

(33)

Constantes inteiras

123afhoje

constante inteira 123afh seguida de um identificador oje;

0baCh

também é uma constante hexadecimal;

(34)

Constantes inteiras

123afhoje

constante inteira 123afh seguida de um identificador oje;

0baCh

também é uma constante hexadecimal;

7620OO

(35)

Constantes inteiras

123afhoje

constante inteira 123afh seguida de um identificador oje;

0baCh

também é uma constante hexadecimal;

7620OO

é uma constante octal seguida por um identificador O;

(36)

Constantes inteiras

123afhoje

constante inteira 123afh seguida de um identificador oje;

0baCh

também é uma constante hexadecimal;

7620OO

é uma constante octal seguida por um identificador O;

1011tb10b

constante decimal 1011 seguida pelo identificador

(37)

String constante

Inicia com aspas

Seqüência de quaisquer caracteres (quaisquer ???). Termina com aspas

(38)

TOKEN: constantes string, null

TOKEN :

{ // constante string como "abcd bcda" < string_constant:

"\""( ˜["\"","\n","\r"])* "\"" > |

< null_constant: "null" > // constante null }

(39)

TOKEN: identificadores

Os identificadores são definido como sendo iniciados por uma letra, seguida por letras ou dígitos.

TOKEN : {

< IDENT: <LETTER> (<LETTER>|<DIGIT>)* > |

< #LETTER:["A"-"Z","a"-"z"] > |

< #DIGIT:["0"-"9"] > }

Foram utilizados dois tokens

#LETTER

e

#DIGIT

para

definir

IDENT

. Esses tokens não são utilizados na

gramática da linguagem

X

++

, mas servem como

auxiliares na definição do próprio AL.

(40)

Conflitos II

for

(41)

Conflitos II

for

(42)

Conflitos II

for

class

(43)

Conflitos II

for

class

Definir prioridade

(44)

O que o AL produz: Token

int kind; Contém o tipo do token reconhecido. Cada

um dos tokens descritos no arquivo .jj como IF ou

IDENT é definido na classe langXConstants como

sendo uma constante inteira. Assim, supondo que

langXConstants.IDENT foi definido com o valor 9,

então ao reconhecer um identificador, o AL irá produzir um objeto Token cuja variável kind tem o valor 9;

int beginLine, beginColumn, endLine,

endColumn; Essas variáveis indicam, respectivamente,

a linha e a coluna dentro do arquivo de entrada, onde se inicia e onde termina o token reconhecido;

(45)

O que o AL produz: Token

String image; É a cadeia que foi lida e reconhecida

como token. Por exemplo, se a cadeia func10 foi lida na entrada e reconhecida como um IDENT, então essa

variável contém a cadeia lida, ou seja, func10;

Token next; Uma referência para o próximo token

reconhecido após ele. Se o AL ainda não leu nenhum outro token ou se esse é o último token da entrada, então seu valor é null;

Token specialToken; É um apontador para o último

token especial reconhecido antes deste. Veja mais adiante os comentários sobre o que são os tokens especiais.

(46)

Comentários

(47)

Comentários

Comentário não é um item léxico;

(48)

Comentários

Comentário não é um item léxico;

Pode aparecer em qualquer ponto do programa;

(49)

Comentários

Comentário não é um item léxico;

Pode aparecer em qualquer ponto do programa;

a = b.myMethod(10, /* comentário */ c) + 2;

(50)

Comentários

Comentário não é um item léxico;

Pode aparecer em qualquer ponto do programa;

a = b.myMethod(10, /* comentário */ c) + 2;

Deve ser tratado pelo AL; Por exemplo, ignorar.

(51)

Comentários

Comentários multilinha /* ... */ Linha única // ....

AL simplesmente ignora

(52)

Definição de comentários

SKIP : {

"/*": multilinecomment }

(53)

Definição de comentários

SKIP : { "/*": multilinecomment } <multilinecomment> SKIP: { "*/": DEFAULT | <˜[]> }

(54)

Definição de comentários

SKIP : { "/*": multilinecomment } <multilinecomment> SKIP: { "*/": DEFAULT | <˜[]> }

Vale a regra de que sempre a maior cadeia possível é

utilizada no casamento. Como o segundo padrão tem

apenas um caractere, então ao aparecer a cadeia */, o

casamento é sempre feito no primeiro padrão.

(55)

Erro léxico

(56)

Erro léxico

Ao aparecer um item léxico não válido.

(57)

Erro léxico

Ao aparecer um item léxico não válido.

AL gerado pelo JavaCC lança um “TokenMgrError ” Isso faz com que a execução do AS termine.

(58)

Erro léxico

Ao aparecer um item léxico não válido.

AL gerado pelo JavaCC lança um “TokenMgrError ” Isso faz com que a execução do AS termine.

(59)

Erro léxico

Ao aparecer um item léxico não válido.

AL gerado pelo JavaCC lança um “TokenMgrError ” Isso faz com que a execução do AS termine.

Gostaríamos de ignorar e continuar a análise

(60)

Erro léxico

Ao aparecer um item léxico não válido.

AL gerado pelo JavaCC lança um “TokenMgrError ” Isso faz com que a execução do AS termine.

Gostaríamos de ignorar e continuar a análise

Para isso devemos evitar que o AL identifique o erro

Ou seja, qualquer outro símbolo que aparecer, deve ser tratado.

(61)

Exercícios

Estudar no livro a implementação do comentário de linha única.

Estudar no livro a implementação da recuperação de erro léxico.

Baixar o arquivo do Capítulo 3. Gerar o “compilador” e executar com os programas exemplos que você

Referências

Documentos relacionados

Desse modo, ao observar a história dos deslocamentos dos povos indígenas na região, como por exemplo no caso palikur tal como observado por López (2011), temos que sua

The results of those assays evidenced the importance of a larger diameter of the pilot hole compared to the inner diameter of the screw for reducing insertion torque and

De seguida, vamos adaptar a nossa demonstrac¸ ˜ao da f ´ormula de M ¨untz, partindo de outras transformadas aritm ´eticas diferentes da transformada de M ¨obius, para dedu-

Note on the occurrence of the crebeater seal, Lobodon carcinophagus (Hombron &amp; Jacquinot, 1842) (Mammalia: Pinnipedia), in Rio de Janeiro State, Brazil.. On May 12, 2003,

Entre elas estão os discursos orais, o entretenimento, as petições, os slogans, as imagens, as caricaturas, a produção editorial, a imprensa, a cinematografia, a dramaturgia,

O sistema de aquisição de grandezas analógicas - SAGA, tem como objetivo obter, armazenar históricos, criticar, tratar, gerar curvas de previsão e tendência de

Para obter mais informações sobre como ativar os perfis do Device Link utilizando as Configurações de cor para especialistas no driver da impressora Integrated Fiery Color

a) Todas as candidaturas preenchidas, juntamente com a documentação complementar, serão enviadas para os Serviços Financeiros dos Pacientes (PFS) - Departamento de Assistência