【问题标题】:Writing a mini-language with haskell, trouble with "while" statements and blocks { }用 haskell 编写迷你语言,“while”语句和块的麻烦{}
【发布时间】:2012-10-14 14:20:22
【问题描述】:

编辑:问题部分解决,跳到底部进行更新。

我正在使用 haskell 编写一种小型语言,并且已经取得了很大进展,但是我在实现使用块的语句时遇到了麻烦,例如“{ ... }”。我已经在我的解析器文件中实现了对 If 语句的支持:

stmt = skip +++ ifstmt +++ assignment +++ whilestmt

ifstmt = symbol "if" >>
         parens expr >>= \c ->
         stmt >>= \t ->
         symbol "else" >>
         stmt >>= \e ->
         return $ If c t e

whilestmt = symbol "while" >>
            parens expr >>= \c ->
        symbol "\n" >>
        symbol "{" >>
        stmt >>= \t ->
        symbol "}" >>
        return $ While c t

expr = composite +++ atomic

在语法文件中:

class PP a where 
  pp :: Int -> a -> String

instance PP Stmt where
  pp ind (If c t e) = indent ind ++ 
                      "if (" ++ show c ++ ") \n" ++ 
                      pp (ind + 2) t ++
                      indent ind ++ "else\n" ++
                      pp (ind + 2) e
  pp ind (While c t) = indent ind ++
                   "while (" ++ show c ++") \n" ++
                   "{" ++ pp (ind + 2) t ++ "}" ++
                   indent ind

while 语句有问题,我不明白是什么。逻辑似乎是正确的,但是当我运行代码时出现以下错误:

EDIT: Fixed the first problem based on the first reply, now it is not recognizing my while statment which I assume comes from this:
exec :: Env -> Stmt -> Env
exec env (If c t e) = 
    exec env ( if eval env c == BoolLit True then t else e )
exec env (While c t) =
    exec env ( if eval env c == BoolLit True then t )

正在读取的文件如下所示:

x = 1; c = 0;
if (x < 2) c = c + 1; else ;
-- SEPARATE FILES FOR EACH
x = 1; c = 1;
while (x < 10)
{
  c = c * x;
  x = x + 1;
}
c

我试图理解错误报告,但我尝试过的方法都无法解决问题。

【问题讨论】:

    标签: haskell mini-language


    【解决方案1】:

    &gt;&gt;&gt;&gt;= 绑定比 $ 更紧密。尝试使用

    return (While c t)
    

    而不是

    return $ While c t
    

    另外,在 &gt;&gt;= 右侧的 lambda 表达式周围加上括号。

    或者只使用do-notation:

    whilestmt = do
        symbol "while"
        c <- parens expr
        symbol "\n"
        symbol "{"
        t <- stmt
        symbol "}"
        return $ While c t
    

    【讨论】:

      【解决方案2】:

      问题在于,在 Haskell 中,if 语句除了then 外,还必须有一个else。您对Whileexec 实现指定了当条件为True 时要做什么,但没有说明条件为False 时的行为。事实上,当条件为True 时,您的代码只执行一次while 循环的主体,但它应该继续执行它(并将更新线程化到环境中),直到条件变为False。所以,是这样的:

      exec env (While c t) = execWhile env c t
      
      execWhile env c t | eval env c == BoolLit True = let env' = exec t in execWhile env' c t
                        | otherwise = env
      

      【讨论】:

      • 哦,我刚刚注意到你重复了这个问题,并且已经得到了答案......
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多