一元运算符的表达式解析器

时间:2015-08-14 03:43:58

标签: parsing haskell parsec

我试图为两个运算符创建一个表达式解析器,其中只有^是后缀一元,所以使用操作数它看起来像R^

问题在于,每当遇到操作符^而不是结尾时,它就会停在那里并返回成功解析的任何内容。这意味着"R;S;T^"成功解析,但"R^;S;T^"R处停止。但是,"(R^);S;T^"工作正常。

我从他用于一元减号的在线帖子中获得了帮助,但这是一个前缀运算符(例如-X)。他最初的解决方案是在reservedOp2给出错误,因此我将其修改为reservedOp2 name = try (string name >> notFollowedBy (oneOf opChar))并产生上述输出。我需要它使用或不使用括号。

import Control.Applicative
import Text.ParserCombinators.Parsec hiding (many,optinal,(<|>))
import Text.ParserCombinators.Parsec.Expr
import Text.Parsec.Language (haskell)
import qualified Text.Parsec.Token as P
import Text.Parsec.String (Parser)

data RT = Comp RT RT        
        | Conv RT           
        | Var String
        deriving (Show)

whiteSpace = P.whiteSpace haskell
word = P.identifier haskell
parens = P.parens haskell
opChar = "^;"

reservedOp2 :: String -> CharParser st ()
reservedOp2 name = try (string name >> notFollowedBy (oneOf opChar) >> whiteSpace)


term = parens relexpr
       <|> Var <$> word
       <?> "term"

table = [ [postfix "^" Conv]
        , [binary ";" Comp AssocLeft]
        ]

prefix  name fun = Prefix  $ reservedOp2 name >> return fun
binary  name fun = Infix   $ reservedOp2 name >> return fun
postfix name fun = Postfix $ reservedOp2 name >> return fun

relexpr :: Parser RT
relexpr = buildExpressionParser table term <?> "expression"

1 个答案:

答案 0 :(得分:1)

无法解析,例如"R^;S"因为postfix "^" Conv notFollowedBy (oneOf opChar)失败,因此'^' 后跟';')。解决方法是从';'中删除opChar

opChar = "^"

或者,如果您可以使用reservedOp中的haskell

,则会更加轻松
reservedOp2 = P.reservedOp haskell

这些更改都会修复示例的解析。

相关问题