スキャナーが失敗したときに列番号を取得できるように、列番号を設定しようとしています。
[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