我有一臺掃描儀,解析器和主從創建通過的Flex /野牛EOF傳播VS文件
bison -d parser.y; flex scanner.l; gcc main.c parer.tab.c lex.yy.c
可執行當我運行./a.out
是我想要做什麼:如果Ctrl+D
被按下EOF
被檢測到並且main
可以相應地起作用。這意味着:如果yyin
是stdin
那麼命中Return
就結束該行的解析並且主循環等待下一個輸入行。按Ctrl+D
結束主循環中break
的解析輸入並退出。如果輸入來自文件,則e,g,testFile
該文件可以包含1個要解析的表達式,直到EOF。在文件場景中,新行應該像空格和製表符一樣被吃掉。當輸入來自stdin
時,所有這些行爲應該像解釋器一樣,並且當輸入來自文件時,就像腳本評估器一樣。這種測試文件的示例內容是:test\n
。這裏沒有檢測到EOF。而且我很難理解爲什麼會這樣。換句話說,我想這個問題here的一個擴展,另外與輸入文件的工作
parser.y:
%{
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
/* stuff from flex that bison needs to know about: */
int yylex();
int yyparse();
FILE *yyin;
static int parseValue;
void yyerror(const char *s);
%}
%token TWORD
%token TEOF
%token TJUNK
%start input
%%
input: word { printf("W"); parseValue = 1; }
| eof { printf("eof"); parseValue = -11;}
| /* empty */ { printf("_"); parseValue = -1; }
| error { printf("E"); parseValue = -2; }
;
eof: TEOF
;
word: TWORD
;
%%
void yyerror(const char *s) {
printf("nope...");
}
int getWord(FILE *file) {
int err;
if (file) {
yyin = file;
} else /* error */ {
printf("file not valid");
return -3;
}
err = yyparse();
if (!err) {
return parseValue;
} else /* error */ {
printf("parse error");
return -4;
}
}
scanner.l:
%{
#include <stdio.h>
#include "parser.tab.h"
#define YYSTYPE int
int yylex();
%}
/* avoid: implicit declaration of function ‘fileno’ */
/*%option always-interactive*/
%option noyywrap
/* to avoid warning: ‘yyunput’ defined but not used */
%option nounput
/* to avoid warning: ‘input’ defined but not used */
%option noinput
%%
<<EOF>> { return TEOF; }
[ \t] { }
[\n] { if (yyin == stdin) return 0; }
[a-zA-Z][a-zA-Z0-9]* { return TWORD; }
. { return TJUNK; }
%%
的main.c:
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdbool.h>
int main(int argc, char *argv[]) {
int result = 0;
FILE *fOut = stdout, *fIn = stdin;
/* skip over program name */
++argv, --argc;
if (argc > 0) {
fIn = fopen(argv[0], "r");
}
while (true) {
fprintf(fOut, "\nTEST : ", result);
result = getWord(fIn);
if (result == -11) {
printf(" %i ", result); printf("--> EOF");
break;
}
if (result < 0) {
printf(" %i ", result); printf("--> <0");
/*continue;*/
break;
}
fprintf(fOut, " => %i", result);
}
fprintf(fOut, "\n\n done \n ");
exit(EXIT_SUCCESS);
}
我試圖根據建議重寫解析here或here,沒有太大的成功。從文件讀取輸入時,主要知道EOF的正確方法是什麼?
更新: 一項建議是,該問題可能是由於return 0;
上\n
。作爲一個快速測試,我只返回0,如果yyin == stin
但叫./a.out testFile
仍然沒有趕上EOF
。 更新2: 我這通過使用yywrap
工作。我擺脫了所有的TEOF
東西。該掃描儀具有部分:
extern int eof;
,並在年底:
int yywrap() {
eof = 1;
return 1;
}
在解析器有一個:
int eof = 0;
,並在文件中進一步下跌:
err = yyparse();
if (err != 0) return -4;
else if (eof) return -11;
else return parseValue;
如果有人能給我一個更優雅的解決方案,我會直到欣賞。 This可能是製作乾淨版本的好方法。
非常感謝,非常感謝。我會嘗試一下,看看它是如何工作的。我希望upvote你,但沒有足夠的聲譽...... – oops
我已經刪除了返回0和''\ n''但文件解析不起作用;它仍然循環。不知道如何繼續。 – oops
它應該循環(在'yyparse()'內部),直到詞法分析器返回'0'來表示輸入結束。這已經有一段時間了,但是我記得flex在返回'TEOF'標記(一次)後實際上會返回'0'。 (有幾個宏放棄解析或早期接受,但你沒有使用它們...) – torek