我正在做一个使用flex和bison编写复杂数字计算器的作业。但我的程序无法给出正确的输出。
.lex文件:
%option noyywrap
%{
#include<stdio.h>
#include<stdlib.h>
#include "complex_cal.h"
#define YYSTYPE complex
#include "complex_cal.tab.h"
void RmWs(char* str);
%}
/* Add your Flex definitions here */
/* Some definitions are already provided to you*/
ws [ \t]+
digits [0-9]
number (0|[1-9]+{digits}*)\.?{digits}*
im [i]
complexnum {ws}*[-]*{ws}*{number}{ws}*[+|-]{ws}*{number}{ws}*{im}{ws}*
op [-+*/()]
%%
{complexnum} {RmWs(yytext); sscanf(yytext,"%lf %lf",&(yylval.real),&(yylval.img)); return CNUMBER;}
{ws} /**/
{op} return *yytext;
%%
/* function provided to student to remove */
/* all the whitespaces from a string. */
void RmWs(char* str){
int i=0,j=0;
char temp[strlen(str)+1];
strcpy(temp,str);
while (temp[i]!='\0'){
while (temp[i]==' '){i++;}
str[j]=temp[i];
i++; j++;
}
str[j]='\0';
}
.y档案:
%{
#include <stdio.h>
#include <stdlib.h>
#include "complex_cal.h"
/* prototypes of the provided functions */
complex complex_add (complex, complex);
complex complex_sub (complex, complex);
complex complex_mul (complex, complex);
complex complex_div (complex, complex);
/* prototypes of the provided functions */
int yylex(void);
int yyerror(const char*);
%}
%token CNUMBER
%left '+' '-'
%left '*' '/'
%nonassoc '(' ')'
%%
/* start: Add your grammar rules and actions here */
complexexp: complexexp '+' complexexpmultidiv {$$=complex_add($1, $3);}
| complexexp '-' complexexpmultidiv {$$=complex_sub($1, $3);}
| complexexpmultidiv {$$.real=$1.real;$$.img=$1.img;}
;
complexexpmultidiv: complexexpmultidiv '*' complexsimple {$$=complex_mul($1, $3);}
| complexexpmultidiv '/' complexsimple {$$=complex_div($1, $3);}
| complexsimple {$$.real=$1.real;$$.img=$1.img;}
;
complexsimple: '(' complexexp ')' {$$.real=$2.real;$$.img=$2.img;}
| '(' CNUMBER ')' {$$.real=$2.real;$$.img=$2.img;}
;
/* end: Add your grammar rules and actions here */
%%
int main(){ return yyparse(); }
int yyerror(const char* s){
printf("%s\n", s);
return 0;
}
/* function provided to do complex addition */
/* input : complex numbers c1, c2 */
/* output: nothing */
/* side effect : none */
/* return value: result of addition in c3 */
complex complex_add (complex c1, complex c2){
/* c1 + c2 */
complex c3;
c3.real = c1.real + c2.real;
c3.img = c1.img + c2.img;
return c3;
}
/* function provided to do complex subtraction */
/* input : complex numbers c1, c2 */
/* output: nothing */
/* side effect : none */
/* return value: result of subtraction in c3 */
complex complex_sub (complex c1, complex c2){
/* c1 - c2 */
complex c3;
c3.real = c1.real - c2.real;
c3.img = c1.img - c2.img;
return c3;
}
/* function provided to do complex multiplication */
/* input : complex numbers c1, c2 */
/* output: nothing */
/* side effect : none */
/* return value: result of multiplication in c3 */
complex complex_mul (complex c1, complex c2){
/* c1 * c2 */
complex c3;
c3.real = c1.real*c2.real - c1.img*c2.img;
c3.img = c1.img*c2.real + c1.real*c2.img;
return c3;
}
/* function provided to do complex division */
/* input : complex numbers c1, c2 */
/* output: nothing */
/* side effect : none */
/* return value: result of c1/c2 in c3 */
complex complex_div (complex c1, complex c2){
/* c1 / c2 (i.e. c1 divided by c2 ) */
complex c3;
double d;
/*divisor calculation using the conjugate of c2*/
d = c2.real*c2.real + c2.img*c2.img;
c3.real = (c1.real*c2.real + c1.img*c2.img)/d;
c3.img = (c1.img*c2.real - c1.real*c2.img)/d;
return c3;
}
.h文件:
#include <string.h>
/* struct for holding a complex number */
typedef struct {
double real;
double img;
} complex;
/* define the return type of FLEX */
#define YYSTYPE complex
编译文件的脚本:
bison -d -v complex_cal.y
flex -ocomplex_cal.lex.yy.c complex_cal.lex
gcc -o complex_cal complex_cal.lex.yy.c complex_cal.tab.c
./complex_cal
该程序的一些正确的样本运行:
输入:(5 + 6I)*(6 + 1i)中
输出:24.000000 + 41.000000i
输入:(7 + 8I)/( - 3-4i)*(5 + 7I)
输出:-11.720000-14.040000i
输入:(7 + 8I)/(( - 3-4i)*(5 + 7I))
输出:-0.128108 + 0.211351i
但是当我运行这个程序时,程序只给出一个与我的输入相同的输出。例如,当我输入(5 + 6i)(6 + 1i)时,它只给出(5 + 6i)(6 + 1i)。即使我输入任何其他东西,例如,输入“abc”它只给出“abc”并且不是语法错误。我不知道问题出在哪里,我希望知道如何解决它。
答案 0 :(得分:1)
回声来自于输入与任何lex规则都不匹配。通常,您希望在所有其他lex规则之后有一个终端“错误”lex规则:
. { fprintf(stderr, "Unexpected input character '%c', ignoring\n", *yytext; }
添加后,您应该开始看到有关意外输入字符的消息。如果这些消息看起来是错误的(例如,它看起来像你应该将这些字符识别为complexnum或其他标记的一部分),那么这意味着你的其他标记的正则表达式是错误的。
要调试语法,请使用标志-DYYDEBUG
进行编译(在任何源文件之前将其添加到脚本的gcc
行),然后设置YYDEBUG
env var在运行你的程序时(输入命令YYDEBUG=1 ./complex_cal
。)这将导致你的野牛生成的解析器打印出有关它获得的标记,它转移到的状态以及它正在减少的规则的各种消息。通过完成这些工作并查看正在发生的意外事件,您应该能够使用语法调试任何问题。
答案 1 :(得分:0)
宣告:
complex result;
添加到规则的顶部:
s: complexexep { result = $1; YYACCEPT; }
进入main()函数:
if (yyparse() == 0)
printf("(%lf, %lf)\n", result.real, result.img);
else
printf("Error!\n");
并添加到lex文件(作为最后一条规则):
. { return (yytext[0]); };
答案 2 :(得分:0)
输出实际上并不重复您输入的所有内容。相反,它删除所有空格。例如,'a b c'将输出'abc'。