parsing - Haskell:为什么在执行数据评估时不执行我的算术评估函数?
问题描述
我正在编写一种简单的语言,但遇到了一个问题,即算术表达式并不期望它们的运算符,尽管它们是在语言中定义的。从那以后我回去更简单地表达我的程序。目前,我唯一的复杂表达式是算术。我可以解析整数、字符串、布尔值和列表。它可以识别诸如“5 Add 5”之类的表达式,但只能以列表的形式“[5 Add 5]”。
由于原子的解析方式,我怀疑当它不在列表中时它不会解析。原子解析器解析布尔值,然后解析任意原子。如果将算术表达式放入字符串中,它也将被正确解析。
我不确定为什么它没有正确评估。我有一个处理算术表达式的评估函数,但是当我尝试通过命令行为其提供参数时它不起作用。当我将它加载到 GHCI 中时,我可以完美地使用它,所以我知道算术评估函数有效,但是当我给它命令行参数时,我看不出它为什么不评估。任何算术表达式只会导致表达式本身,而不是应该返回的值。
我能想到的唯一原因是,当解析表达式时,它不会被解析为算术表达式,而是被解析为列表或字符串。
data HenryVal = Integer Integer
| Bool Bool
| Atom String
| String String
| List [HenryVal]
| ABinOp ABinOp
| Ad HenryVal HenryVal
| ABinary ABinOp HenryVal HenryVal
data ABinOp = Add
| Subtract
| Multiply
| Divide
deriving (Show)
evalABinOp :: HenryVal -> ABinOp -> HenryVal -> HenryVal
evalABinOp (Integer a) Add (Integer b) = Integer (a +b)
evalABinOp (Integer a) Multiply (Integer b) = Integer (a * b)
evalABinOp (Integer a) Divide (Integer b) = Integer (a `div` b)
evalABinOp (Integer a) Subtract (Integer b) = Integer (a - b)
eval :: HenryVal -> HenryVal
eval val@(Atom _) = val
eval val@(String _) = val
eval val@(Integer _) = val
eval val@(Bool _) = val
eval (List [Atom "quote", val]) = val
eval val@(List _) = val
eval (ABinary op x y) = evalABinOp (eval x) op (eval y)
spaces :: Parser ()
spaces = skipMany1 space
parseString :: Parser HenryVal
parseString = do
char '"'
x <- many (noneOf "\"")
char '"'
return $ String x
parseList :: Parser HenryVal
parseList = liftM List $ sepBy parseExpr spaces
parseNumber :: Parser HenryVal
parseNumber = liftM (Integer . read) $ many1 digit
parseAtom :: Parser HenryVal
parseAtom = do
first <- letter
rest <- many (letter <|> digit)
let atom = first:rest
return $ case atom of
"True" -> Bool True
"False" -> Bool False
_ -> Atom atom
parseExpr :: Parser HenryVal
parseExpr = parseNumber <|>
parseAtom <|>
parseString <|>
do
_ <- char '['
x <- try parseList
_ <- char ']'
return x
readExpr :: String -> HenryVal
readExpr input = case parse parseExpr "Henry" input of
Left error -> String $ "No Match: " ++ show error
Right val -> val
main :: IO ()
main = getArgs >>= print . eval . readExpr . head
解决方案
推荐阅读
- c# - 在 ASP Net Core 5 Web Api 上启用 OPTIONS 标头的 CORS
- c - 为什么 volatile 在多线程代码中是可选的?
- python - 烧瓶重定向在 repl.it 上根本不起作用
- vue.js - 设置 Vue Bootstrap Table _rowVariant 和行边距
- r - 我是否必须创建要分配的 x 变量,以便 sapply() 可以工作?
- python - 如何调整多图(Altair)的比例并添加图例?
- rs485 - 算法校验和 crc
- c++ - 旧 C++ 代码中关键字/修饰符 _seg 的含义
- java - MotionEvent ACTION_MOVE 在某些设备上生成不准确
- python - 尝试显示行号时在 Python 中双重记录输出 - 这里有什么问题?