Universidad de los Andes Ingeniería de Sistemas y Computación ISIS-4109 Diseño de Lenguajes Profesor: Silvia Takahashi ([email protected]) Gramática de un lenguaje para interactuar con el Micromundo Suponga que tenemos las siguientes funciones para manejar el micromundo. No estamos suponiendo una implementación OO. En lugar de esto, suponemos que tenemos funciones que nos permiten construir, modificar y consultar micromundos: newWorld(dim, cones,cubes, cylinders, pyramids, spheres: int; loc: Location) : Micromundo Esta función sirve para crear un micromundo de dimensión dim con el contendido inicial de la caja dado por los parámetros. La localización inicial está dada por loc que puede ser de la forma Box o loc(int, int). move(mundo :Micromundo, loc : Location): Micromundo El valor de esta función es el micromundo que resulta de mover el brazo de mundo al sitio indicado por loc. No debe sacar al brazo del mundo. get(mundo :Micromundo, shape :Shape): Micromundo El valor de esta función es el micromundo que resulta de pasar un objeto de forma “shape” de la caja al brazo en el micromundo mundo. El brazo debe estar sobre la caja, no debe tener ningún objeto y la caja debe contener el objeto. put(mundo :Micromundo): Micromundo El valor de esta función es el micromundo que resulta de poner el objeto que tiene el brazo en la posición donde se encuentra. Debe tener un objeto y si no está sobre la caja, no debe haber ni un cono, ni una esfera ni una pirámide donde se encuentra. pick(mundo :Micromundo): Micromundo El valor de esta función es el micromundo que resulta de recoger el objeto que se encuentra en la posición donde se encuentra el brazo en el micromundo mundo. El brazo no debe estar sobre al caja y debe haber al menos un objeto en la casilla sobre la que se encuentra el brazo. getLocation(mundo: Micromundo): Location Retorna la posición del brazo en el micromundo mundo. asgReg(mundo: Micromundo, reg, val: int):Micromundo El valor de esta función es el micromundo que se obtiene al asignarle al registro reg el valor val en el micromundo mundo. getReg(mundo: Micromundo, reg: int): int El valor de esta función es el valor guardado en el registro reg en el micromundo mundo. getTopShape(mundo: Micromundo): Shape El valor de esta función es la forma del que está en el tope de la casilla sobre el cual se encuentra el brazo. El brazo no debe estar sobre la caja y debe haber al menos un objeto en la casilla. carryingObject?(mundo: Micromundo): Boolean El valor es verdadero si el brazo tiene un objeto; falso de lo contrario. anyObject?(mundo: Micromundo): Boolean El valor es verdadero si la casilla donde se encuentra el brazo tiene una casilla. Es falso de lo contrario. El brazo debe estar sobre una casilla. carriedObject(mundo: Micromundo): Shape La forma del objeto que tiene el brazo en el micromundo mund. El brazo debe tener un objeto. getDim(mundo: Micromundo): int Retorna la dimensión del mundo. countBox(mundo:Micromundo, shape: Shape):int Retorna la cantidad de objetos de forma shape que hay en la caja. getXLocation(loc: Location): int Loc debe ser de la forma loc(int, int) y retorna el primer componente. getYLocation(loc: Location): int Loc debe ser de la forma loc(int, int) y retorna el segundo componente. Read():int Lee un valor entero de un stream de entrada. Ahora las ecuaciones denotacionales correspondientes a la gramática dada en clase. Suponemos que los valores por defecto son: Dimensión: 10, 10 de cada objeto en la caja e inicia en la caja. Después de cada regla de la gramática se escribe la ecuación denotacional. Prog → NewWorld InicDPB StartExecution Instructions End Prog a NewWorld InicDPB StartExecution Instructions End b = let m = InicDPB a InicDPB b in Instrs a Instructions bm endlet InicDPB → StartInic Dim ( INT) EndInic InicDPB a StartInic Dim ( INT) EndInic b = newWorld(INT.val, 10, 10, 10, 10, 10, Box) InicDPB → StartInic Dim ( INT ) , InicPB InicDPB a StartInic Dim ( INT ) , InicPB b = InicPB a InicPB b INT.val InicDPB → StartInic InicPB InicDPB a StartInic InicPB b = InicPB a InicPB b10 InicDPB → λ InicDPB a λb = newWorld(10,10, 10, 10, 10, 10, Box) InicPB → Pos ( Location ) EndInic InicPB a Pos ( Location ) EndInic bdim = NewWorld(dim, 10, 10, 10, 10, 10, Loc a Locationb) InicPB → Pos ( Location ) , InicB EndInic InicPB a Pos ( Location ) , InicB EndInic bdim = let loc = Loc a Locationb in InicB a InicB bdim,loc endlet InicPB → InicB EndInic InicPB a InicB EndInic bdim = InicB a InicB bdim,Box InicB → InicBox (cns(INT1),cbs(INT2),cyls(INT3),pyrs(INT4),sphs(INTS)) InicB a InicBox ( cns(INT1), cbs(INT2) cyls(INT3), pyrs(INT4), sphs(INT5)) EndInic bdim, loc = NewWorld( dim, INT1.val, INT2.val, INT3.val, INT4.val, INT5.val, loc) Location → BOX Loca BOX b = Box Location → INT1 , INT2 Loca INT1 , INT2 b = loc(INT1,.val, INT2.val) Instructions → Inst Instrs a Inst bm = Instr a Inst bm Instructions → Inst ; Instructions Instrs a Inst ; Instructions b m = let m1= Instr a Inst b m Instrs a Instructions b m1 endlet in Inst → GO Location1 Instr a GO Location1 b m = let loc = location a Location1 b m in if (loc = Box) then move(m, Box) else let x = getYLocation(loc) and y = getYLocation(loc) and n = getDim(m) in if (1 <= x and x<= n and y >= 1 and y <=n) then move (m, loc) else ⊥ endif endLet endIf endlet Inst → GET Shape Instr a GET Shape b m= let s = Shape a Shape b in if CountBox(m,s) > 0 and not(carryingObject?(m)) and getLocation (m) == Box then get(m,s) else ⊥ Endif endLet Inst → PUT Instr a PUT b m= if not(carryingObject?(m))then ⊥ else if getLocation(m) == Box then Put(m) else if not(anyObject?(m)) then Put(m) else if getTopShape(m)∈{Cube,Cylinder} then Put(m) else ⊥ endIf endIf endIf endIf Inst → PICK Instr a PICK b m= if getLocation(m)= Box then ⊥ else if carryingObject?(m) or not(anyObject?(m)) then ⊥ else Pick(m) endIf endIf Inst → MOVE Dir INT Instr a MOVE Dir INT b m= if getLocation(m)=Box then ⊥ else let dir = Dira Dir b and x y N d = = = = getXLocation(getLocation(m)) and getYLocation(getLocation(m)) and getDim(m) and INT.val in if dir == Right then if (d+x) > N then ⊥ else move(m,pos(d+x,y)) endif else if dir == Left then if (x-d) < 1 then ⊥ else move(m,pos(x-d,y)) endif else if dir == Front then if (y-d) < 1 then ⊥ else move(m,pos(x,y-d)) endif else if (y+d) >N then ⊥ else move(m,pos(x,y+d)) endif endif endif endif endlet endif Inst → READ REG Instr a READ REG b m = asgReg(m, REG.val,read()) Inst → REG ASG Value Instr a REG ASG Value b m = asgReg(m, REG.val, Val a Value b m) Inst → IF Cond THEN Instructions ELSE Instructions FI Instr a IF Cond THEN Instructions1 ELSE Instructions2 FI b m = if Cond a Cond b m then Instr a Instructions1 b m else Instr a Instructions2 b m endif Inst → WHILE Cond DO Instructions OD Instr a WHILE Cond DO Instructions OD b m = if Cond a Cond b m then insLoop else m endif where insLoop = let m1= Instrsa Instructions b m in Instr a WHILE Cond DO Instructions OD b m1 Endlet endWhere Shape → CUBE Shapea CUBE b= Cube Shape → SPHERE Shapea SPHERE b= Sphere Shape → PYRAMID Shapea PYRAMID b= Pyramid Shape → CONE Shapea CONE b= Cone Shape → CYLINDER Shapea CYLINDER b= Cylinder Dir → FRONT Dira Front b= Front Dir → BACK Dira BACK b= Back Dir → RIGHT Dira RIGHT b= Right Dir → LEFT Dira LEFT b= Left Location1 → BOX Location a BOX bm= Box Location1 → Value1 , Value2 Location a Value1 , Value2 bm= Pos (Val a Value1 bm, Val a Value2 bm ) Value → INT Val a INT bm= INT.val Value → REG Val a REG bm= GetReg(m, Reg.val) Value → GETX Val a GETX bm= let loc = GetLocation(m) in if loc == BOX then ⊥ else getXLocation(loc) endif endlet Value → GETY Val a GETY bm= let loc = GetLocation(m) in if loc == BOX then ⊥ else getYLocation(loc) endif endlet Value → GET_DIM Val a GET_DIM bm= getDim(m) Cond → AT BOX Cond a AT BOX bm= (getLocation(m) == Box) Cond → ANY (Shape) IN BOX Cond a AT BOX bm= (CountBox(m, Shape a Shape b) > 0) Cond → HAS ANY Cond a HAS ANY bm= (carryingObject?(m)) Cond → CAN PUT Cond a CAN PUT bm= if not(carryingObject?(m))then false else if getLocation(m) == Box then true else if not(anyObject?(m)) then true else if getTopShape(m)∈{Cube,Cylinder} then true else false endIf endIf endIf endIf Cond → AT FAR Dir Cond a AT FAR Dir bm= if getLocation(m)=Box then false else let dir = Dira Dir b and x = getXLocation(getLocation(m)) and y = getYLocation(getLocation(m)) and N = getDim(m) in if dir == Right then (x==N) else if dir == Left then (x==0) else if dir == Front then (y==0) else (y==N) endif endif endif endLet endif Terminal ( ) , ; REG INT Cbs Cns Cyls Sphs Pyrs ANY ASG AT BACK BOX CAN CONE CUBE CYLINDER Dim DO ELSE End EndInic FAR FI FRONT GET GO HAS IF IN InicBox LEFT MOVE NewWorld OD PICK Pos PUT PYRAMID READ RIGHT SPHERE Sphs StartExecution Representación Textual “(“ “)” “,” “;” “REG1”|“REG2” | “REG3” |“REG4” |“REG5” | “REG6” | “REG7” | “REG8” [“0”-“9”]+ “Cubes” “Cones” “Cylinders” “Spheres” “Pyramids” “ANY” “:=” “AT” “BACK” “Box” “CAN” “CONE” “CUBE” “CYLINDER” “Dim” “DO” “ELSE” “End” “IndInic” “FAR” “FI” “FRONT” “Get” “Go” “HAS” “IF” “IN” “InicBox” “LEFT” “MOVE” “NewWorld” “OD” “PICK” Pos “PUT” “PYRAMID” “READ” “RIGHT” “SPHERE” “Spheres” “StartExecution” StartInic THEN WHILE “StartInic” “THEN” “WHILE”