4

私はflex2.5.35とbison2.7を使用しています(これはflexの問題ですが、私は信じているので、parser.yを省略しました)

私のFlex文法は非常に単純です:

lexer.l

%{
#define YY_NO_INPUT
#include "parser.h"

#define YY_USER_ACTION yylloc->first_line = yylloc->last_line = yylineno; \
    yylloc->first_column = yycolumn; yylloc->last_column = yycolumn + (int)yyleng - 1; \
    yycolumn += (int)yyleng;

%}

%option yylineno
%option outfile="lexer.c" header-file="lexer.h"
%option warn
%option reentrant noyywrap never-interactive nounistd
%option nounput
%option bison-bridge
%option bison-locations

%%

[ \n\r\t]*               { /* Skip blanks. */ }
[A-Za-z0-9_\-@]+       { yylval->value = strdup(yytext); return TOKEN_VAR; }
"&&"                   { return TOKEN_AND; }
"||"                   { return TOKEN_OR; }
"!"                    { return TOKEN_NOT; }
"("                    { return TOKEN_LPAREN; }
")"                    { return TOKEN_RPAREN; }

%%

文字列をスキャンしたとき、行番号と列番号の値は初期化されていないガベージでした。コードをトレースし、生成されたlexer.cのyy_scan_bufferに次の行を追加しました。

b->yy_bs_lineno = 1;
b->yy_bs_column = 1;

これで、値は期待どおりになりました。

これはバグですか?yy_create_bufferこれらのフィールドを正しく初期化しますが、そうでyy_scan_bufferはありません。

%option yylineno文字列を解析するときに使用できませんか?

回避策はありますか、それとも生成されたlexer.cを本当に変更する必要がありますか?

4

2 に答える 2

3

はい、これはバイソンの問題であることを確認できます。たまたま、「コンパイラ関数」で初期化して修正しました

void myParseFunction(const char* code, ...){
    yyscan_t myscanner;
    yylex_init(&myscanner);
    struct yyguts_t * yyg = (struct yyguts_t*)myscanner;

    yy_delete_buffer(YY_CURRENT_BUFFER,myscanner);
    yy_scan_string(code, myscanner);

    // [HACK] Those are not properly initialized for non file parsers
    // and becuase of that we get garbage in yyerror...
    yylineno = 1;
    yycolumn = 0;

    bool nasi = yyparse(myscanner, <your_args>);
        yylex_destroy(myscanner);
        return nasi;
}

yylineno と yycolumn は、"yyg" を参照するマルコとして定義されているため、再入可能パーサーでうまく機能することに注意してください。

于 2016-04-30T20:15:32.740 に答える
1

oreilly本の「レクサーへの場所の追加」の部分からYY_USER_ACTIONコードを適切にコピーしました

int yycolumn = 1;リンクのコード例で行われているように、YY_USER_ACTIONの定義の前に追加するのを忘れたと思います。

于 2013-02-10T14:15:25.117 に答える