我试图为两个运算符创建一个表达式解析器,其中只有^
是后缀一元,所以使用操作数它看起来像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"
答案 0 :(得分:1)
无法解析,例如"R^;S"
因为postfix "^" Conv
notFollowedBy (oneOf opChar)
失败,因此'^'
后跟';'
)。解决方法是从';'
中删除opChar
:
opChar = "^"
或者,如果您可以使用reservedOp
中的haskell
:
reservedOp2 = P.reservedOp haskell
这些更改都会修复示例的解析。