Я пытаюсь разобрать набор арифметических выражений из .txt-файла. (по одному в каждой строке). Я могу получить правильную логику для первой строки, но парсер дает 0 для второго выражения. Более того, я хочу напечатать всю строку на выходе, но путаюсь с того, с чего начать.Yacc не разбирает второе выражение в txt-файле
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 %c bad %d \n",*yytext,*yytext); return '?'; }
%%
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",$1);}
;
Expr : Expr '+' Expr { $$ = $1 + $3; }
| Expr '-' Expr { $$ = $1 - $3; }
| Expr '*' Expr { $$ = $1 * $3; }
| Expr '/' Expr { if($3==0)
yyerror("Divide by Zero Encountered.");
else
$$ = $1/$3;
}
| '-' Expr { $$ = -$2; }
| Fact { $$=$1; }
;
Fact : '(' 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);
}
yyparse();
}
void yyerror(char *mesg){
printf("Bad Expression : %s\n", mesg);
}
Текстовый файл
4+3-2*(-7)
65*+/abc
9/3-2*(-5)
Out поставил
=21
Bad Expression : syntax error
Ожидаемый выход
4+3-2*(-7)=21
65*+/abc=Bad Expression : syntax error
9/3-2*(-5)=13
Даже если удалить плохое выражение из 2-й линии INT текст файла анализатор дает результата
=21
=0
вместо
=21
=13
Я попытался прочитать данные и сохранить их в переменной & отображение арифметического выражения с использованием функции обработки файлов во время цикла и использования yyparse() в цикле для сканирования по строкам. Я не могу отследить проблему, поскольку исходный код немного сложный, и я начал изучать эту вещь всего за 20 дней.
Выполнение кода с помощью команд
yacc -v -t -d calc.yacc (I am getting 22 shift/reduce conflicts.)
lex calc.lex
gcc y.tab.c lex.yy.c -lm -ll -o calc
./calc calc.txt
Части вашей проблемы может заключаться в определении 'Calc'. Вы печатаете '$ 1' оба раза. –
У вас нет правила ошибки, что затрудняет восстановление ошибок. –