ANTLR - Problema na definição de gramática  XML
Índice dos Fóruns » Java Avançado
Autor Mensagem
schranko
JavaTeenager
[Avatar]

Membro desde: 05/09/2010 17:58:40
Mensagens: 156
Localização: Moscow, Russia
Offline

Pessoal,

Escrevi a gramática abaixo (é a minha primeira, deve estar uma porcaria e ainda não terminei todos as regras!). Mas por agora o problema que estou tendo é que ela está aceitando expressões como AGL(L1)1+2AGL(L2), quando deveria dar erro pois AGL(L1)1 não deveria ser válido... bom, não sei como resolver. Se puder dar uma olhada e me indicar uma solução, algum material, etc, ficaria muito grato!

grammar expressaoMC;

// Expressao

expression : term ( ( PLUS | MINUS ) term ) * ;

// Termos

term : factor ( ( MULT | DIV ) factor ) * ;

// Fatores

factor : NUMBER | function ;

// Funcoes

function : functionPM
| functionNum
| functionLog ;

functionPM :
( 'ACB'
| 'ACL'
| 'AGB'
)
( LPAREN pm RPAREN
) ;

functionNum :
( 'MAX'
| 'MIN'
)
( LPAREN expression SEMI expression RPAREN
) ;

functionLog : 'SE' LPAREN expression SEMI expression SEMI expression RPAREN;

// Tipos (parametros para funcoes)

pm :
( 'L'
| 'B'
) NUMBER ;

NUMBER : ( '0' .. '9' ) + ;

// Operadores matematicos

PLUS : '+' ;

MINUS : '-' ;

MULT : '*' ;

DIV : '/' ;

LPAREN : '(' ;

RPAREN : ')' ;

// Operadores relacionais

EQUALS : '=' ;

GT : '>' ;

GET : '>=' ;

LT : '<' ;

LET : '<=' ;

// Operadores logicos

AND : 'E' ;

OR : 'OU' ;

// Operador de subexpressao

SUB : '!' ;

// Espaco em branco

WS :
( '\t'
| ' '
| '\r'
| '\n'
| '\u000C'
) + { $channel = HIDDEN; } ;

// SEPARADORES

SEMI : ';' ;

"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." (Brian W. Kernighan)
[WWW]
abaldove
Debugger

Membro desde: 03/09/2008 08:59:31
Mensagens: 64
Localização: Guarulhos
Offline

Boa noite schranko, tudo bem?

Bom eu não dei uma olhada na definição da sua gramatica pois estou sem tempo, mas queria comentar sobre a parte do material, existe um livro chamado

Como Construir um Compilador Utilizando Ferramentas Java

http://novatec.com.br/livros/compilador/

Que descreve a criação de uma linguagem chamada x++ utilizando ferramentas java como javacc http://javacc.java.net/ para geração de um parser (ele parece um pouco com o sablecc http://sablecc.org/ se eu me lembro bem), e o jasmin http://jasmin.sourceforge.net/ que converte um formato intermediario para bytecode da jvm.

O livro é bem didatico, não sei se é um requisito para você usar ANTLR mas pelo menos vale a pena dar uma olhada nele pois ele apresenta conceitos interessantes correlatos a compiladores.

Como você disse que essa é sua primeira gramatica vale a pena você começar por alguma coisa mais simples como uma gramatica para aceitar expressões matematicas simples só com numeros mesmo e ir melhorando aos poucos. Só um detalhe esse livro é um pouco antigo por isso deve ser um pouco dificil de achar mas da uma pesquisada.

Existe tambem esse outro livro:

Livro Compiladores - Princípios, Técnicas e Ferramentas

Bom mas você tambem pode talvez usar (se você puder) alguma linguagem funcional como Haskell que são muito boas para essas coisas, aqui no forum tem post falando sobre isso.

Mais uma coisa http://cameraweb.ccuec.unicamp.br/group/mo403

Espero ter te ajudado de alguma forma, se eu tiver tempo tento dar uma olhada na sua gramatica.

Boa Sorte

schranko
JavaTeenager
[Avatar]

Membro desde: 05/09/2010 17:58:40
Mensagens: 156
Localização: Moscow, Russia
Offline

abaldove, obrigado. EU ate conheco um pouco sobre compiladores, mas estou tendo problema em definir a gramatica que aceite corretamente expressoes como a que eu passei.
No caso, uma parte dessa gramatica ja reconhece expressores matematicas, meu problema e justamente quando junto as duas coisas (expressoes matematicas e funcoes). Se puder dar uma olhada eu agradeco!

"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." (Brian W. Kernighan)
[WWW]
davidbuzatto
Moderador
[Avatar]

Membro desde: 07/08/2004 23:47:57
Mensagens: 4013
Localização: Vargem Grande do Sul - SP
Online

Oi schranko,

Não é AGL é ACL certo? Então, o que está acontecendo que é o parser começa a avaliar a expressão e para depois de ACL(L1), dando a expressão como verdadeira.
Estou fazendo umas modificações, vou ver se consigo resolver.

[]'s

Seja educado. Agradeça quem te ajudou. Não custa nada.
Dúvidas de Java? Utilize o fórum! Não respondo via MP.

"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." (Fowler)
"A vida é um escândalo, e no final dá sempre errado. O que humaniza o homem é o fracasso."

http://davidbuzatto.com.br | GitHub | uHunt | CV Lattes | Last.fm
[WWW]
davidbuzatto
Moderador
[Avatar]

Membro desde: 07/08/2004 23:47:57
Mensagens: 4013
Localização: Vargem Grande do Sul - SP
Online

Fiz uma versão simplificada da sua gramática e adicionei parênteses nas expressões.
Tirei as outras funções para facilitar meus testes.
Agora basta vc inseri-las novamente e testar.

Para que o parser leia toda a string de entrada, vc precisa usar o token EOF no final da regra de entrada (expression no seu caso), assim o parser só vai parar quando escontrar o fim do arquivo ou o fim da string.

Dá uma olhada como ficou.


[]'s

This message was edited 1 time. Last update was at 09/02/2012 12:32:42


Seja educado. Agradeça quem te ajudou. Não custa nada.
Dúvidas de Java? Utilize o fórum! Não respondo via MP.

"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." (Fowler)
"A vida é um escândalo, e no final dá sempre errado. O que humaniza o homem é o fracasso."

http://davidbuzatto.com.br | GitHub | uHunt | CV Lattes | Last.fm
[WWW]
davidbuzatto
Moderador
[Avatar]

Membro desde: 07/08/2004 23:47:57
Mensagens: 4013
Localização: Vargem Grande do Sul - SP
Online

Ah, desculpa a demora para responder. Ontem eu estava bem ocupado.

[]'s

Seja educado. Agradeça quem te ajudou. Não custa nada.
Dúvidas de Java? Utilize o fórum! Não respondo via MP.

"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." (Fowler)
"A vida é um escândalo, e no final dá sempre errado. O que humaniza o homem é o fracasso."

http://davidbuzatto.com.br | GitHub | uHunt | CV Lattes | Last.fm
[WWW]
schranko
JavaTeenager
[Avatar]

Membro desde: 05/09/2010 17:58:40
Mensagens: 156
Localização: Moscow, Russia
Offline

David, muito obrigado. Entendi sua solução, contudo obtive mais um erro aqui...
Ao avaliar a expressão (1+2)+3 ocorre o seguinte erro: line 1:4 missing EOF at ')' - porque isso ocorre?
Com relação a "demorar", não se desculpe! eu que me desculpo por minha ignorância ahahah

Muito obrigado,
Angelo

"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." (Brian W. Kernighan)
[WWW]
davidbuzatto
Moderador
[Avatar]

Membro desde: 07/08/2004 23:47:57
Mensagens: 4013
Localização: Vargem Grande do Sul - SP
Online

Oi Angelo,

Parece que resolvi. Adicionei mais uma produção que gera expression EOF.
Seu exemplo funcionou. Tentei um mais complexo e deu certo tbm ( (((1+2)+3)+(ACB(L502)*AGB(B5465))-144*400)+500/4 )
Dá uma olhada:



[]'s

Seja educado. Agradeça quem te ajudou. Não custa nada.
Dúvidas de Java? Utilize o fórum! Não respondo via MP.

"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." (Fowler)
"A vida é um escândalo, e no final dá sempre errado. O que humaniza o homem é o fracasso."

http://davidbuzatto.com.br | GitHub | uHunt | CV Lattes | Last.fm
[WWW]
schranko
JavaTeenager
[Avatar]

Membro desde: 05/09/2010 17:58:40
Mensagens: 156
Localização: Moscow, Russia
Offline

David, funcionou, mas agora está aceitando novamente aquelas expressões no início do problema. ACL(L1)1+2ACL(L2)

Vou dar uma olhada aqui...

Obrigado!

"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." (Brian W. Kernighan)
[WWW]
schranko
JavaTeenager
[Avatar]

Membro desde: 05/09/2010 17:58:40
Mensagens: 156
Localização: Moscow, Russia
Offline

OK David, mesmo assim obrigado. Se puder me ajudar só com mais uma dúvida então. O que preciso é personalizar as mensagens de erro de sintaxe. Sei que dá para implementar a gramática separada do código Java ou junta. Eu preciso de alguma forma interceptar os erros do ANTLR e enviar uma mensagem personalizada para cada erro. Como eu faria isso? Você poderia me explicar ou me enviar alguma referência ou exemplo de código? Muito obrigado pela sua atenção!

"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." (Brian W. Kernighan)
[WWW]
davidbuzatto
Moderador
[Avatar]

Membro desde: 07/08/2004 23:47:57
Mensagens: 4013
Localização: Vargem Grande do Sul - SP
Online

Oi Angelo,

Aqui explica como faz http://www.antlr.org/wiki/display/ANTLR3/Custom+Syntax+Error+Recovery

Algo q vc poderia tentar fazer é algo assim:


Crie a exceção que herda de RecognitionException ao invés de declará-la dentro da gramática.
Ai, quando por usar o parser, vc captura essa excessão que vai conter o erro personalizado.

[]'s

Seja educado. Agradeça quem te ajudou. Não custa nada.
Dúvidas de Java? Utilize o fórum! Não respondo via MP.

"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." (Fowler)
"A vida é um escândalo, e no final dá sempre errado. O que humaniza o homem é o fracasso."

http://davidbuzatto.com.br | GitHub | uHunt | CV Lattes | Last.fm
[WWW]
 
Índice dos Fóruns » Java Avançado
Ir para:   
Powered by JForum 2.1.8 © JForum Team