2013-11-10 92 views
0

我正在做一個使用flex和野牛做作業的複雜數字計算器。但是我的程序無法給出正確的輸出結果。flex和野牛:錯誤的輸出

.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.獲得+2代表和2.向其他人表明你的問題得到了滿意的答案。之後,當您的代表人數超過15人時,您可以提高您認爲「良好」的答案。 –

回答

0

聲明:本

complex result; 

添加到規則的頂部:

s: complexexep { result = $1; YYACCEPT; } 

進入你的main()函數:

if (yyparse() == 0) 
    printf("(%lf, %lf)\n", result.real, result.img); 
else 
    printf("Error!\n"); 

並加入到法文件(如最後一條規則):

. { return (yytext[0]); }; 
+0

它不起作用。它表示打印結果和打印錯誤出現錯誤。其實,是打印C語言的一個功能嗎? – Peter

+0

我的意思是將該部分作爲僞代碼。 –

+0

它不再工作。輸出與我描述的相同。 – Peter

0

輸出實際上並不重複您輸入的所有內容。相反,它會刪除所有的空格。例如,'a b c'將輸出'abc'。

1

回聲來自輸入不符合任何lex規則。在一般情況下,你希望所有的其他規則,法之後,有一個終端「錯誤」治法:

. { fprintf(stderr, "Unexpected input character '%c', ignoring\n", *yytext; } 

隨着那加,你應該開始看到意想不到的輸入字符的消息。如果這些消息看起來不正確(例如,它看起來像你應該將這些字符識別爲complexnum或其他標記的一部分),那麼這意味着你的其他標記的正則表達式是錯誤的。

運行您的程序時,調試你的語法,旗-DYYDEBUG(添加到gcc行腳本的,在任何的源文件)編譯,並設置YYDEBUG的環境變量(輸入命令YYDEBUG=1 ./complex_cal。)這將導致你的野牛生成的解析器打印出各種有關它獲取的令牌,它轉移到的狀態以及正在減少的規則的消息。通過解決這些問題並查看意外事件的發生,您應該能夠調試任何語法問題。