Boa tarde pessoal preciso da preciosa ajuda de v6, estou fazendo um anlisador lexico e sintatico com javacc eu gostaria de saber como eu faço para ele varre meu arquivo com o codigo e ele falar onde esta o erro e falar qual é o erro e continuar a analise do arquivo mesmo encontrado o erro no meio do caminho
Obrigado galera
Hummm vc precisa mesmo usar o javacc?
Não pode usar o antlr?
Se puder, posso te ajudar.
[]´s
e como seria com essa ferramenta???
Basicamente o ANTLR é um gerador de analizadores léxicos e sintáticos como o javacc.
www.antlr.org
[]´s
[quote=lecfribeiro]Boa tarde pessoal preciso da preciosa ajuda de v6, estou fazendo um anlisador lexico e sintatico com javacc eu gostaria de saber como eu faço para ele varre meu arquivo com o codigo e ele falar onde esta o erro e falar qual é o erro e continuar a analise do arquivo mesmo encontrado o erro no meio do caminho
Obrigado galera[/quote]
A arte de criar compiladores de modo que eles não parem no primeiro erro é muito complexa; consulte seu livro de teoria de compiladores para ver que isso não é nem um pouco fácil. De modo geral:
a) Você deve remodelar sua gramática de modo que ela aceite alguns erros bem comuns (e isso depende, é claro, da linguagem). Por exemplo, se for escrever um compilador para uma antiga versão do Pascal (onde você não pode pôr um “;” antes da palavra-chave END) então você pode escrever a gramática de modo que ela aceite esse “;”, mas que emita um aviso em vez de simplesmente parar a análise. Como se vê, isso é excessivamente trabalhoso.
b) Você deve ler a documentação do seu compilador de compiladores (pode ser o JavaCC, ou o AntLR, ou sei lá qual ferramenta você for usar) para ver que tipo de técnica deve-se usar no caso de encontrar um erro que você não previu, e que tipo de estratégia você deve adotar. Para cada compilador de compiladores a estratégia é bem diferente, e normalmente é bem complexa. Leia a documentação até formarem-se bolhas nas suas mãos
Conselho: deixe isso para depois. As primeiras versões do Turbo Pascal simplesmente paravam no primeiro erro, e isso era mais que suficiente para esse compilador (um dos primeiros que rodava muito bem no IBM-PC, de saudosa memória.)
É realmente necessário que vc continue procurando por erros léxicos e sintáticos após o primeiro erro encontrado?
Se vc estivesse falando sobre erros semânticos, dai vc estaria coberto de razão, mas erros sintáticos eu acho que não valerá o esforço.
O analisador sintático gerado pelo ANTLR verifica o código inteiro e gera código de recuperação.
No exemplo no final da minha postagem, que é uma gramática que reconhece expressões matemáticas e as calcula, eu quis que ao ocorrer algum erro (RecognitionException), a excessão fosse passada para baixo na pilha, sendo propagada até que seja tratada por quem chamar o método expressao, que corresponde ao não terminal inicial da gramática e por consequência é a base da pilha de chamadas para o analisador sintático. Quando você não fornece a cláusula catch da produção, o seguinte código é gerado no analisador sintático:
catch (RecognitionException re) {
reportError(re); // imprime o erro na saída de erro
recover(input,re); // recupera do erro para continuar a análise sintática
}
Caso o catch da produção seja fornecido, o código gerado dentro do catch do analisador sintático é o mesmo que está entre chaves, no meu caso um “throw exc;”
Segue a gramática do ANTLR 3.x.
[code]grammar Expressoes;
/*
-
Estrutura:
-
E : M ( ‘+’ M | ‘-’ M )*;
*/
expressao returns [ double v ]
: e=multExpr { $v = $e.v; } (
'+' e=multExpr { $v += $e.v; }
| '-' e=multExpr { $v -= $e.v; }
)*
;
catch [RecognitionException exc] { throw exc; }
/*
-
Estrutura:
-
M : A ( '’ A | ‘/’ A | ‘^’ A );
*/
multExpr returns [ double v ]
: e=atom { $v = $e.v; } (
'*' e=atom { $v *= $e.v; }
| '/' e=atom { $v /= $e.v; }
| '^' e=atom { $v = Math.pow( $v, $e.v ); }
)*
;
catch [RecognitionException exc] { throw exc; }
atom returns [ double v ]
: NUMERO {
$v = Double.parseDouble( $NUMERO.text );
}
| '(' expressao ')' {
$v = $expressao.v;
}
;
catch [RecognitionException exc] { throw exc; }
NUMERO : (‘0’…‘9’)+ ‘.’ (‘0’…‘9’)*
| ‘.’ (‘0’…‘9’)+
| (‘0’…‘9’)+
;
WS : ( ’ ’ | ‘\t’ | ‘\r’ | ‘\n’ ) {$channel=HIDDEN;};[/code]
cara
tem q mexer no codigo gerado
eh bem complicado, pq toda vez q tu gera sobresescreve
ele eh um pouco amarrado nesse ponto
mas eh possivel
Mexer em código gerado? Quem falou isso?
Até onde eu sei, da mesma forma que o ANTLR o JavaCC tbm deixa escrever ações baseadas no reconhecimento de terminais e não terminais.
Não sei na parte de tratamento de erros.