2013-03-31 76 views
0

我必須在flex/bison中爲課堂中的實驗室製作計算器,並且必須添加計算平方根或絕對值的功能以sqrt(x)或abs(x)爲單位。我導入了數學庫,並且如果COMMAND FOR IT CONSIST OF ONE CHARACTER的話,我得到了caculator的工作。這就是我的意思是:將abs(x)和sqrt(x)函數添加到flex/bison計算器

expr: 
...... 
| '(' expr ')' { $$ = fabs($2); } //for abs 
| '[' expr ']' {$$ = sqrt($2); } //for sqrt 
....... 

現在,這工作得很好,如果我把(-2)我得到2,[4] = 2的問題是清楚的,我需要它,因此命令是abs(x)和sqrt(x)。如果我切換代碼說

| "abs(" expr ')' { $$ = fabs($2); } //for abs 
| "sqrt" expr ']' {$$ = sqrt($2); } //for sqrt 

這不起作用,因爲它看到a然後b,並試圖做一些與此。這很可能是因爲我的計算器還支持分配變量值(如x = 2),所以它認爲a和b之間應該有一個運算符。我不知道如何解決這個問題。我將不勝感激任何幫助。 這裏是我的代碼是否有幫助:

hexcalc.y

%{ 
#include <stdio.h> 
#include <math.h> 
#include <stdlib.h> // often required 

// A simple error message to move things along 
void yyerror(const char *msg) 
{ 
printf("ERROR(PARSER): %s\n", msg); 
} 

// Storage for variables: yes Virginia, only 26 variables possible in this langu$ 
long variables[26]; 
%} 

%union { 
float nvalue; 
int ivalue; 
int varindex; 
} 

%token <nvalue> NUMBER 
%token <ivalue> INT 
%token <varindex> NAME 
%type <nvalue> expr 
%type <nvalue> term 
%type <nvalue> varOrNum 
%% 
statementList : statement '\n' 
| statement '\n' statementList 
; 

statement : NAME '=' expr { variables[$1] = $3; } 
| expr { printf("RESULT: %f\n", $1); } 
; 

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

| "abs(" expr ')' { $$ = $2; } 
| "sqrt(" expr ')' { $$ = sqrt($2); } 
| expr '/' term { $$ = $1/$3; } 

| term { $$ = $1; } 
; 

term : term '*' varOrNum { $$ = $1 * $3; } 

| varOrNum { $$ = $1; } 
; 

varOrNum : NUMBER { $$ = $1; } 
| NAME { $$ = variables[$1]; } 
; 

%% 

main() { 
int i; 
for (i=0; i<26; i++) variables[i] = 0; 
yyparse(); 
} 

hexcalc.l

%{ 
#include <stdlib.h> 
#include <math.h> 
#include "hexcalc.h" 
#define BASE 10 
char* endptr; 

%} 

%% 

[a-z] { yylval.varindex = yytext[0] - 'a'; $ 
} 
[0-9]+ { yylval.nvalue = atof(yytext); 
return NUMBER; 
} 
[0-9]+"."[0-9]+?|"."[0-9]+? {yylval.nvalue = atof(yytext); 

return NUMBER; 
} 

[ \t] ; 
\n|. { return yytext[0]; 
} 
%% 

int yywrap() { 
return 1; 
} 

回答

2

你需要認識到在詞法分析器視爲單個標記多字符的名稱,然後在使用它們的語法。最簡單的辦法是隻將它們添加到您的詞法分析器:

abs { return ABS; } 
sqrt { return SQRT; } 

然後,您可以添加到您的解析器:

%token ABS SQRT 

%% 

expr: ABS '(' expr ')' { $$ = fabs($3); } 
    | SQRT '(' expr ')' { $$ = sqrt($3); } 
+0

謝謝!!!!!!!!!!!!!!!!!! –

+0

@KhalilNorman如果這回答您的問題,請將其標記爲「已接受」。 –

0

你需要在你.L文件創建規則「ABS」和「開方「;聲明他們將通過%token返回的令牌;並在語法規則中使用這些標記名稱:ABS「(」expr「)」:...