编辑:问题部分解决,跳到底部进行更新。
我正在使用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
我试图理解错误报告但我没有尝试解决问题。
答案 0 :(得分:4)
>>
和>>=
绑定比$
更紧密。尝试使用
return (While c t)
而不是
return $ While c t
并且,在>>=
右侧的lambda表达式周围加上括号。
或者只是使用do-notation:
whilestmt = do
symbol "while"
c <- parens expr
symbol "\n"
symbol "{"
t <- stmt
symbol "}"
return $ While c t
答案 1 :(得分:0)
问题在于,在Haskell中,除了if
之外,else
语句总是必须有then
。 exec
While
的实现指定条件为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