2

スキャナーが失敗したときに列番号を取得できるように、列番号を設定しようとしています。

[1] で変数をインクリメントするために使用する手法について読んだYY_USER_ACTIONので、再入可能スキャナーでも同じことができると思いましたが、代わりにスキャナーを引数として取るyyget_column/マクロを使用しました。yyset_column

私の試みはこれです(これは純粋にFlexの問題であるため、私のLemonグラマー/パーサーは含まれていません):

%{
    #include "BooleanParser.h"

    #define YY_USER_ACTION yyset_column(yyget_column(yyscanner) + yyget_leng(yyscanner), yyscanner);
%}

%option outfile="BooleanScanner.cpp" header-file="BooleanScanner.h"
%option reentrant
%option noyywrap
%option yylineno

%x DOUBLE_QUOTED

%%

[ \t]   {}

\n      { return NL; }
"||"    { return OR; }
"&&"    { return AND; }
"<"     { return LT; }
">"     { return GT; }
"="     { return EQ; }
"!="    { return NEQ; }
"("     { return LPAREN; }
")"     { return RPAREN; }
"true"  { return TRUE; }
"false" { return FALSE; }


[0-9]+            { return INT; }
[0-9]+\.[0-9]+    { return FLOAT; }
[A-Za-z_][A-Za-z0-9]*    { return ID; }

["]                     { BEGIN(DOUBLE_QUOTED); }
<DOUBLE_QUOTED>[^"]+    {}
<DOUBLE_QUOTED>["]      { BEGIN(INITIAL); return STRING; }
<DOUBLE_QUOTED><<EOF>>  { return -2; }

. { return -1; }

%%

このレクサーがこの例の入力で失敗した場合 (「"」が一致しないため、レクサーは -2 を返します)

foo = 1 && bar = 1.2 || b = "foo

次にyyget_column(myScanner)、35(入力の終わり)のようなものを期待するときに4を返します。思うように貯まらないようです。

私の質問: リエントラント スキャナーでは、現在の列番号を設定して、スキャンが失敗したときにそれを取得できるようにする正しい方法は何ですか?

事前に感謝します(レクサー/パーサージェネレーターを使用するのは初めてです)。

更新:少し近づきました。次のように、累積をデバッグするprintfために を追加しました。YY_USER_ACTION

#define YY_USER_ACTION \
    printf("yyget_column(yyscanner): %i, yyget_leng(yyscanner): %i\n", yyget_column(yyscanner), yyget_leng(yyscanner)); \
    yyset_column(yyget_column(yyscanner) + yyget_leng(yyscanner), yyscanner);

そして、上記の入力による出力は次のとおりです。

yyget_column(yyscanner): 0, yyget_leng(yyscanner): 3
yyget_column(yyscanner): 3, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 4, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 5, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 6, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 7, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 8, yyget_leng(yyscanner): 2
yyget_column(yyscanner): 10, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 11, yyget_leng(yyscanner): 3
yyget_column(yyscanner): 14, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 15, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 16, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 17, yyget_leng(yyscanner): 3
yyget_column(yyscanner): 20, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 21, yyget_leng(yyscanner): 2
yyget_column(yyscanner): 23, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 24, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 25, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 26, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 27, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 28, yyget_leng(yyscanner): 1
yyget_column(yyscanner): 0, yyget_leng(yyscanner): 4

したがって、問題なく蓄積されますが、最終的には Flex がそれを 0 にリセットするようです :( これを防ぐ/回避する方法を教えてください。失敗した後に列番号を取得することは特に興味深いことです。

[1] http://oreilly.com/linux/excerpts/9780596155971/error-reporting-recovery.html

4

1 に答える 1

2

先に進んで自分自身に答えます。「問題」は、テスト入力で発生したのは、スキャナーが引用符で囲まれた文字列内の入力の最後に予期せず到達したためです(私のルールは<<EOF>>本来のように一致しました)。当然のことながら、Flex は、累積された列番号を含めて、この時点でスキャナーをリセットします。

これは特殊なケースであり、この時点では列番号はあまり意味がないことに気付きました。他のエラー状態 (認識されない文字、-1 を返す) では問題なく動作します。

だから、私は今幸せです:)

于 2013-08-18T23:23:20.643 に答える