2014-02-25 104 views
0

由於某些原因,野牛不想做任何評估。所有文件的編譯順利進行,程序運行。當我輸入表達式4+5並按回車時,它將分別爲4+5創建令牌。我甚至可以將一些printf放入野牛認識每個標記屬性的地方,包括加號(43)。靈活/野牛沒有正確評估

但是該程序從不評估此生產expr '+' term { $$ = $1 + $3; }。至少根據我的知識,這絕不會被稱爲,即使這是生產assign '\n' { printf("%d\n", $1); }從不打印出價值。當^D退出時,它會觸發void yyerror(const char *)

任何有關這個問題的幫助是非常感謝。謝謝!

//FLEX 
%{ 
    //#include <stdio.h> 
    #include "y.tab.h" 
%} 

%option noyywrap 

letter [A-Za-z] 
digit [0-9] 
space [ \t] 

var  {letter} 
int  {digit}+ 
ws  {space}+ 

%% 

{var} { yylval = (int)yytext[0]; return VAR; } 
{int} { yylval = atoi(yytext); return CONST; } 
{ws} { } 
.  { return (int)yytext[0]; } 

%% 

/* nothing */ 

//BISON 
%{ 

//INCLUDE 
//#include <ctype.h> 

//DEFINE 
#define YYDEBUG 1 

//PROTOTYPE 
void yyerror(const char *); 
void print_welcome(); 
int get_val(int); 
void set_val(int, int); 

%} 

%token CONST 
%token VAR 

%% 

session 
    : { print_welcome(); } 
     eval 
    ; 

eval 
    : eval line 
    | 
    ; 

line 
    : assign '\n'  { printf("%d\n", $1); } 
    ; 

assign 
    : VAR '=' expr  { set_val($1, $3); $$ = $3; } 
    | expr    { $$ = $1; } 
    ; 

expr 
    : expr '+' term  { $$ = $1 + $3; } 
    | expr '-' term  { $$ = $1 - $3; } 
    | term    { $$ = $1; } 
    ; 

term 
    : term '*' factor { $$ = $1 * $3; } 
    | term '/' factor { $$ = $1/$3; } 
    | term '%' factor { $$ = $1 % $3; } 
    | factor   { $$ = $1; } 
    ; 

factor 
    : '(' expr ')'  { $$ = $2; } 
    | CONST    { $$ = $1; } 
    | VAR    { $$ = get_val($1); } 
    ; 

%% 

void yyerror(const char * s) 
{ 
    fprintf(stderr, "%s\n", s); 
} 

void print_welcome() 
{ 
    printf("Welcome to the Simple Expression Evaluator.\n"); 
    printf("Enter one expression per line, end with ^D\n\n"); 
} 

static int val_tab[26]; 

int get_val(int var) 
{ 
    return val_tab[var - 'A']; 
} 

void set_val(int var, int val) 
{ 
    val_tab[var - 'A'] = val; 
} 

//MAIN 

//PROTOTYPE 
int yyparse(); 

int main() 
{ 
    extern int yydebug; 
    yydebug = 0; 
    yyparse(); 
    return 0; 
} 
+0

在運行程序之前,通過使用-DYYDEBUG = 1編譯並設置shell env變量export YYDEBUG = 1來打開YACC調試。它打印出關於移位和減少操作的非常可讀的輸出。 –

+0

詞法分析器是否返回'\ n'?如果沒有,那麼你的線路規則不會被觸發。您可以將'\ n'作爲空格並使用';'作爲表達式的結尾。 –

+0

你不需要術語和因素規則。只需使用「expr:expr'+'expr」並使用YACC運算符優先級機制。 –

回答

3

lex文件不相匹配\n任何規則,因爲在lex/flex.任何字符匹配除線端。 lex(或flex)的默認規則會迴應並忽略匹配的字符,所以\n會發生什麼情況。由於解析器將無法接受line,除非它看到一個\n標記,它最終將被迫向您顯示語法錯誤。

所以,你需要更改規則

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

.|\n { return (int)yytext[0]; } 

(我不會打擾你了跟投給int但它肯定不會做任何傷害,所以我離開它)

+0

有什麼好笑的是我關機,然後去睡了一晚。然後我有一個夢想,這是問題(謝謝你)。今天早上我看到你的帖子時,我笑得這麼辛苦,有時我可能會成爲一個真正的白癡。感謝您的幫助,我非常感謝。現在一切正常。 :d –