抽象语法树代表Haskell中的程序

时间:2014-04-11 22:28:09

标签: haskell syntax tree while-loop abstract

我获得了以下数据类型:

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'

对此的任何帮助将不胜感激。感谢

1 个答案:

答案 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的参数结构,就无法完成。

相关问题