【问题标题】:yyin doesn't read all data in a text fileyyin 不会读取文本文件中的所有数据
【发布时间】:2016-12-06 20:46:53
【问题描述】:

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

ma​​in.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) 中的所有行

问题是 yyin 没有读完文本中的所有行。我得到的结果是

= 3

我应该得到的结果是

= 3
= 6
= 4

我该如何解决这个问题。请注意,我希望 main.c 保留。

【问题讨论】:

  • exit(0) 表示您的程序已成功完成。你确定你对exit()在这里打电话if((fileInput=fopen(argv[1],"r"))==NULL) { printf("Error reading files, the program terminates immediately\n"); exit(0); }吗?

标签: c yacc lex


【解决方案1】:

这与yyin 无关。您的问题是 您的语法 无法识别一系列 语句;它只识别一个。解析了文件的第一行并最终将其简化为语句,解析器无能为力。它无法将一系列以 statement 开头的符号简化为其他任何符号。由于解析器卡住时仍有输入,它会向调用者返回一个错误代码,但调用者忽略了。

要使解析器能够处理多个语句,您需要一个规则。大概您会希望生成的符号成为开始符号,而不是 statement。这是一个合理的规则:

statements: statement
    | statements statement
    ;

【讨论】:

    【解决方案2】:

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

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

    不要为换行返回 0。您可能需要迭代您的第一个语法规则(接受一系列语句)——正如 John Bollinger 在另一个 answer 中所建议的那样。

    【讨论】:

      猜你喜欢
      • 2017-03-20
      • 1970-01-01
      • 1970-01-01
      • 2014-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-18
      • 2021-04-09
      相关资源
      最近更新 更多