0

flex と bison を使ってパーサーを書こうとしています。しかし、どのようにファイルを変更しても、「1 行目の構文エラー」というエラーが常に表示されます。これは、yyinput の test.vm ファイルです。

$asfdfsdf
sdfsdfs
sdfsdfsd
sdfsdfsd
sfsdfd

これは vtl4.l ファイルです。

%{
#include<stdio.h>
#include<string.h>
#include "context.h"
#include "bool.h"
#include "vtl4.tab.h"
%}
%%
(.|\n)* {yylval.string = yytext;return CONTENT;}
<<EOF>> {return FINAL;}
%%

これは vtl4.y ファイルです。

%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bool.h"
#include "parser.h"
#include "context.h"
#include "vtl4.tab.h"

extern FILE * yyin;
extern FILE * yyout;
extern int yylex();
extern int yywrap();
%}

%union {
struct simpleNode *ast;
double d;
int i;
bool b;
char* string;
struct symbol *sym;
}

%type <ast> root stmts stmt

%token <string> CONTENT

%token FINAL

%%

root:stmts FINAL {printf("root\n");$$ = process($1);traverse($$);}
;

stmts: {printf("stmts:stmt\n");$$ = 0;}
|stmts stmt {printf("stmts:stmts stmt\n");$$ = add_ybrother($1,$2);}
;

stmt:CONTENT {printf("stmt\n");$$ = text($1);}
;

%%
int main(){
FILE *src;
src = fopen("test.vm","r");
yyin = src;
yyparse();
fclose(src);
return 1;
}

int yywrap(){
return 1;
}

メイクファイル:

CC=cc

FLEX=vtl4.l

BISON=vtl4.y

parse:vtl4.tab.c lex.yy.c
       $(CC) -o out *.c -ll


vtl4.tab.c:$(BISON)
      bison -d $(BISON) --report=all

lex.yy.c:$(FLEX)
        flex $(FLEX)

./out を実行すると、正しい結果が表示されますが、最終的には常に「line:1: error: syntax error」と表示されます!理由がわかりません。

lex ルールを編集するとうまくいきます

<<EOF>> {return FINAL;}

<<EOF>> {yyterminate();}

yacc ルールを変更します。

root:stmts FINAL {printf("root\n");$$ = process($1);traverse($$);}

root:stmts {printf("root\n");$$ = process($1);traverse($$);}

しかし、私は理由を知りませんか?

4

1 に答える 1

2

ルールでを使用するreturn FINALと、トークナイザーはファイルの終わりに<<EOF>>戻り続けます。FINALwhenflexを と組み合わせてbison使用​​する場合は、明示的なファイル終了トークンを使用する必要はありません (使用すべきではありません)。1 を返すyylex場合、ファイルの終わりで返される 0 に頼るだけです。yywrapyyterminate

この場合、文法はFINAL処理できないトークンの無限の流れに直面します。もちろん、このエンドレス ストリームを文法に組み込むべきではありません。これは、文法が「正しい」ものになりますが、終了することはないからです。

トークナイザーが 1 つのトークンで完全なファイルと一致することを認識していると思いますCONTENT。そのため、文法がCONTENTトークンのリストをサポートしていても、常に 1 つしか表示されません。

PS:デバッグ トレースをパーサーに追加する-tオプションを使用して問題を発見しました。bisonFINAL

P.S2:のコンパイラ呼び出しでMakefile使用した. いくつかのランダムなファイルがディレクトリにぶら下がっている可能性があるため、これは非常に危険です。ルールが依存するすべてのファイルを参照するために使用することをお勧めします。*.cparse.c$^

P.S3: 独自に定義したため、. を失う可能性がありyywrapます。main-ll

于 2013-03-25T22:06:25.427 に答える