2016-12-06 6 views
0

質問から新しい問題があります:Call a function in a Yacc file from another c file今回は、LexとYaccのyyin関数の問題に直面します。私のコードは次のとおりです。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. 私はパラメータFileInputクラスで、ファイルを開き、関数を呼び出し、それを読んで、パース()するのmain.cを作成しました。 calc.yで
  2. は、私は、パーサーは、ループおよび(test.txtという)

問題はそのyyinがなかったのである」テキストファイル内のすべての行を読み取ることができるようにFileInputクラスと同じになるようにポインタyyinを設定しますテキストのすべての行を読み上げる。私が得た結果は

= 3 

である私が取得する必要があり、結果はどのように私はこの問題を解決することができ

= 3 
= 6 
= 4 

です。 main.cを残しておきたいと思います。

+0

'exit(0)'はプログラムが正常に完了したことを意味します。{ printf( "ファイルの読み込み中にエラーが発生しました。プログラムはすぐに終了します。\"ファイルの読み込み中にエラーが発生しました。 n "); exit(0); } '? – Michi

答えて

1

これは、yyinとは関係ありません。あなたの問題はあなたの文法の一連を認識しません。 1つだけを認識します。ファイルの最初の行を解析し、最終的にステートメントに縮小したので、パーサーはそれ以上何もできません。 ステートメントで始まる一連のシンボルを他のものに縮小する方法はありません。パーサーが詰まったときにまだ入力が残っているので、エラーコードを呼び出し元に返しますが、呼び出し元はそれを無視します。

パーサーが複数のステートメントを処理できるようにするには、そのためのルールが必要です。おそらく、結果のシンボルがの文の代わりに開始シンボルになるようにしてください。これは、合理的なルールのようになります。それは改行を読み込むとき

statements: statement 
    | statements statement 
    ; 
2

あなた字句解析は0を返します。

YaccまたはBisonのすべての文法は、EOF(ファイルの終わり)を意味する0として認識します。あなたはファイルの終わりに達したとあなたの文法に言った。それはあなたを信じていた。

改行で0を返しません。John Bollingerで提案されているように、最初の文法ルールを反復する(一連のステートメントを受け入れる)必要があります。もう1つはanswerです。

関連する問題