我获得了以下数据类型:
data Aexp = N Integer | V Var | Add Aexp Aexp | Mult Aexp Aexp | Sub Aexp Aexp
data Bexp = Bcon Bool | Eq Aexp Aexp | Le Aexp Aexp | Neg Bexp | And Bexp Bexp
data Stm = Ass Var Aexp | Skip | Comp Stm Stm | If Bexp Stm Stm | While Bexp Stm | Block DecV DecP Stm | Call Pname
分别用于算术表达式,布尔表达式和语句。
我被要求返回代表以下程序的Stm:
x:=5;
y:=1;
while ¬(x=1) do
y:=y*x;
x:=x-1
到目前为止,我有以下内容:
p :: Stm
p = (Ass x 5) (Ass y 1) (While (Neg (Eq x 1)) Ass x (Sub x 1) Ass y (Mult y x))
我这样做只是在纸上写出程序,然后从中绘制语法树。首先,我不确定这是否真的正确,因为我真的不知道如何证明它。第二,当我编译时,我得到很多错误,如:
denotational.hs:122:10: Not in scope: `x'
denotational.hs:122:20: Not in scope: `y'
denotational.hs:122:41: Not in scope: `x'
denotational.hs:122:51: Not in scope: `x'
denotational.hs:122:58: Not in scope: `x'
denotational.hs:122:67: Not in scope: `y'
denotational.hs:122:75: Not in scope: `y'
denotational.hs:122:77: Not in scope: `x'
对此的任何帮助将不胜感激。感谢
答案 0 :(得分:2)
您的AST代表(子)语言的语法。该子语言中的所有内容都必须在您的AST中,而不是Haskell。
因此,假设您的语言完全由您可能编写的Stm
列表表示
x:=5;
作为
fragx :: [Stm]
fragx = [ Ass "x" (N 5) ]
它在AST的树结构中捕获该片段中从字面值到绑定变量名称的所有信息。一个更大的例子
x:=5;
y:=1;
是
frag2 :: [Stm]
frag2 = [ Ass "x" (N 5)
, Ass "y" (N 1)
]
fragy :: [Stm]
fragy = [ Ass "y" (N 1) ]
与
frag2 == fragx ++ fragy
演示了我们如何谈论将两个程序在语法上附加为Haskell函数(++) :: [Stm] -> [Stm] -> [Stm]
。同样,这些片段是子语言语法的简单静态表示。在Haskell方面没有什么棘手的事情发生,特别是没有Haskell变量流入子语言变量。
添加最终片段可能看起来像
fragAll :: [Stm]
fragAll = fragx ++ fragy
++ [ While (Neg (Eq (V "x") (N 1))) (Block ...)
]
但如果不查看Block
的参数结构,就无法完成。