Como construir um compilador utilizando ferramentas Java p. 1/3 Como construir um compilador utilizando ferramentas Java Aula 5 Análise Léxica com JavaCC Prof. Márcio Delamaro delamaro@icmc.usp.br
Como construir um compilador utilizando ferramentas Java p. 2/3 O que é o JavaCC Ambiente ou ferramenta que permite a geração de um analisador sintático completo
Como construir um compilador utilizando ferramentas Java p. 2/3 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
Como construir um compilador utilizando ferramentas Java p. 2/3 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
Como construir um compilador utilizando ferramentas Java p. 2/3 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 Permite também a construção da árvore sintática
Como construir um compilador utilizando ferramentas Java p. 3/3 Como funciona langx.jj JavaCC
Como construir um compilador utilizando ferramentas Java p. 4/3 Como funciona sort.x langx.jj JavaCC sort.jas
Como funciona Como construir um compilador utilizando ferramentas Java p. 5/3
Como construir um compilador utilizando ferramentas Java p. 6/3 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. 7/3 Partes do arquivo jj options { STATIC = false; PARSER_BEGIN(Test) public class Test { PARSER_END(Test) SKIP : { " " JAVACODE void program() {
Como construir um compilador utilizando ferramentas Java p. 8/3 A classe principal tests2.jj PARSER_BEGIN(Test) public class Test { static public void main(string args[]) { System.out.printf("Hello world!"); PARSER_END(Test)
A classe principal Como construir um compilador utilizando ferramentas Java p. 9/3
Como construir um compilador utilizando ferramentas Java p. 10/3 A classe principal: langx++.jj PARSER_BEGIN(langX) package parser; /* declaração de pacote */ import java.io.*; /* imports necessários */ public class langx {... PARSER_END(langX)
Como construir um compilador utilizando ferramentas Java p. 11/3 Variáveis da classe... public class langx { final static String Version = "X++ Compiler - Version 1.0-2004"; boolean Menosshort = false; // saída resumida = falso...
Como construir um compilador utilizando ferramentas Java p. 12/3 Método principal: variáveis locais... public class langx { // Define o método "main" da classe langx. public static void main(string args[]) throws ParseException { String filename = ""; // nome do arquivo a ser analisado langx parser; // analisador léxico/sintático int i; boolean ms = false; System.out.println(Version);...
Como construir um compilador utilizando ferramentas Java p. 13/3 Método principal: ler argumentos public class langx { public static void main(string args[]) throws ParseException {... // lê os parâmetros 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. 14/3 Método principal: ler nome arquivo public static void main(string args[]) throws ParseException {... if (args[i].equals("-")) { // lê da entrada padrão System.out.println("Reading from standard input..."); parser = new langx(system.in); else { // lê 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/3 Criação do AS if (args[i].equals("-")) { // lê da entrada padrão System.out.println("Reading from standard input..."); parser = new langx(system.in); else { // lê 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. 16/3 Execução e finalização public static void main(string args[]) throws ParseException {... parser.menosshort = ms; parser.program(); // chama o método que faz a análise // verifica se houve erro léxico 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).
Como construir um compilador utilizando ferramentas Java p. 17/3 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;
Como construir um compilador utilizando ferramentas Java p. 18/3 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. 19/3 Código Java TOKEN_MGR_DECLS : { int countlexerror = 0; public int foundlexerror() { return countlexerror;
Como construir um compilador utilizando ferramentas Java p. 20/3 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"
Como construir um compilador utilizando ferramentas Java p. 21/3 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" >
Como construir um compilador utilizando ferramentas Java p. 22/3 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, então GT será o casamento realizado.
Como construir um compilador utilizando ferramentas Java p. 23/3 TOKEN: operadores TOKEN : { < ASSIGN: "=" > < GT: ">" > < LT: "<" > < EQ: "==" > < LE: "<=" > < GE: ">=" > < NEQ: "!=" > < PLUS: "+" > < MINUS: "-" > < STAR: "*" > < SLASH: "/" > < REM: "%" >
Como construir um compilador utilizando ferramentas Java p. 24/3 TOKEN: outros símbolos TOKEN : { < LPAREN: "(" > < RPAREN: ")" > < LBRACE: "{" > < RBRACE: "" > < LBRACKET: "[" > < RBRACKET: "]" > < SEMICOLON: ";" > < COMMA: "," > < DOT: "." >
Como construir um compilador utilizando ferramentas Java p. 25/3 TOKEN: constantes inteiras TOKEN : { // números decimais, octais, hexadecimais ou binários < 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. 26/3 Constantes inteiras 123afhoje
Como construir um compilador utilizando ferramentas Java p. 26/3 Constantes inteiras 123afhoje constante inteira 123afh seguida de um identificador oje;
Como construir um compilador utilizando ferramentas Java p. 26/3 Constantes inteiras 123afhoje constante inteira 123afh seguida de um identificador oje; 0baCh
Como construir um compilador utilizando ferramentas Java p. 26/3 Constantes inteiras 123afhoje constante inteira 123afh seguida de um identificador oje; 0baCh também é uma constante hexadecimal;
Como construir um compilador utilizando ferramentas Java p. 26/3 Constantes inteiras 123afhoje constante inteira 123afh seguida de um identificador oje; 0baCh também é uma constante hexadecimal; 7620OO
Como construir um compilador utilizando ferramentas Java p. 26/3 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;
Como construir um compilador utilizando ferramentas Java p. 26/3 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
Como construir um compilador utilizando ferramentas Java p. 26/3 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 tb10b.
Como construir um compilador utilizando ferramentas Java p. 27/3 String constante Inicia com aspas Seqüência de quaisquer caracteres (quaisquer???). Termina com aspas Como definir?
Como construir um compilador utilizando ferramentas Java p. 28/3 TOKEN: constantes string, null TOKEN : { // constante string como "abcd bcda" < string_constant: "\""( ["\"","\n","\r"])* "\"" > < null_constant: "null" > // constante null
Como construir um compilador utilizando ferramentas Java p. 29/3 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.
Como construir um compilador utilizando ferramentas Java p. 30/3 Conflitos II for
Como construir um compilador utilizando ferramentas Java p. 30/3 Conflitos II for class
Como construir um compilador utilizando ferramentas Java p. 30/3 Conflitos II for class Definir prioridade
Como construir um compilador utilizando ferramentas Java p. 30/3 Conflitos II for class Definir prioridade A definição que aparecer primeiro tem maior prioridade
Como construir um compilador utilizando ferramentas Java p. 31/3 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;
Como construir um compilador utilizando ferramentas Java p. 32/3 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.
Como construir um compilador utilizando ferramentas Java p. 33/3 Comentários Comentário não é um item léxico;
Como construir um compilador utilizando ferramentas Java p. 33/3 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/3 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/3 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/3 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. 34/3 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. 35/3 Definição de comentários SKIP : { "/*": multilinecomment
Como construir um compilador utilizando ferramentas Java p. 35/3 Definição de comentários SKIP : { "/*": multilinecomment <multilinecomment> SKIP: { "*/": DEFAULT < []>
Como construir um compilador utilizando ferramentas Java p. 35/3 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.
Como construir um compilador utilizando ferramentas Java p. 36/3 Erro léxico Ao aparecer um item léxico não válido.
Como construir um compilador utilizando ferramentas Java p. 36/3 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/3 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/3 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/3 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/3 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.
Como construir um compilador utilizando ferramentas Java p. 37/3 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ê desenvolveu (sort, bintree, etc).