2017-02-14 9 views
0

私はテキストファイルとその結果から算術式全体を表示しようとしていますが、ファイル処理オプションで試しましたが、動作しません。YACC文法で入力テキストをエコーする方法は?

YACC:

%{ 
#include <stdio.h> 
#include <string.h> 
#define YYSTYPE int /* the attribute type for Yacc's stack */ 
extern int yylval;  /* defined by lex, holds attrib of cur token */ 
extern char yytext[]; /* defined by lex and holds most recent token */ 
extern FILE * yyin; /* defined by lex; lex reads from this file */ 
%} 

%token NUM 

%% 

Calc : Expr    {printf(" = %d\n",$1);} 
    | Calc Expr   {printf(" = %d\n",$2);} 
    | Calc error   {yyerror("\n");} 
    ; 
Expr : Term    { $$ = $1;   } 
    | Expr '+' Term  { $$ = $1 + $3; } 
    | Expr '-' Term  { $$ = $1 - $3; } 
    ; 
Term : Fact    { $$ = $1;   } 
    | Term '*' Fact  { $$ = $1 * $3; } 
    | Term '/' Fact  { if($3==0){ 
       yyerror("Divide by Zero Encountered."); 
      break;} 
       else 
       $$ = $1/$3;  
        } 
    ; 
Fact : Prim    { $$ = $1;  } 
    | '-' Prim   { $$ = -$2;  } 
    ;  
Prim : '(' Expr ')'  { $$ = $2;  } 
    | Id     { $$ = $1;  } 
    ; 
Id :NUM     { $$ = yylval; } 
    ; 
%% 

void yyerror(char *mesg); /* this one is required by YACC */ 

main(int argc, char* *argv){ 
char ch,c; 
FILE *f;  
if(argc != 2) {printf("useage: calc filename \n"); exit(1);} 
if(!(yyin = fopen(argv[1],"r"))){ 
     printf("cannot open file\n");exit(1); 
} 
/* 
f=fopen(argv[1],"r"); 
if(f!=NULL){ 
char line[1000]; 
while(fgets(line,sizeof(line),f)!=NULL) 
    { 
      fprintf(stdout,"%s",line); 
     yyparse(); 
    } 

} 
*/ 
yyparse(); 
} 

void yyerror(char *mesg){ 
printf("\n%s", mesg); 
} 

LEX

%{ 
#include <stdio.h> 
#include "y.tab.h" 
int yylval; /*declared extern by yacc code. used to pass info to yacc*/ 
%} 

letter [A-Za-z] 
digit ([0-9])* 
op  "+"|"*"|"("|")"|"/"|"-" 
ws  [ \t\n\r]+$ 
other . 

%% 

{ws} { /*Nothing*/ } 
{digit} { yylval = atoi(yytext); return NUM;} 
{op} { return yytext[0];} 
{other} { printf("bad%cbad%d\n",*yytext,*yytext); return '?'; } 

%% 

マイテキストファイルには、これら2つの式を含んでいます

4+3-2*(-7) 
9/3-2*(-5) 

私のように出力したい:

4+3-2*(-7)=21 
9/3-2*(-5)=13 

しかし、出力は次のとおりです。

=21 
=13 

パーサはので、この(コメントコード)を使用する合法的ではありません一度にすべての計算を行いますので。ですから、入力文を文法に渡して表示し、Calcブロックに印刷する必要があります。私は文法の入力を表示することについてGoogleに関連する何かを見つけることができません。コメント&の提案について事前に感謝します。

+0

あなたはどのように動作していないかは言いません。私たちに手がかりを与えてください。 –

+0

9/3-2 *( - 5)= 13のような出力が必要ですが、文法が出力をフェッチする場合にのみ可能です。 –

+0

まだ役に立ちません。あなたは、Googleに関係するものは何も見つけられていないと言います。あなたは何と考えていますか?あなたは何を探しましたか?ここでコメントするのではなく、詳細をあなたの質問に更新してください。 –

答えて

0

これは文法では行いません。あまりにも複雑で文法がどんな再編成をしてもかまいません。レクサーでそれを行うことを検討することができます。つまり、空白のアクション以外のすべてのアクションで、返す直前にyytextを印刷することが考えられますが、すべての入力が読み込まれたときにエコーします。lex(1)の入力関数。

NBあなたはフレックス(1)、ないLEX(​​1)を使用しなければならない、とあなたが変更した場合yyyextなくなるがchar[]char *になっている、ということに注意してください。

私はあなたの前に質問が、このルールではそれを言及しませんでした:

{other} { printf("bad%cbad%d\n",*yytext,*yytext); return '?'; } 

は、より良いように記述することになります。

{other} { return yytext[0]; } 

パーサはそれを見ると、構文が生成されますその方法エラーが発生したため、何も印刷する必要はありません。この技術では、個々の特殊文字の規則を取り除くこともできます。+,-=*,/,(,)、パーサーはyytext[0]で認識します。

0

最後に、私はそれを得た:

YACC

%{ 
#include <stdio.h> 
#include <string.h> 
#define YYSTYPE int /* the attribute type for Yacc's stack */ 
extern int yylval; /* defined by lex, holds attrib of cur token */ 
extern char yytext[]; /* defined by lex and holds most recent token */ 
extern FILE *  yyin; /* defined by lex; lex reads from this 
file */ %} 

%token NUM 

%% 

Calc : Expr    {printf(" = %d\n",$1);} 
    | Calc Expr   {printf(" = %d\n",$2);} 
    | error    {yyerror("Bad Expression\n");} 
    ; 

Expr : Term    { $$ = $1;   } 
    | Expr Add Term  { $$ = $1 + $3; } 
    | Expr Sub Term  { $$ = $1 - $3; } 
    ; 
Term : Fact    { $$ = $1;   } 
    | Term Mul Fact  { $$ = $1 * $3; } 
    | Term Div Fact  { if($3==0){ 
       yyerror("Divide by Zero Encountered."); 
      break;} 
       else 
       $$ = $1/$3; 
        } 
    ; 
Fact : Prim    { $$ = $1;  } 
    | '-' Prim   { $$ = -$2;  } 
    ;  
Prim : LP Expr RP   { $$ = $2;  } 
    | Id     { $$ = $1;  } 
    ; 
Id :NUM     { $$ = yylval; printf("%d",yylval); } 
    ; 
Add : '+' {printf("+");} 
Sub : '-' {printf("-");} 
Mul : '*' {printf("*");} 
Div : '/' {printf("/");} 
LP : '(' {printf("(");} 
RP : ')' {printf(")");} 

%% 

void yyerror(char *mesg); /* this one is required by YACC */ 

main(int argc, char* *argv){ 
char ch,c; 
FILE *f;  
if(argc != 2) {printf("useage: calc filename \n"); exit(1);} 
if(!(yyin = fopen(argv[1],"r"))){ 
     printf("cannot open file\n");exit(1); 
} 
yyparse(); 
} 

void yyerror(char *mesg){ 
printf("%s ", mesg); 
} 

おかげEJP & EMACSユーザーが応答するため。

関連する問題