Parsing Haskell:如果块计算器在GHCI中正常工作,但在通过解析表达式对其求值时却不能正常工作
我正试图为我的语言编写一个计算器,它接受一个解析的if块,计算所有条件并过滤掉假分支,然后随机选择一个分支。我正处于这样一个阶段,我可以过滤掉分支,留下我可能的路径,但只能在GHCI内。当我试图通过命令行将if块传递到程序中时,如果第一个分支为True,则会发生这种情况,这是唯一执行的分支,否则不管是否有任何分支,都会返回一个空列表。我的二进制表达式求值器工作正常,因此我知道我的错误与if求值器或解析器中的逻辑有关 以下是通过命令行执行的行为:Parsing Haskell:如果块计算器在GHCI中正常工作,但在通过解析表达式对其求值时却不能正常工作,parsing,haskell,eval,Parsing,Haskell,Eval,我正试图为我的语言编写一个计算器,它接受一个解析的if块,计算所有条件并过滤掉假分支,然后随机选择一个分支。我正处于这样一个阶段,我可以过滤掉分支,留下我可能的路径,但只能在GHCI内。当我试图通过命令行将if块传递到程序中时,如果第一个分支为True,则会发生这种情况,这是唯一执行的分支,否则不管是否有任何分支,都会返回一个空列表。我的二进制表达式求值器工作正常,因此我知道我的错误与if求值器或解析器中的逻辑有关 以下是通过命令行执行的行为: ~/Desktop/Olivia > ./M
~/Desktop/Olivia > ./Main "if (1 > 3)-> 1 + 1 [] (1 < 2)-> 2 + 2"
[]
~/Desktop/Olivia > ./Main "if (1 < 3)-> 1 + 1 [] (1 < 2)-> 2 + 2"
[2]
这是我预期的结果。对于n
sub if表达式的数量,我将选择整个列表中的一个列表作为我的分支,然后再回去评估循环保护并开始程序的下一次迭代
我的数据类型:
data HVal
= HInteger Integer
| HBool Bool
| HString String
| HList [HVal]
| Expr HVal Op HVal
| EqExpr HVal Op HVal
| Neg HVal
| Assign HVal HVal
| Do HVal [HVal]
| If HVal [HVal] [HVal]
| SubIf HVal [HVal]
| Load String
deriving (Eq, Read)
我的解析器:
parseIf :: Parser HVal
parseIf = do
_ <- string "if"
spaces
_ <- string "("
cond <- (parseExpr <|> parseEqExpr <|> parseBool)
_ <- string ")->"
expr <- spaces *> many (parseExpression <* spaces)
expr' <- spaces *> many (parseExpression <* spaces)
return $ If cond expr expr'
parseSubIf :: Parser HVal
parseSubIf = do
_ <- string "[]"
spaces
_ <- string "("
cond <- (parseExpr <|> parseEqExpr <|> parseBool)
_ <- string ")->"
expr <- spaces *> many (parseExpression <* spaces)
return $ SubIf cond expr
我认为错误可能与if块的解析器有关。我的想法是,if块包含第一个分支的条件及其计算结果,然后是一个子表达式列表,其中列表的每个元素都包含分支条件及其计算结果。听起来您需要自己测试解析器,在ghci中或通过在编译的程序中打印解析结果。您可能需要为HVal导出
Show
,以便可以打印它。expr many(parseExpression@chi Many的使用使得一个分支可能包含多个表达式,如果其条件为真。这就是为什么if
采用列表。第一个列表指可能的表达式。如果第一个分支的条件为真,那么第二个列表是包含if语句的下一个n
分支的列表
parseIf :: Parser HVal
parseIf = do
_ <- string "if"
spaces
_ <- string "("
cond <- (parseExpr <|> parseEqExpr <|> parseBool)
_ <- string ")->"
expr <- spaces *> many (parseExpression <* spaces)
expr' <- spaces *> many (parseExpression <* spaces)
return $ If cond expr expr'
parseSubIf :: Parser HVal
parseSubIf = do
_ <- string "[]"
spaces
_ <- string "("
cond <- (parseExpr <|> parseEqExpr <|> parseBool)
_ <- string ")->"
expr <- spaces *> many (parseExpression <* spaces)
return $ SubIf cond expr
eval :: HVal -> HVal
---------- EVALUATING PRIMITIVES ----------
eval val@(HString _) = val
eval val@(HInteger _) = val
eval val@(HBool _) = val
eval val@(HList _) = val
eval (Expr x op y) = evalExpr x op y
eval (If cond expr expr') = evalIf cond expr expr'
eval (SubIf cond expr) = evalSubIf cond expr
evalIf :: HVal -> [HVal] -> [HVal] -> HVal
evalIf cond expr expr' = if ((eval cond) == (HBool True))
then HList $ map eval expr
else HList $ (filter (/= (HInteger 1)) (map eval expr'))
evalSubIf :: HVal -> [HVal] -> HVal
evalSubIf cond expr = if ((eval cond) == (HBool True))
then HList $ map eval expr
else (HInteger 1)