Construyendo el compilador Parte IV: ANTLR V4, y gramática de Cardelli

 La entrada de hoy es algo corta. Solo quiero nombrar y enfatizar qué es una gramática de cardelli.

Una gramática de cardelli o los tipos de cardelli, es una manera de expresar formalmente las reglas semánticas que definen un lenguaje de programación. Para este proyecto, serán las siguientes.


Sistema de tipos


Definiendo Sintaxis de los Tipos

  • int

  • char

  • boolean

  • void

  • error


Tipo de ámbito

  • Ámbito estático-léxico


Consideraciones generales


  • Números son: [0..9]*

  • Palabras reservadas de bool: true, false

  • otras palabras reservadas: if, while, { },[ ],  



Proposiciones

: En todos los posibles ámbitos

G : Ámbito Global

No.

Regla

Explicación

1

|- true: bool

|- false: bool

Los lexemas “true” y “false” serán tomados con tipo de dato bool en todo el programa.

2

G |- a: int

G |- b: int

------------------

G |- a + b: int

G |- a - b: int

G |- a * b: int

G |- a / b: int

G |- a % b: int

G |- a < b: bool

G |- a > b: bool

G |- a >= b: bool

G |- a <= b: bool

G |- a == b: bool

G |- a != b: bool

G |- a = b: void

Entre “a” y “b”, con tipos de datos “int”, la suma, resta,  multiplicación, división y modular serán “int” también.


Las operaciones lógicas retornarán bool.

3

G |- a: char

G |- b: char

------------------

G |- a + b: char

G |- a - b: ERROR

G |- a * b: ERROR

G |- a / b: ERROR

G |- a == b: bool

G |- a != b: bool

G |- a = b: void

Entre “a” y “b”, con tipos de datos “char”, la suma resultará en la concatenación pero la resta, multiplicación y división generará ERROR.


Los tipos de operandos para los operadores de equivalencia deben de ser ambos operandos del mismo tipo.

4

G |- a: int

G |- b: char

------------

G |- a + b: int

G |- a - b: int

G |- a * b: int

G |- a / b: ERROR

G |- a % b: int

G |- a == b: ERROR

G |- a != b: ERROR

G |- a && b: ERROR

G |- a || b: ERROR

G |- !a || !b: ERROR

Con carácter global, las operaciones de suma, resta y multiplicación entre un int y un char resultan en un int. Sin embargo, la división generará ERROR.

5

|- <: bool

|- >: bool

|- <=: bool

|- >=: bool

Operaciones de comparación

6

|- ==: bool

|- !=: bool

Operaciones de equivalencia

7

|- &&: bool

|- ||: bool

Operaciones condicionales

8

|- a(): void

Existencia de métodos con valor de retorno vacío

9

G |- a: bool

G |- b: bool

------------------

G |- a && b: bool

G |- a || b: bool

G |- a == b: bool

G |- a != b: bool

G |- a = b: void

Con carácter global, las operaciones condicionales entre booleanos dan cómo resultado un booleano.


Los tipos de operandos para los operadores de equivalencia deben de ser ambos operandos del mismo tipo.

10

G |- a: int

G |- b: bool

------------------

G |- a + b: ERROR

G |- a - b: ERROR

G |- a * b: ERROR

G |- a / b: ERROR

G |- a % b: ERROR

G |- a == b: ERROR

G |- a != b: ERROR

G |- a && b: ERROR

G |- a || b: ERROR

G |- !a || !b: ERROR

Cualquier operación entre tipos de datos “int” y “bool”, la suma, resta, multiplicación y división resultará en ERROR.

11

, a: int, b: int |- a==b: ERROR

Dadas dos variables del tipo int o de cualquier tipo, si ambas son iguales, ERROR.

12

, a: int,bool,char |- a: ERROR

Dado una variable “a” de tipo int, bool o char, si se vuelve a definir otra variable a, genera  ERROR.

13

, a: int |- w=10: ERROR

Dada una variable int o cualquier tipo, es teorema que si tratamos de usar otra que no sea la declarada, es error.

14

|- main(): void

El  programa  contiene  una  definición  de  un  método main sin  parámetros,  en donde se empezará la ejecución del programa.

15

G |- a: void

G |- b: void

------------------

G |- a + b: ERROR

G |- a - b: ERROR

G |- a * b: ERROR

G |- a / b: ERROR

G |- a % b: ERROR

Funciones, variables, etc. de tipo void que no retornan un valor, no pueden realizar operaciones entre sí, por lo que generará ERROR.

16

num en la declaración de un arreglo debe de ser mayor a 0.

*

17

El número y tipos de argumentos en la llamada a un método deben de ser los mismos  que  los  argumentos  formales,  es  decir  las  firmas  deben  de  ser idénticas.

*

18

|- expre<method>: return value

Si  un  método  es  utilizado  en  una  expresión,este  debe  de  devolver  un resultado.*

19

G |- a: bool

G |- b: bool

--------------------

G |- a && b: bool

G |- a || b: bool

G |- !a || !b: bool

Los tipos de operandos para los operadores <cond_ops> y el operador ! deben de ser del tipo boolean.

20

G |- <expr>: bool

--------------------

G |- if(<expr>){...}: void

G |- while(<expr>){...}: void

Teniendo <expr> como un bool, dicha expresión está dentro de una condición if y while es correcto, de lo contrario ERROR.

21

G |- <expr>: int

G |- id: arreglo(tabla de símbolos)

--------------------

G |- id[<expr>]: void

Si se tiene la expresión id[<expr>], id debe de ser un arreglo y el tipo de <expr> debe de ser int.

22

G |- X: struct

G |- Y: struct

G |- x: int

G |- y: int

--------------------

G |- X a: void

G |- Y b: void

G |- a.x: int

G |- b.y: int

G |- a.x + a.y: int

G |- a.x - a.y: int

G |- a.x * a.y: int

G |- a.x / a.y: int

La definición de un tipo struct ocurre posicionando el struct utilizado y el nombre de la variable del struct, además, el contenido del struct (en este caso ocurre con int’s, pero puede ser cualquier tipo primitivo) puede operarse entre sí como se ha hecho en definiciones anteriores.




Espero les guste. 

En la siguiente entrada.
El analizado semántico TERMINADO!!!


Comentarios

Entradas populares de este blog

Construyendo el compilador Parte I: ANTLR V4 (ya van 4 versiones, increible), café y una miradita a los parser y lexer generados con Java

Construyendo el compilador Parte V: Finalizando el analizar Semántico

Construyendo el compilador Parte III: ANTLR V4, Listener vs Visitor y la tabla de Símbolos