como construir um compilador utilizando ferramentas...

35
Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação de Erros Sintáticos Prof. M ´ arcio Delamaro [email protected] Como construir um compilador utilizando ferramentas Java – p. 1/2

Upload: others

Post on 13-Aug-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Como construir um compilador utilizandoferramentas Java

Aula 8 – Recuperação de Erros Sintáticos

Prof. Marcio [email protected]

Como construir um compilador utilizando ferramentas Java – p. 1/22

Page 2: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

O que temos até agora

A.S. lê entrada.

Se entrada estiver de acordo com a gramática,execução termina OK.

Se existir algum erro sintático, uma execeção é lançada.

ParseException é tratada no método main.

Uma mensagem de erro é dada.

Como construir um compilador utilizando ferramentas Java – p. 2/22

Page 3: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Tratamento da exceçãotry {

parser.program();

}

catch (ParseException e)

{

System.err.println(e.getMessage());

parser.contParseError = 1;

}

finally {

System.out.println(parser.token_source.foundLexError() +

" Lexical Errors found");

System.out.println(parser.contParseError +

" Syntactic Errors found");

}

Como construir um compilador utilizando ferramentas Java – p. 3/22

Page 4: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

A saída é...X++ Compiler - Version 1.0 - 2004

Reading from file bintree-erro-sintatico.x . . .

Encountered "mes" at line 21, column 4.

Was expecting one of:

"[" ...

";" ...

"." ...

">" ...

"<" ...

"==" ...

"<=" ...

">=" ...

"!=" ...

0 Lexical Errors found

1 Syntactic Errors found

Como construir um compilador utilizando ferramentas Java – p. 4/22

Page 5: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Recuperação de errosEncountered "mes" at line 21, column 4.

Was expecting one of:

"[" ...

";" ...

"." ...

">" ...

"<" ...

"==" ...

"<=" ...

">=" ...

"!=" ...

Encountered "<" at line 27, column 14.

Was expecting one of:

<int_constant> ...

<string_constant> ...

"null" ...

<IDENT> ...

"(" ...

"+" ...

"-" ...

Como construir um compilador utilizando ferramentas Java – p. 5/22

Page 6: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Recuperação de errosEncountered "right" at line 43, column 14.

Was expecting one of:

"(" ...

"[" ...

"," ...

";" ...

Encountered "1" at line 69, column 14.

Was expecting one of:

"[" ...

"." ...

"=" ...

<IDENT> ...

0 Lexical Errors found

4 Syntactic Errors found

Como construir um compilador utilizando ferramentas Java – p. 6/22

Page 7: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Método de resincronização (do pânico)S → aAcd

A → gh

Como construir um compilador utilizando ferramentas Java – p. 7/22

Page 8: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Método de resincronização (do pânico)S → aAcd

A → gh

Analisar: agabcd

Como construir um compilador utilizando ferramentas Java – p. 7/22

Page 9: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Método de resincronização (do pânico)S → aAcd

A → gh

Analisar: agabcd

Método S não deve ser afetado por esse erro sintático.

Como construir um compilador utilizando ferramentas Java – p. 7/22

Page 10: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Método de resincronização (do pânico)S → aAcd

A → gh

Analisar: agabcd

Método S não deve ser afetado por esse erro sintático.

O método A deve ressincronizar a entrada com onão-terminal que se espera reconhecer (S).

Como construir um compilador utilizando ferramentas Java – p. 7/22

Page 11: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Método de resincronização (do pânico)S → aAcd

A → gh

Analisar: agabcd

Método S não deve ser afetado por esse erro sintático.

O método A deve ressincronizar a entrada com onão-terminal que se espera reconhecer (S).

Consumir tokens até que apareça algum que possibilitea continuidade da análise.

Como construir um compilador utilizando ferramentas Java – p. 7/22

Page 12: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Método de resincronização (do pânico)S → aAcd

A → gh

Analisar: agabcd

Método S não deve ser afetado por esse erro sintático.

O método A deve ressincronizar a entrada com onão-terminal que se espera reconhecer (S).

Consumir tokens até que apareça algum que possibilitea continuidade da análise.

Método A precisa saber até onde ler.

Como construir um compilador utilizando ferramentas Java – p. 7/22

Page 13: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Método de resincronização (do pânico)S → aAcd

A → gh

Analisar: agabcd

Método S não deve ser afetado por esse erro sintático.

O método A deve ressincronizar a entrada com onão-terminal que se espera reconhecer (S).

Consumir tokens até que apareça algum que possibilitea continuidade da análise.

Método A precisa saber até onde ler.

Usar FOLLOW de A.

Como construir um compilador utilizando ferramentas Java – p. 7/22

Page 14: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Um pouco melhor

S → aAcd | bAef

A → gh

Como construir um compilador utilizando ferramentas Java – p. 8/22

Page 15: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Um pouco melhor

S → aAcd | bAef

A → gh

FOLLOW(A) = {c, e}

Como construir um compilador utilizando ferramentas Java – p. 8/22

Page 16: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Um pouco melhor

S → aAcd | bAef

A → gh

FOLLOW(A) = {c, e}

Se estivermos utilizando a primeira produção de S,desejaremos utilizar o c para fazer a recuperação deerros, e não o e.

Como construir um compilador utilizando ferramentas Java – p. 8/22

Page 17: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Um pouco melhor

S → aAcd | bAef

A → gh

FOLLOW(A) = {c, e}

Se estivermos utilizando a primeira produção de S,desejaremos utilizar o c para fazer a recuperação deerros, e não o e.

Devemos permitir que a cada chamada de A sejainformado, por meio de um parâmetro, qual é o token desincronização a ser utilizado.

Como construir um compilador utilizando ferramentas Java – p. 8/22

Page 18: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

No JavaCC

Construções try/catch

Dessa forma, caso não haja um casamento esperado, ométodo pode fazer a ressincronização.

Um erro de sintaxe é sinalizado com um ParseException

Como construir um compilador utilizando ferramentas Java – p. 9/22

Page 19: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Tratamento de errovoid A(){}{

try {"g" "h"

}catch (ParseException e){

// tratamento de erro}

}

Como construir um compilador utilizando ferramentas Java – p. 10/22

Page 20: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Chamada a não-terminaisvoid A(){}{

try {"g" B() "h"

}catch (ParseException e){

// tratamento de erros de A ou de B}

}

Como construir um compilador utilizando ferramentas Java – p. 11/22

Page 21: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Chamada a não-terminais

Nesse último caso, o não-terminal B pode ou nãoimplementar o tratamento de erro.

Se tratar, o método A não muda.

Se não tratar, um erro pode ser propagado e tratado emA.

Para cada chamada de não-terminal que trata dos errosdeve ser passado um conjunto de ressincronização.

Como construir um compilador utilizando ferramentas Java – p. 12/22

Page 22: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Esquema geralvoid S(){

RecoverySet x = new RecoverySet(<c>),y = new RecoverySet(<e>);

}{

( <a> A(x) <c> <d> |<b> A(y) <e> <f>

)}

Como construir um compilador utilizando ferramentas Java – p. 13/22

Page 23: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Esquema geralvoid A(RecoverySet r){}{

try {<g> <h>

}catch (ParseException e){

consumeUntil(r, e, "A");}

}

Como construir um compilador utilizando ferramentas Java – p. 14/22

Page 24: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Método consumeUntil

Dá mensagem sobre recuperação de erros (ver main);

Como construir um compilador utilizando ferramentas Java – p. 15/22

Page 25: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Método consumeUntil

Dá mensagem sobre recuperação de erros (ver main);

Se conjunto de sincronização não null, vai consumindoos tokens da entrada até achar algum no conjunto.

Como construir um compilador utilizando ferramentas Java – p. 15/22

Page 26: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Método consumeUntil

Dá mensagem sobre recuperação de erros (ver main);

Se conjunto de sincronização não null, vai consumindoos tokens da entrada até achar algum no conjunto.

Se um <EOF> for achado, lança outro tipo de exceçãoParseEOFException

Como construir um compilador utilizando ferramentas Java – p. 15/22

Page 27: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Método consumeUntil

Dá mensagem sobre recuperação de erros (ver main);

Se conjunto de sincronização não null, vai consumindoos tokens da entrada até achar algum no conjunto.

Se um <EOF> for achado, lança outro tipo de exceçãoParseEOFException

Por isso, todos os métodos devem declarar esse tipo deexceção.

Como construir um compilador utilizando ferramentas Java – p. 15/22

Page 28: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Método consumeUntil

Dá mensagem sobre recuperação de erros (ver main);

Se conjunto de sincronização não null, vai consumindoos tokens da entrada até achar algum no conjunto.

Se um <EOF> for achado, lança outro tipo de exceçãoParseEOFException

Por isso, todos os métodos devem declarar esse tipo deexceção.

Incremnta número de erros encontrados.

Como construir um compilador utilizando ferramentas Java – p. 15/22

Page 29: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Do começovoid program()

throws ParseEOFException : {

RecoverySet g = new RecoverySet(EOF);

}

{

try {

[ classlist(g) ] <EOF>

}

catch (ParseException e) {

consumeUntil(g, e, "program");

}

}

Como construir um compilador utilizando ferramentas Java – p. 16/22

Page 30: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

RecoverySet

Implementa um conjunto de inteiros, com algumasoperações específicas

Construtor RecoverySet(int)

boolean contains(int)

RecoverySet union(RecoverySet)

RecoverySet add(in)

RecoverySet remove(in)

String toString()

Como construir um compilador utilizando ferramentas Java – p. 17/22

Page 31: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

classlistvoid classlist(RecoverySet g)

throws ParseEOFException : {

RecoverySet f = First.classlist.union(g);

}

{

classdecl(f) [ classlist(g) ]

}

Não há recuperação de erros.

Não há possibilidade de erros sintático.

Uso dos conjuntos da classe First

Como construir um compilador utilizando ferramentas Java – p. 18/22

Page 32: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

classbodyvoid classbody(RecoverySet g) throws ParseEOFException : {

RecoverySet f1 = new RecoverySet(RBRACE),

f2 = new RecoverySet(SEMICOLON),

f3 = First.methoddecl.union(f1),

f4 = First.constructdecl.union(f3),

f5 = First.vardecl.union(f4);

}

{

try {

<LBRACE>

[classlist(f5)]

(LOOKAHEAD(3) vardecl(f2) <SEMICOLON>)*(constructdecl(f4))*(methoddecl(f3))*

<RBRACE>

}

catch (ParseException e) {

consumeUntil(g, e, "classbody");

}

}

Como construir um compilador utilizando ferramentas Java – p. 19/22

Page 33: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Algumas exceçõesvoid lvalue(RecoverySet g) throws ParseEOFException :

{}

{

try {

<IDENT> (

<LBRACKET> expression(null) <RBRACKET> |

<DOT> <IDENT> [<LPAREN> arglist(null) <RPAREN>]

)*}

catch (ParseException e) {

consumeUntil(g, e, "lvalue");

}

}

É o ponto “mais baixo” onde se realiza

recuperação de erros.

a[i + * 3].x = 123;

Como construir um compilador utilizando ferramentas Java – p. 20/22

Page 34: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Expressionvoid expression(RecoverySet g)

throws ParseEOFException :

{}

{

try {

numexpr()

[(<LT>|<GT>|<LE>|<GE>|<EQ>|<NEQ>)

numexpr()]

}

catch (ParseException e) {

consumeUntil(g, e, "expression");

}

}

Como construir um compilador utilizando ferramentas Java – p. 21/22

Page 35: Como construir um compilador utilizando ferramentas Javadelamaro/SlidesCompiladores/Aula8-Cap5.pdf · Como construir um compilador utilizando ferramentas Java Aula 8 – Recuperação

Algumas melhorias

A forma de cálculo do conjunto de sincronização ébastante simples.

Esse conjunto é muito importante no sucesso darecuperação.

Nem sempre é eficiente.

Uma análise caso-a-caso pode melhorar a eficiência daestratégia.

Ver descrição no capítulo 5.

Como construir um compilador utilizando ferramentas Java – p. 22/22