为什么Parsec不会考虑我的< |>的右侧?替代?

时间:2012-12-09 14:29:57

标签: haskell lexical-analysis parsec

我正在尝试解析C ++代码。因此,我需要一个上下文敏感的词法分析器。在C ++中,>>是一个或两个令牌(>>> >),具体取决于上下文。为了使它更复杂,还有一个令牌>>=,无论上下文如何,它都是相同的。

punctuation :: Bool -> Parser Token
punctuation expectDoubleGT = do
    c <- oneOf "{}[]#()<>%;:.+-*/^&|~!=,"
    case c of
        '>' ->
            (char '=' >> return TokGTEq) <|>
            if expectDoubleGT
                then (string ">=" >> return TokRShiftEq) <|> return TokGT
                else (char '>' >> ((char '=' >> return TokRShiftEq) <|> return TokRShift)) <|> return TokGT

expectDoubleGTFalse时,此功能正常。但是,当expectDoubleGTTrue(上面第二行)时,输入为>>时会出错。

*Parse> parseTest (punctuation True) ">"
TokGT
*Parse> parseTest (punctuation True) ">>="
TokRShiftEq
*Parse> parseTest (punctuation True) ">>"
parse error at (line 1, column 2):
unexpected end of input
expecting ">="

为什么表达式(string ">=" >> return TokRShiftEq) <|> return TokGT会引发错误,而不是在输入为TokGT时返回>? (第一个>已被消耗)

2 个答案:

答案 0 :(得分:11)

Parsec只在

中尝试第二个解析器
p1 <|> p2

如果p1失败而没有消费任何输入。在输入">>"后,在消耗了第一个'>'后,

string ">="

在使用左侧'>'后失败,因此不使用第二个解析器。

您需要try

try (string ">=" >> return TokRShiftEq)

这样如果string ">="失败,则不会消耗任何输入并使用替代解析器。

答案 1 :(得分:-1)

使用libclang。它可以解析所有的C ++。无论你怎么努力,你都无法做到。