yyin不读取文本文件中的所有数据

时间:2016-12-06 20:46:53

标签: c yacc lex

我从这个问题中遇到了一个新问题: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

这就是我的代码的工作方式:

  1. 我创建了main.c来打开一个文件并读取它然后使用参数fileInput调用一个函数parse()。
  2. 在calc.y中,我将指针yyin设置为与fileInput相同,因此解析器可以循环并读取文本文件中的所有行(test.txt)
  3. 问题是yyin没有阅读文中的所有行。我得到的结果是

    = 3
    

    我应该得到的结果是

    = 3
    = 6
    = 4
    

    我怎么能解决这个问题。请注意,我希望main.c保留。

2 个答案:

答案 0 :(得分:2)

您的词法分析器在读取换行符时返回CTR

来自Yacc或Bison的所有语法都认为0表示EOF(文件结尾)。你告诉你的语法你已经到了文件的末尾;它相信你。

换行时不要返回0。你可能需要让你的第一个语法规则迭代(接受一系列语句) - 正如John Bollinger在另一个answer中的建议。

答案 1 :(得分:1)

这与yyin无关。您的问题是您的语法无法识别一系列语句;它只识别一个。在解析了文件的第一行并最终将其缩减为语句后,解析器就无法做到。它无法将从语句开始的一系列符号缩减为其他任何符号。由于解析器加密时仍有输入,它会向其调用者返回一个错误代码,但调用者会忽略它。

要使解析器能够处理多个语句,您需要一个规则。据推测,您希望生成的符号是起始符号,而不是语句。这是一个合理的规则:

statements: statement
    | statements statement
    ;
相关问题