Implementación de la Tabla de Atributos
Siguiendo la tabla de atributos de la gramática atribuida, se deben añadir los atributos type
y lvalue
a las expresiones.
Symbol | Atribute Name | Java Type | Syn/Inh | Description |
expression | type | Type | Synthetized | Type of the expression |
expression | lvalue | boolean | Synthetized | True if the expression can appear to the left of an assignment |
De nuevo, aunque se podría hacer a mano, en este apartado se hará automáticamente con VGen. Para ello bastará con indicar en el fichero de entrada de VGen, /specifications/AbstractGrammar.txt los atributos que añade la etapa actual.
CATEGORIES
...
NODES
program -> ...
...
// -----------------------
ATTRIBUTE GRAMMAR Identification
variable -> varDefinition;
// -----------------------
ATTRIBUTE GRAMMAR TypeChecking
expression -> type;
expression -> lvalue:boolean;
Ahora sólo quedaría regenerar el código con vgen.
c:\mlang> vgen.bat
Esto produce los siguientes cambios en el código fuente para implementar los atributos type
y lvalue
en las expresiones:
Por un lado, añade los métodos de acceso en el interfaz Expression.
java/* PHASE TypeChecking expression -> type:type expression -> lvalue:boolean */ public interface Expression extends AST { public void setType(Type type); public Type getType(); public void setLvalue(boolean lvalue); public boolean isLvalue(); }
Además, en la clase AbstractExpressión de la que derivan todo los nodos expressión, se han implementando los métodos anteriores.
java/* PHASE TypeChecking expression -> type:type expression -> lvalue:boolean */ public abstract class AbstractExpression extends AbstractAST implements Expression { // PHASE TypeChecking private Type type; private boolean lvalue; // -------------------------------- // PHASE TypeChecking public void setType(Type type) { if (type == null) throw new IllegalArgumentException("Parameter 'type' can't be null. Pass a non-null value or use 'type?' in the abstract grammar"); this.type = type; } public Type getType() { return type; } public void setLvalue(boolean lvalue) { this.lvalue = lvalue; } public boolean isLvalue() { return lvalue; } }
TIP
Si se estuviera usando herencia múltiple de categorías y hubiera nodos que implementaran el interfaz Expressión pero no heredaran de AbstractExpression, VGen implementaría los métodos directamente en dichos nodos de tal manera que queden implementados en cualquier circunstancia.