我正在尝试解析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
时,此功能正常。但是,当expectDoubleGT
为True
(上面第二行)时,输入为>>
时会出错。
*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
时返回>
? (第一个>
已被消耗)
答案 0 :(得分:11)
Parsec只在
中尝试第二个解析器p1 <|> p2
如果p1
失败而没有消费任何输入。在输入">>"
后,在消耗了第一个'>'
后,
string ">="
在使用左侧'>'
后失败,因此不使用第二个解析器。
您需要try
try (string ">=" >> return TokRShiftEq)
这样如果string ">="
失败,则不会消耗任何输入并使用替代解析器。
答案 1 :(得分:-1)
使用libclang
。它可以解析所有的C ++。无论你怎么努力,你都无法做到。