エラーの行番号と列番号を取得する方法 (つまり、文字列のどの部分が文法規則に従っていないか)? yacc パーサーを使用して文法をチェックしています。ありがとうございました。
1797 次
1 に答える
1
lex/yacc ベースのコンパイラーの書き方を説明し、例を示している Dragon book と aho book を読んだほうがよいでしょう。
エラーの行/列を取得するには、レクサーに列と行を保持させる必要があります。したがって、レクサーでは、2 つのグローバルを宣言する必要がありますSourceLine
(SourceCol
もちろん、キャメル ケースを使用しないより適切な名前を使用することもできます)。
各トークン生成では、生成されたトークンの列を計算する必要があります。そのために、次のようにマクロを使用します。
#define Return(a, b, c) \
{\
SourceCol = (SourceCol + yyleng) * c; \
DPRINT ("## Source line: %d, returned token: "a".\n", SourceLine); \
return b; \
}
そのマクロを使用したトークンの生成は次のとおりです。
"for" { Return("FOR", FOR, 1);
次に、行を保持するために、新しい行を作成するトークンごとに、次を使用しています。
{NEWLINES} {
BEGIN(INITIAL);
SourceLine += yyleng;
Return("LINE", LINE, 0);
}
次に、パーサーで取得できます。これらを extern グローバルとして宣言するSourceCol
と、次のようになります。SourceLine
extern unsigned int SourceCol;
extern unsigned int SourceLine;
文法の生成ではparse_error
、次のことができます。
parse_error : LEXERROR
{
printf("OMG! Your code sucks at line %u and col %u!", SourceLine, SourceCol);
}
もちろん、 を追加しyytext
たり、より詳細なエラー メッセージを処理したりすることもできます。しかし、すべてはあなた次第です。
于 2013-06-05T12:49:05.317 に答える