Como construir um compilador utilizando ferramentas...
Transcript of Como construir um compilador utilizando ferramentas...
Como construir um compilador utilizandoferramentas Java
Aula 5 – Análise Léxica com JavaCC
Prof. Marcio [email protected]
Como construir um compilador utilizando ferramentas Java – p. 1/37
O que é o JavaCC
Ambiente ou ferramenta que permite a geração de umanalisador sintático completo
Como construir um compilador utilizando ferramentas Java – p. 2/37
O que é o JavaCC
Ambiente ou ferramenta que permite a geração de umanalisador sintático completo
A partir de uma descrição de alto nível gera código Java
Como construir um compilador utilizando ferramentas Java – p. 2/37
O que é o JavaCC
Ambiente ou ferramenta que permite a geração de umanalisador 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
Como construir um compilador utilizando ferramentas Java – p. 2/37
O que é o JavaCC
Ambiente ou ferramenta que permite a geração de umanalisador 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
Permite também a construção da árvore sintática
Como construir um compilador utilizando ferramentas Java – p. 2/37
Como funciona
langx.jj JavaCC
Como construir um compilador utilizando ferramentas Java – p. 3/37
Como funciona
langx.jj JavaCC
sort.x
sort.jas
Como construir um compilador utilizando ferramentas Java – p. 4/37
Como funciona
Como construir um compilador utilizando ferramentas Java – p. 5/37
Partes do arquivo jj
Opções
Declaração da classe principal
Declarações do AL
Declarações do AS
Como construir um compilador utilizando ferramentas Java – p. 6/37
Partes do arquivo jjoptions {
STATIC = false;
}
PARSER_BEGIN(Test)
public class Test {
}
PARSER_END(Test)
SKIP :
{
" "
}
JAVACODE void program()
{
}
Como construir um compilador utilizando ferramentas Java – p. 7/37
A classe principaltests2.jj
PARSER_BEGIN(Test)
public class Test {
static public void main(String args[]) {
System.out.printf("Hello world!");
}
}
PARSER_END(Test)
Como construir um compilador utilizando ferramentas Java – p. 8/37
A classe principal
Como construir um compilador utilizando ferramentas Java – p. 9/37
A classe principal: langx++.jjPARSER_BEGIN(langX)
package parser; / * declarac ao de pacote * /
import java.io. * ; / * imports necess arios * /
public class langX {
...
}
PARSER_END(langX)
Como construir um compilador utilizando ferramentas Java – p. 10/37
Variáveis da classe...
public class langX {
final static String Version = "X++ Compiler - Version 1.0 - 20 04";
boolean Menosshort = false; // sa ıda resumida = falso
...
}
Como construir um compilador utilizando ferramentas Java – p. 11/37
Método principal: variáveis locais...
public class langX {
// Define o m etodo "main" da classe langX.
public static void main(String args[]) throws ParseExcept ion
{
String filename = ""; // nome do arquivo a ser analisado
langX parser; // analisador l exico/sint atico
int i;
boolean ms = false;
System.out.println(Version);
...
}
Como construir um compilador utilizando ferramentas Java – p. 12/37
Método principal: ler argumentospublic class langX {
public static void main(String args[]) throws ParseExcept ion
{
...
// 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);
}
}
...
}
Como construir um compilador utilizando ferramentas Java – p. 13/37
Método principal: ler nome arquivopublic static void main(String args[]) throws ParseExcept ion
{
...
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;
}
}
...
}
Como construir um compilador utilizando ferramentas Java – p. 14/37
Criação do ASif (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;
}
}
Como construir um compilador utilizando ferramentas Java – p. 15/37
Execução e finalizaçãopublic static void main(String args[]) throws ParseExcept ion
{
...
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.foundLexErro r() +
" Lexical Errors found");
else
System.out.println("Program successfully analyzed.");
}
O AS “possui” um AL. O AL é definido pelo usuário
(algumas coisas).
Como construir um compilador utilizando ferramentas Java – p. 16/37
Classe principal: outros métodospublic class langX {
public static void main(String args[]) throws ParseExcept ion
{
...
}
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;
}
Como construir um compilador utilizando ferramentas Java – p. 17/37
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;
descrição dos itens léxicos;
Como construir um compilador utilizando ferramentas Java – p. 18/37
Código Java
TOKEN_MGR_DECLS :{int countLexError = 0;
public int foundLexError(){
return countLexError;}
}
Como construir um compilador utilizando ferramentas Java – p. 19/37
SKIPTodas as definições nesta seção utilizam a representaçãode expressões regulares. A palavra SKIP indica ao JavaCCque desejamos definir quais são as cadeias que devem serignoradas.SKIP :
{
" "
| "\t"
| "\n"
| "\r"
| "\f"
}
Como construir um compilador utilizando ferramentas Java – p. 20/37
TOKEN: palavras reservadasTOKEN é utilizada para definir, por meio de expressõesregulares, quais as cadeias a serem reconhecidas e quaisos 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" >
}
Como construir um compilador utilizando ferramentas Java – p. 21/37
Conflitos
AL é construído de modo que a maior cadeia possível sejareconhecida. Por isso não há nenhum problema quanto auma Expressão Regular poder gerar subcadeias de outraExpressão Regular. Sempre será considerada a maiorcadeia da entrada que casar com alguma expressãoregular. Isso acontece, por exemplo, a seguir com os tokensGT e GE. Se a entrada possuir um string >=, este seráidentificado como um GE, mas se possuir um > apenas,então GT será o casamento realizado.
Como construir um compilador utilizando ferramentas Java – p. 22/37
TOKEN: operadoresTOKEN :
{
< ASSIGN: "=" >
| < GT: ">" >
| < LT: "<" >
| < EQ: "==" >
| < LE: "<=" >
| < GE: ">=" >
| < NEQ: "!=" >
| < PLUS: "+" >
| < MINUS: "-" >
| < STAR: " * " >
| < SLASH: "/" >
| < REM: "%" >
}
Como construir um compilador utilizando ferramentas Java – p. 23/37
TOKEN: outros símbolosTOKEN :
{
< LPAREN: "(" >
| < RPAREN: ")" >
| < LBRACE: "{" >
| < RBRACE: "}" >
| < LBRACKET: "[" >
| < RBRACKET: "]" >
| < SEMICOLON: ";" >
| < COMMA: "," >
| < DOT: "." >
}
Como construir um compilador utilizando ferramentas Java – p. 24/37
TOKEN: constantes inteirasTOKEN :
{ // 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"])
) >
}
Como construir um compilador utilizando ferramentas Java – p. 25/37
Constantes inteiras123afhoje
Como construir um compilador utilizando ferramentas Java – p. 26/37
Constantes inteiras123afhoje
constante inteira 123afh seguida de um identificador oje;
Como construir um compilador utilizando ferramentas Java – p. 26/37
Constantes inteiras123afhoje
constante inteira 123afh seguida de um identificador oje;
0baCh
Como construir um compilador utilizando ferramentas Java – p. 26/37
Constantes inteiras123afhoje
constante inteira 123afh seguida de um identificador oje;
0baCh
também é uma constante hexadecimal;
Como construir um compilador utilizando ferramentas Java – p. 26/37
Constantes inteiras123afhoje
constante inteira 123afh seguida de um identificador oje;
0baCh
também é uma constante hexadecimal;
7620OO
Como construir um compilador utilizando ferramentas Java – p. 26/37
Constantes inteiras123afhoje
constante inteira 123afh seguida de um identificador oje;
0baCh
também é uma constante hexadecimal;
7620OO
é uma constante octal seguida por um identificador O;
Como construir um compilador utilizando ferramentas Java – p. 26/37
Constantes inteiras123afhoje
constante inteira 123afh seguida de um identificador oje;
0baCh
também é uma constante hexadecimal;
7620OO
é uma constante octal seguida por um identificador O;
1011tb10b
Como construir um compilador utilizando ferramentas Java – p. 26/37
Constantes inteiras123afhoje
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 identificadortb10b.
Como construir um compilador utilizando ferramentas Java – p. 26/37
String constante
Inicia com aspas
Seqüência de quaisquer caracteres (quaisquer ???).
Termina com aspas
Como definir ?
Como construir um compilador utilizando ferramentas Java – p. 27/37
TOKEN: constantes string, nullTOKEN :
{ // constante string como "abcd bcda"
< string_constant:
"\""( ˜["\"","\n","\r"]) * "\"" >
|
< null_constant: "null" > // constante null
}
Como construir um compilador utilizando ferramentas Java – p. 28/37
TOKEN: identificadoresOs identificadores são definido como sendo iniciados poruma 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.
Como construir um compilador utilizando ferramentas Java – p. 29/37
Conflitos II
for
Como construir um compilador utilizando ferramentas Java – p. 30/37
Conflitos II
for
class
Como construir um compilador utilizando ferramentas Java – p. 30/37
Conflitos II
for
class
Definir prioridade
Como construir um compilador utilizando ferramentas Java – p. 30/37
Conflitos II
for
class
Definir prioridade
A definição que aparecer primeiro tem maior prioridade
Como construir um compilador utilizando ferramentas Java – p. 30/37
O que o AL produz: Tokenint kind; Contém o tipo do token reconhecido. Cadaum dos tokens descritos no arquivo .jj como IF ouIDENT é definido na classe langXConstants comosendo uma constante inteira. Assim, supondo quelangXConstants.IDENT foi definido com o valor 9,então ao reconhecer um identificador, o AL irá produzirum 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 seinicia e onde termina o token reconhecido;
Como construir um compilador utilizando ferramentas Java – p. 31/37
O que o AL produz: TokenString image; É a cadeia que foi lida e reconhecidacomo token. Por exemplo, se a cadeia func10 foi lida naentrada e reconhecida como um IDENT, então essavariável contém a cadeia lida, ou seja, func10;
Token next; Uma referência para o próximo tokenreconhecido após ele. Se o AL ainda não leu nenhumoutro token ou se esse é o último token da entrada,então seu valor é null ;
Token specialToken; É um apontador para o últimotoken especial reconhecido antes deste. Veja maisadiante os comentários sobre o que são os tokensespeciais.
Como construir um compilador utilizando ferramentas Java – p. 32/37
Comentários
Comentário não é um item léxico;
Como construir um compilador utilizando ferramentas Java – p. 33/37
Comentários
Comentário não é um item léxico;
Pode aparecer em qualquer ponto do programa;
Como construir um compilador utilizando ferramentas Java – p. 33/37
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;
Como construir um compilador utilizando ferramentas Java – p. 33/37
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;
Como construir um compilador utilizando ferramentas Java – p. 33/37
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.
Como construir um compilador utilizando ferramentas Java – p. 33/37
Comentários
Comentários multilinha /* ... */
Linha única // ....
AL simplesmente ignora
Usamos conceito de estado, característica do JavaCC
Como construir um compilador utilizando ferramentas Java – p. 34/37
Definição de comentáriosSKIP : {
"/*": multilinecomment}
Como construir um compilador utilizando ferramentas Java – p. 35/37
Definição de comentáriosSKIP : {
"/*": multilinecomment}
<multilinecomment> SKIP:{
"*/": DEFAULT| < []>}
Como construir um compilador utilizando ferramentas Java – p. 35/37
Definição de comentáriosSKIP : {
"/*": 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.
Como construir um compilador utilizando ferramentas Java – p. 35/37
Erro léxico
Ao aparecer um item léxico não válido.
Como construir um compilador utilizando ferramentas Java – p. 36/37
Erro léxico
Ao aparecer um item léxico não válido.
AL gerado pelo JavaCC lança um “TokenMgrError ”
Como construir um compilador utilizando ferramentas Java – p. 36/37
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.
Como construir um compilador utilizando ferramentas Java – p. 36/37
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
Como construir um compilador utilizando ferramentas Java – p. 36/37
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
Como construir um compilador utilizando ferramentas Java – p. 36/37
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 sertratado.
Como construir um compilador utilizando ferramentas Java – p. 36/37
Exercícios
Estudar no livro a implementação do comentário delinha única.
Estudar no livro a implementação da recuperação deerro léxico.
Baixar o arquivo do Capítulo 3. Gerar o “compilador” eexecutar com os programas exemplos que vocêdesenvolveu (sort, bintree, etc).
Como construir um compilador utilizando ferramentas Java – p. 37/37