我有一個符號表,它包含一個變量/符號的名稱,它的數據和它的數據類型(存儲爲char)。我喜歡它,所以符號被看作是一個iexpr,如果它是一個整數,或者是一個rexpr,如果它是一個實數。這些是規則,我現在他們:Bison多規則符號
iexpr: INT_TOKEN
| iexpr PLUS iexpr { $$ = $1 + $3; }
| iexpr MINUS iexpr { $$ = $1 - $3; }
| iexpr DIVIDE iexpr {$$ = $1/$3;}
| iexpr MOD iexpr{$$ = $1 % $3;}
| LPARENT iexpr RPARENT{$$=$2;}
| SYMBOL { symrec *s;
s = getsym($1);
if(s!=0){
if(s->type == 'i'){
$$ = atoi(s->data);
}
}
}
;
rexpr: REAL_TOKEN
| rexpr PLUS rexpr { $$ = $1 + $3; }
| rexpr MINUS rexpr { $$ = $1 - $3; }
| iexpr PLUS rexpr { $$ = (double) $1 + $3; }
| iexpr MINUS rexpr { $$ = (double) $1 - $3; }
| rexpr PLUS iexpr { $$ = $1 + (double) $3; }
| rexpr MINUS iexpr { $$ = $1 - (double) $3; }
| rexpr DIVIDE rexpr {$$ = $1/$3;}
| rexpr MULTIPLY rexpr{$$ = $1 * $3;}
| rexpr DIVIDE iexpr {$$ = $1/(double) $3;}
| rexpr MULTIPLY iexpr {$$= $1 * (double) $3;}
| iexpr DIVIDE rexpr {$$ = (double) $1/$3;}
| iexpr MULTIPLY rexpr {$$ = (double) $1 * $3;}
| rexpr MOD rexpr {$$ = (int)$1 % (int)$3;}
| rexpr MOD iexpr {$$ = (int)$1 % $3;}
| iexpr MOD rexpr {$$ = $1 % (int)$3;}
| LPARENT rexpr RPARENT{$$ =$2;}
| SYMBOL { symrec *s;
s = getsym($1);
if(s!=0){
if(s->type == 'r'){
$$ = atof(s->data);
}
}
}
;
然而在rexpr分別規則永遠不會使用,因爲它永遠只能看到它作爲一個iexpr。我怎樣才能使它取決於類型描述符它被視爲該類型,而不僅僅是一個整數?
編輯:所以我試圖改變我的lex文件,這樣它會返回一個不同的令牌每種類型。爲此,我需要包含可符號化的頭文件,以便我可以檢查該名稱並根據其類型返回不同的符號。下面是該代碼:
[a-zA-Z]+ { yylval.string = strdup(yytext);
symrec *s;
s = getsym(yylval.string);
if(s!=0){
if(s->type == 'r'){
return RSYMBOL;
}else if(s->type == 'i'){
return ISYMBOL;
}
}else{
return SYMBOL;
}
}
但現在我有一個錯誤說,我有我的頭功能的多個定義,因爲我包含在這兩個文件。
謝謝!你能看看我的編輯?我認爲這是我應該做的,但我會遇到更多的問題。 – cage479
@ cage479:你沒有在頭文件中定義函數;你只聲明他們。如果你要定義函數,你顯然會遇到重複的定義錯誤,以及全局變量的重複定義。順便說一句,如果詞法分析器可以訪問符號表,它可以返回符號表條目而不是符號名稱的副本。這是一種減少內存分配的經典技術,即使詞法分析器不會根據符號表信息修改其行爲。 – rici
如果它不是很明顯,我沒有太多經驗創建我自己的頭文件。所以如果我只聲明的功能(即時通訊假設只是「symrec * getsym()」)我在哪裏實際定義它們?我是否需要在我的bison和flex文件中定義它們或者只是其中的一個? – cage479