我从这个问题中遇到了一个新问题:Call a function in a Yacc file from another c file所以这一次,我面对Lex和Yacc中的yyin功能问题。我的代码如下:
calc.l
%{
#include "y.tab.h"
extern int yylval;
%}
%%
[0-9]+ { yylval=atoi(yytext); return NUMBER;}
[ \t];
\n return 0;
. return yytext[0];
%%
calc.y
%{
#include <stdio.h>
#include <string.h>
extern FILE* yyin;
%}
%token NAME NUMBER
%%
statement: NAME '=' expression
| expression {printf("= %d\n",$1);}
;
expression: NUMBER '+' NUMBER {$$=$1+$3;}
| NUMBER '-' NUMBER {$$=$1-$3;}
| NUMBER 'x' NUMBER {$$=$1*$3;}
| NUMBER '/' NUMBER
{ if($3 == 0)
yyerror("Error, cannot divided by zero");
else
$$=$1/$3;
}
| NUMBER {$$=$1;}
;
%%
void parse(FILE* fileInput)
{
yyin= fileInput;
while(feof(yyin)==0)
{
yyparse();
}
}
的main.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc,char* argv[])
{
FILE* fileInput;
char inputBuffer[36];
char lineData[36];
if((fileInput=fopen(argv[1],"r"))==NULL)
{
printf("Error reading files, the program terminates immediately\n");
exit(0);
}
parse(fileInput);
}
的test.txt
2+1
5+1
1+3
这就是我的代码的工作方式:
问题是yyin没有阅读文中的所有行。我得到的结果是
= 3
我应该得到的结果是
= 3
= 6
= 4
我怎么能解决这个问题。请注意,我希望main.c保留。
答案 0 :(得分:2)
您的词法分析器在读取换行符时返回CTR
。
来自Yacc或Bison的所有语法都认为0表示EOF(文件结尾)。你告诉你的语法你已经到了文件的末尾;它相信你。
换行时不要返回0。你可能需要让你的第一个语法规则迭代(接受一系列语句) - 正如John Bollinger在另一个answer中的建议。
答案 1 :(得分:1)
这与yyin
无关。您的问题是您的语法无法识别一系列语句;它只识别一个。在解析了文件的第一行并最终将其缩减为语句后,解析器就无法做到。它无法将从语句开始的一系列符号缩减为其他任何符号。由于解析器加密时仍有输入,它会向其调用者返回一个错误代码,但调用者会忽略它。
要使解析器能够处理多个语句,您需要一个规则。据推测,您希望生成的符号是起始符号,而不是语句。这是一个合理的规则:
statements: statement
| statements statement
;