Acciones en Medio de una Regla

A veces necesitamos insertar una acción en medio de una regla. Una acción en medio de una regla puede hacer referencia a los atributos de los símbolos que la preceden (usando $n), pero no a los que le siguen.

Cuando se inserta una acción $ \left \{ action_1\right \}$ para su ejecución en medio de una regla $ A \rightarrow \alpha \beta $ :

$ A \rightarrow \alpha \left \{ action_1 \right \} \beta \left \{ action_2\right \}$
eyapp crea una variable sintáctica temporal $ T$ e introduce una nueva regla:

  1. $ A \rightarrow \alpha T \beta \left \{ action_2\right \}$
  2. $ T \rightarrow \epsilon \left \{ action_1 \right \}$

Las acciones en mitad de una regla cuentan como un símbolo mas en la parte derecha de la regla. Asi pues, en una acción posterior en la regla, se deberán referenciar los atributos de los símbolos, teniendo en cuenta este hecho.

Las acciones en mitad de la regla pueden tener un atributo. Las acciones posteriores en la regla se referirán a él como $_[n], siendo n su número de orden en la parte derecha.

Observe que la existencia de acciones intermedias implica que la gramática inicial es modificada. La introducción de las nuevas reglas puede dar lugar a ambiguedades y/o conflictos. Es responsabilidad del programador eliminarlos. Por ejemplo, dada la gramática:

cs : '{' decs ss '}' | '{' ss '}' ;
Si la modificamos como sigue:
cs : { decl(); } '{' decs ss '}' 
   | '{' ss '}' 
   ;
habremos introducido un conflicto.

Ejercicio 3.26.1   Explique las razones por las cuales la introducción de la acción que prefija la primera regla da lugar a conflictos

Ejercicio 3.26.2   El conflicto no se arregla haciendo que la acción que precede sea la misma:
cs : { decl(); } '{' decs ss '}' 
   | { decl(); } '{' ss '}' 
   ;
Explique donde está el fallo de esta propuesta

Ejercicio 3.26.3   ¿Se arregla el conflicto anterior usando esta otra alternativa?

cs :  tp '{' decs ss '}' 
   |  tp { decl(); } '{' ss '}' 
   ;
   
tp : /* empty */ { decl(); }
   ;

Casiano Rodríguez León
2009-12-09