7

我正在尝试解析 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

expectDoubleGT什么时候False,这个函数工作正常。但是,当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>>

4

2 回答 2

11

Parsec 只尝试第二个解析器

p1 <|> p2

如果p1在不消耗任何输入的情况下失败。在输入">>"上,在第一个'>'被消耗之后,

string ">="

使用 left over 后失败'>',因此不使用第二个解析器。

你需要一个try

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

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

于 2012-12-09T14:34:04.490 回答
-1

使用libclang. 它可以解析所有的 C++。不管你怎么努力,你都做不到。

于 2015-03-04T20:47:11.837 回答