É gerada uma classe para o analisador semântico. Sua implementação porém é por conta do usuário.
O único método que o analisador semântico possíu é o método executeAction(). O analisador sintático chama ele sempre que uma ação semântica é encontrada. São passados de paâmetro para este método o número da ação semântica que o disparou, e o último token reconhecido antes da ação.
Para este exemplo, o analisador semântico vai precisar apenas de uma pilha para avaliar as expressões. Em casos mais complexos, como um compilador, será preciso uma tabela de símbolos também. E o gerador de código deve ser acionado por ações semânticas também.
import java.util.Stack;
public class Semantico implements Constants
{
Stack stack = new Stack();
public int getResult()
{
return ((Integer)stack.peek()).intValue();
}
public void executeAction(int action, Token token) throws SemanticError
{
Integer a, b;
switch (action)
{
case 1:
String tmp = currentToken.getLexeme();
if (tmp.charAt(0) == '0')
throw new SemanticError("Números
começados por 0 não são permitidos", token.getPosition());
stack.push(Integer.valueOf(tmp));
break;
case 2:
b = (Integer) stack.pop();
a = (Integer) stack.pop();
stack.push(new Integer(a.intValue()
+ b.intValue()));
break;
case 3:
b = (Integer) stack.pop();
a = (Integer) stack.pop();
stack.push(new Integer(a.intValue()
- b.intValue()));
break;
case 4:
b = (Integer) stack.pop();
a = (Integer) stack.pop();
stack.push(new Integer(a.intValue()
* b.intValue()));
break;
case 5:
b = (Integer) stack.pop();
a = (Integer) stack.pop();
stack.push(new Integer(a.intValue()
/ b.intValue()));
break;
}
}
}
Este é um exemplo simples, todas as ações são implementadas diretamente dentro do switch. Um caso mais complexo deve ter um método para cada ação, utilizando o switch para selecionar o método.
Foi feita uma restrição semântica para exemplificar como devem ser indicados os erros semânticos. Se o analisador encontra um erro, ele deve lançar um SemanticError, passando como parâmetro a mensagem de erro e a posição do erro (que é em geral a posição do último token).
Java | throw new SemanticError(msg, pos) |
C++ | throw SemanticError(msg, pos) |
Delphi | raise ESemanticError.create(msg, pos) |