我的目标是使用Text.ParserCombinators.ReadP在Haskell中构建计算器,该函数实现+, - ,*,/,^以及否定,并遵循PEMDAS。首先,我必须解析一个字符串输入到数学表达式(MathExp
)。我有部分代码如下:读取括号和否定
import Control.Applicative hiding (many)
import Control.Monad
import Data.Char
import Data.List
import Data.Ord
import Text.ParserCombinators.Readp
type Name = String
type Number = Int
data MathExp
= Number Number
| Neg MathExp
| Plus MathExp MathExp
| Minus MathExp MathExp
| Mult MathExp MathExp
| Div MathExp MathExp
| Pow MathExp MathExp
| Var String
deriving (Eq, Show)
parseNumber :: ReadP MathExp
parseNumber = do
skipSpaces
x <- munch1 isDigit
return (Number (read x :: Int))
parsePlus :: ReadP (MathExp -> MathExp -> MathExp)
parsePlus = do
x <- char '+'
return Plus
parseMinus :: ReadP (MathExp -> MathExp -> MathExp)
parseMinus = do
skipSpaces
x <- char '-'
return Minus
parsePlusMinus = choice [parsePlus, parseMinus] --parse both--
parseMult :: ReadP (MathExp -> MathExp -> MathExp)
parseMult = do
x <- char '*'
return Mult
parseDiv :: ReadP (MathExp -> MathExp -> MathExp)
parseDiv = do
x <- char '/'
return Div
parseMultDiv = choice [parseMult, parseDiv] --parse both M,D--
parsePow :: ReadP (MathExp -> MathExp -> MathExp)
parsePow = do
x <- char '^'
return Pow
parseNeg :: ReadP MathExp
parseNeg = undefined
parseParens = undefined
我没有问题,结合我目前拥有的解析器,使用chainl1
和chainr1
,实施正确的顺序结合性和优先级,但是我不知道如何正确实施否定和括号。
我知道如果否定符号也是-
符号,它可以在整数,括号或变量(字母串)之前出现。变量是计算器的另一部分(我没有麻烦)。此外,否定可以包括空白;例如1+2* - 3
是该计算器的有效字符串输入。
“PEMDAS” 是不是一个真正的字。你的意思是“操作顺序”? – dfeuer
是的,操作顺序。 – Harambe17
Hello CS 161通过搜索发现此页的学生,1.不要在线发布作业。 2.不要依靠SO贡献者为你做功课。如果遇到麻烦,请在Piazza上张贴。这就是我们使用它的原因。并熟悉协作政策:http://cmsc-16100.cs.uchicago.edu/2017/policies.php我们期待您提交的任何解决方案能够展示与作业的原创互动。如果您有任何问题,请给我们发邮件。和平,你的教师 –