1

エラーの行番号と列番号を取得する方法 (つまり、文字列のどの部分が文法規則に従っていないか)? yacc パーサーを使用して文法をチェックしています。ありがとうございました。

4

1 に答える 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 に答える