7

C++コードを解析しようとしています。したがって、コンテキスト依存のレクサーが必要です。C ++では、コンテキストに応じて、>>1つまたは2つのトークン(>>または)です。> >さらに複雑にするために>>=、コンテキストに関係なく常に同じであるトークンもあります。

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(上の最後から2行目)の場合、入力が。の場合はエラーになります>>

*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は、2番目のパーサーのみを試行します

p1 <|> p2

p1入力を消費せずに失敗した場合。入力">>"で、最初のもの'>'が消費された後、

string ">="

残りを消費した後に失敗する'>'ため、2番目のパーサーは使用されません。

あなたには必要だtry

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

そこでstring ">="失敗した場合、入力は消費されず、代替パーサーが使用されます。

于 2012-12-09T14:34:04.490 に答える
-1

を使用しlibclangます。すべてのC++を解析できます。どんなに一生懸命頑張ってもできません。

于 2015-03-04T20:47:11.837 に答える