Skip to content

Especificación de la Comprobación de Tipos

Extracción de Requisitos

Se incluyen a continuación los requisitos de la descripción del lenguaje que corresponden a la etapa de comprobación de tipos de MLang:

  • La escritura (print) puede ser tanto de expresiones enteras como reales.
  • Las operaciones aritméticas solo podrán realizarse entre operandos del mismo tipo, no habiendo conversiones implícitas. Esto quiere decir que, por ejemplo, no se puede sumar un entero con un real.
  • En las asignaciones, el tipo de la variable a asignar deberá coincidir con el tipo del valor a ser asignado. Por tanto, no se puede asignar un valor real a una variable entera ni a la inversa.

Especificación mediante Gramática Atribuida

Los requisitos semánticos anteriores se expresarán, tal y como se hizo en la etapa de identificación, mediante una gramática atribuida. Esto permitirá indicar qué información se necesita añadir al árbol (atributos) y qué reglas se deben aplicar.

Para hacer la gramática atribuida de esta etapa, al igual que como se hizo en la anterior, se utilizará el esqueleto de dicho metalenguaje generado por VGen en vgen.output/skeleton.specifications. Así que, de nuevo, se abre el fichero Attribute Grammar.template.html en Word (o editor equivalente) para y rellenar las tablas con los detalles de la especificación de esta etapa.

Concretamente, en la tabla de reglas:

  • En la tercera columna (semantic functions) se realizará la tarea de inferencia de tipos, es decir, calcular el tipo de toda expresión.
  • En la segunda columna (predicates), se realizará la tarea de comprobación de tipos propiamente dicha, en la cual se comprobarán los tipos obtenidos mediante la inferencia en el contexto del nodo actual.

El resultado de este proceso se muestra a continuación:

Attributes

SymbolAtribute NameJava TypeSyn/InhDescription
expressiontypeTypeSynthetizedType of the expression
expressionlvaluebooleanSynthetizedTrue if the expression can appear to the left of an assignment

Auxiliary Functions

NameDescription
sameType(type_a, type_b)True if the params are equal

Rules

NodePredicatesFunctions
program → varDefinition* statement*
varDefinition → type name:string
intType:type → ε
floatType:type → ε
print:statement → expression
assignment:statement → left:expression right:expressionsameType(left.type, right.type)

left.lvalue == true
arithmetic:expression → left:expression operator:string right:expressionsameType(left.type, right.type)arithmetic.type = left.type
arithmetic.lvalue = false
variable:expression → name:stringvariable.type = variable.varDefinition.type

variable.lvalue = true
intLiteral:expression → intValue:intintLiteral.type = intType
intLiteral.lvalue = false
floatLiteral:expression → floatValue:floatfloatLiteral.type = floatType
floatLiteral.lvalue = false

Cosas a destacar de la gramática atribuida:

  • El nombre del atributo lvalue proviene de la terminología de la teoría de lenguajes de programación, donde se denomina lvalue a la expresión que puede aparecer en la parte izquierda de una asignación (left value). Por tanto, decir que una expresión es lvalue es decir que la expresión puede ser asignada, es decir, es modificable.

    TIP

    Nótese que el atributo lvalue no hubiera sido necesario si se hubiera definido el hijo left de assignment como una variable en vez de una expression. En la especificación del parser se explicó el porqué de esta decisión.

  • La función auxiliar sameType, evidentemente, no es necesaria y hubiera sido más lógico poner directamente left.type == right.type en lugar de usar dicha función. Al ser MLang es un lenguaje tan sencillo, no es necesaria ninguna función auxiliar. Sin embargo, se pretendía que hubiera alguna función de este tipo para poder mostrar posteriormente cómo sería su implementación, ya que en gramáticas más elaboradas no es raro que se necesiten funciones auxiliares. Es por ello que, por un motivo didáctico, se añade de una forma un tanto artificial esta función auxiliar.