5

構文エラーが発生したときに「期待されるトークン」リストを生成する既知の方法はありますか?パーサジェネレータとしてレモンを使用しています。

4

2 に答える 2

9

これはうまくいくようです:

%syntax_error { 
        int n = sizeof(yyTokenName) / sizeof(yyTokenName[0]);
        for (int i = 0; i < n; ++i) {
                int a = yy_find_shift_action(yypParser, (YYCODETYPE)i);
                if (a < YYNSTATE + YYNRULE) {
                        printf("possible token: %s\n", yyTokenName[i]);
                }
        }
}

可能なすべてのトークンを試行し、現在のパーサー状態で適用可能なトークンを出力します。

間違ったトークンが来た場合、パーサーはすぐにsyntax_errorを呼び出さないことに注意してください。ただし、後でトークンをシフトできることを期待して、スタックにあるものを減らしようとします。他に何も減らすことができず、現在のトークンをシフトできない場合にのみ、パーサーはsyntax_errorを呼び出します。削減によりパーサーの状態が変更されます。つまり、削減前に適用されていたよりも少ないトークンが表示される可能性があります。ただし、エラー報告には十分なはずです。

于 2012-10-22T11:04:18.857 に答える
1

レモンでそのようなリストを生成する直接的な方法はありません。ただし、Lemonツールのデバッグ出力と生成されたパーサーのデバッグトレースを使用して、これを試すことができます。ParseTrace関数を呼び出した後、生成されたパーサーはShiftsとReduceのリストを出力し、入力ストリームに適用します。構文エラーの前の最後のShiftには、エラーの前の現在の状態の数が含まれています。パーサーの*.outファイルでこの状態を見つけて、予想されるトークンのリストを確認してください。

于 2012-08-07T13:13:45.313 に答える