Facult acultad de Ciencias Exactas, Exactas, Ingenier´ıa y Agrimensura Agrimensura Escuela de Ciencias Exactas y Naturales ´n Departamento de Ciencias de la Computaci on o ´ lisis de Lenguajes de Programacion ´ n II Analisis a o
Trabajo Pr´ actico actico 1
1
Intr In trodu oducc cci´ i´ on on
Se presenta un lenguaje imperativo simple con variables enteras y comandos para asignaci´on, composici´on on secuencial, ejecuci´on on condicional (if ) y ciclos (while). Se especific especifica a su sintax sintaxis is abstracta, su sintaxis concreta, una realizaci´on on de su sintaxis abstracta en Haskell , y por ´ultimo ultimo su sem´antica antica denotacion denotacional. al. El objetivo del trabajo es construir construir un int´ int´erprete erprete en Haskell Haskell para el lenguaje lenguaje presentad presentado. o. Para Para simplificar simplificar el trabajo, se brinda brinda un analizador analizador sint´actico actico –parser –parser – que traduce un programa de su representaci´on on concreta a una representaci´on on no ambigua en t´erminos erminos de la sintaxis sintaxis abstracta. abstracta. El trabajo se deber´a realizar individualmente y se debe entregar hasta el martes 31 de agosto inclusive:
• en papel, un informe con los ejercicios resueltos sin omitir todo el c´odigo que haya escrito; onico a
[email protected] con asunto TP1 ALPII, el c´odigo odigo fuente • por correo electr´onico del int´erprete erpr ete (archivo (ar chivo Interp.hs), y la implementaci´on on del algoritmo de Euclides en LIS (archivo euclides.lis).
2 2.1
Espec Especifi ifica caci ci´ ´ on del Lenguaje Imperativo Simple (LIS) on Sintax Sintaxis is Abstra Abstracta cta
Aunque es posible especificar la sem´antica antica de un lenguaje como una funci´on on sobre el conjunto de cadenas de caracteres de su sintaxis concreta, una especificaci´on on de ese estilo es innecesariamente complicada. Las frases de un lenguaje formal que se representan como cadenas de caracteres son en realidad entidades abstractas y es mucho m´as as conveniente definir la sem´antica antica del lenguaje sobre estas entidade entidades. s. La sintaxis abstracta de un lenguaje formal es la especificaci´on de los conjuntos de frases abstractas del lenguaje. Por otro lado, aunque las frases sean conceptualmente abstractas, se necesita alguna notaci´on para representarlas. Una sintaxis abstracta se puede expresar utilizando una gram´ atica abstracta , la cual define conjuntos de frases independientes de cualquier representaci´on on particular, pero al mismo tiempo provee una notaci´on on simple para estas frases. Una gram´atica atica abstracta para LIS es la siguiente:
intexp ::= nat | var | −u intexp | intexp + intexp | intexp −b intexp | intexp × intexp | intexp ÷ intexp boolexp ::= true | false | intexp = intexp | intexp < intexp | intexp > intexp | boolexp ∧ boolexp | boolexp ∨ boolexp | ¬boolexp Trabajo Pr´ actico 1
Agosto 2010
P´ agina agina 1
ALPII
comm ::= skip | var := intexp | comm ; comm | if boolexp then comm else comm | while boolexp do comm donde var representa al conjunto de identificadores de variables y nat al conjunto de los n´umeros naturales.
2.2
Sintaxis Concreta
La sintaxis concreta de un lenguaje incluye todas las caracter´ısticas que se observan en un progama fuente, como delimitadores y par´entesis. La sintaxis concreta de LIS se describe por la siguiente gram´ atica libre de contexto en BNF:
digit letter nat var intexp
::= ’0’ | ’1’ | . . . | ’9’ ::= ’a’ | . . . | ’Z’ ::= digit | digit nat ::= letter | letter var ::= nat | var | ’-’intexp | intexp ’+’intexp | intexp ’-’intexp | intexp ’*’intexp | intexp ’/’intexp | ’(’intexp ’)’ boolexp ::= ’true’ | ’false’ | intexp ’=’intexp | intexp ’<’intexp | intexp ’>’intexp | boolexp’&’boolexp | boolexp’|’boolexp | ’~’boolexp | ’(’boolexp’)’ comm ::= ’skip’ | var ’:=’intexp | comm ’;’comm | ’if’ boolexp ’then’ comm ’else’ comm ’end’ | ’while’ boolexp ’do’ comm ’end’ La gram´ atica as´ı definida es ambigua. Para desambiguarla, se conviene una lista de precedencia para los operadores del lenguaje, enumer´andolos en grupos de orden decreciente de precedencia:
−u
(∗ /)
(+ −b )
(= < >)
∼
& |
:= ;
donde todos los operadores binarios asocian a izquierda excepto =, < y > que no son asociativos (la asociatividad es irrelevante para :=, ya que ni (x0 := x1 ) := x2 ni x0 := (x1 := x2 ) satisfacen la gram´atica) Ejercicio 2.2.1 Extienda las sintaxis abstracta y concreta de LIS para incluir una nueva expresi´ on entera, al estilo del operador condicional ternario “ ?:” del lenguaje C
TP1
Ago 2010
P´ agina 2
ALPII
2.3
Realizaci´ on de la Sintaxis Abstracta en Haskell
Cada no terminal de la gram´atica de la sintaxis abstracta puede representarse como un tipo de datos; cada regla de la forma L ::= s0 R0 s1 R1 . . . Rn
s
1 n
−
donde s0 , . . . , sn son secuencias de s´ımbolos terminales, da lugar a un constructor de tipo R0 × R1 × . . . × Rn
1
−
→L
Los identificadores de variables podemos representarlos como String s. type Variable = String
Las expresiones aritm´ eticas con el tipo IntExp y las booleanas con el tipo BoolExp data IntExp = Const Integer
| Var Variable | UMinus IntExp | Plus IntExp IntExp | Minus IntExp IntExp | Times IntExp IntExp | Div IntExp IntExp data BoolExp = BTrue | BFalse | Eq IntExp IntExp | Lt IntExp IntExp | Gt IntExp IntExp | And BoolExp BoolExp | Or BoolExp BoolExp | Not BoolExp Los comandos son representados por el tipo Comm . Notar que s´ olo se permiten variables de un tipo (entero). data Comm = Skip
| | | |
Let Variable IntExp Seq Comm Comm Cond BoolExp Comm Comm While BoolExp Comm
Ejercicio 2.3.1 Extienda la realizaci´ on de la sintaxis abstracta en Haskell para incluir el operador
ternario descripto en el Ejercicio 2.2.1
2.4
Sem´ antica Denotacional para Expresiones
Para definir la sem´antica de las expresiones enteras y booleanas de la gram´atica abstracta, se deben definir funciones sem´anticas que les asignen un significado. El significado de una expresi´on entera es un valor de Z, y el significado de una expresi´on booleana es un valor en B = {true, false}. El significado o denotaci´on de cada expresi´on depende de un estado que le asigna un valor (entero)
TP1
Ago 2010
P´ agina 3
ALPII
a sus variables. Llamamos Σ al conjunto de estados var → Z que le atribuye a cada variable un valor entero. Las funciones sem´anticas para las expresiones del lenguaje son −intexp ∈ intexp → Σ → Z
−boolexp ∈ boolexp → Σ → B
y quedan definidas por las siguientes ecuaciones, donde σ ∈ Σ. 0intexp σ vintexp σ −u eintexp σ e0 + e1 intexp σ
= = = =
0 σv −eintexp σ e0 intexp σ + e1 intexp σ
trueboolexpσ falseboolexpσ e0 = e1 boolexpσ ¬ pboolexpσ p0 ∧ p1 boolexpσ p0 ∨ p1 boolexpσ
= = = = = =
true false
e0 intexp σ = e1 intexp σ ¬ pboolexpσ p0 boolexpσ ∧ p1 boolexpσ p0 boolexpσ ∨ p1 boolexpσ
(y an´ alogamente para 1, 2, . . . )
(y an´ alogamente para −b , × y ÷)
(y an´ alogamente para < y >)
Es importante distiguir entre el lenguaje del cual se describe la sem´antica, o lenguaje objeto, y el lenguaje que se utiliza para describirla, el metalenguaje. En el lado izquierdo de cada ecuaci´on, los corchetes dobles encierran un patr´ on similar al lado derecho de alguna regla de producci´on de la gram´atica abstracta, donde e, e0 y e1 son metavariables sobre expresiones enteras y p, p0 y p1 son metavariables sobre expresiones booleanas. Puede pensarse que es absurdo definir 0 en t´erminos de 0, + en t´erminos de +, y as´ı sucesivamente. Sin embargo, no hay circularidad en las definiciones porque los s´ımbolos encerrados entre corchetes dobles denotan constructores del lenguaje objeto, mientras que fuera de ellos denotan operadores del metalenguaje (en este caso, la matem´atica y l´ogica convencionales). Las ecuaciones dadas satisfacen dos condiciones fundamentales:
• Existe exactamente una ecuaci´on para cada producci´on de la gram´atica abstracta • Cada ecuaci´on expresa el significado de una frase en funci´on de los significados de sus subfrases Un conjunto de ecuaciones que cumple estas condiciones se dice que es dirigido por sintaxis, y en conjunto con una definici´on adecuada de la gram´atica asegura que los objetos definidos son realmente funciones. Existe un solo problema con estas definiciones: cada expresi´on entera debe denotar alg´ un valor entero, pero en la aritm´etica convencional no se le puede asignar ning´un valor con sentido a una divisi´on de la forma n ÷ 0. Por simplicidad, evitamos tratar este problema dentro de la definici´on de la sem´antica denotacional, pero sin embargo lo trataremos m´as elegantemente al momento de construir un int´ erprete para el lenguaje. Ejercicio 2.4.1 Extienda la sem´ antica denotacional para expresiones enteras para incluir el op-
erador ternario descripto en el Ejercicio 2.2.1
2.5
Sem´ antica denotacional para comandos
Los comandos simplemente modifican el estado Σ. Por lo tanto el significado de un comando es una funci´on (parcial) Σ → Σ. Sea (x → n; σ) el estado que devuelve n si la variable es x y se TP1
Ago 2010
P´ agina 4
ALPII
comporta como σ en cualquier otro caso. Entonces: skipcomm σ v := ecomm σ c; c comm σ
= σ = (v → eintexp σ; σ) = c comm (ccomm σ) ccomm σ cuando bboolexpσ = true = c comm σ cuando bboolexpσ = false c; while b do ccomm σ cuando bboolexpσ = true = σ cuando bboolexpσ = false
if b then c else c comm σ
while b do ccomm σ
La ecuaci´on que define el caso del while no es dirigida por sintaxis (no est´a dada exclusivamente por el significado de sus subfrases), por lo que no tenemos ninguna garant´ıa de que la ecuaci´on define un significado ´unico y que por lo tanto estamos definiendo una funci´on. Sin embargo, para solucionar esto tendr´ıamos que dejar de trabajar con funciones entre conjuntos y entrar en la teor´ıa de dominios. Por ahora, y con esta advertencia, tomamos la ecuaci´ on dada como una definici´on v´alida. Ejercicio 2.5.1 Complete el script bosquejado en el archivo Interp.hs, para construir un int´ erprete
de LIS. H´ agalo primero dejando que el metalenguaje (Haskell) maneje los errores de divisi´ on por 0. Luego modifique el tipo de retorno y la definici´ on de la funci´ on de evaluaci´ on para poder distinguir cuando se produce un error de divisi´ on por 0. Puede utilizar la funci´ on run definida en Interp.hs para verificar que el int´erprete se comporta como es esperado al ejecutar los programas de ejemplo sqrt.lis y error.lis Ejercicio 2.5.2 Escriba un programa euclides.lis que use el algoritmo de Euclides y que calcule
el m´ aximo com´ un divisor de dos naturales a y b dados y lo guarde en una variable res. Verifique que el programa se interpreta correctamente. Ejercicio 2.5.3 El comando repeat tiene la forma repeat c until b. Su efecto se describe por
el siguiente diagrama de flujo:
Figure 1: Comando repeat Agregue una regla de producci´ on a la gram´ atica abstracta de LIS y extienda la funci´ on sem´antica de comandos para el comando repeat .
TP1
Ago 2010
P´ agina 5