プロが教えるわが家の防犯対策術!

今、yaccとlexで、logや三角関数を含む電卓を作るプログラムを作成しています。四則演算は実装できました。パイも実装できました。しかしlogや三角関数sin,cos,tanやabs,expなどがどうしても実装できません。以下のプログラムをlinux上のターミナルで実行しsin(90)やlog(90)どと入力しても、sintax errorと返されてしまいます。ちなみに実行時は-lmオプションは付けています。どうしたらこれらが実装できるのでしょうか。ご教授願えると幸いです。

■yaccの.yファイル■
%{
#define YYSTYPE double
#define PAICONST 3.14159265358979
#include <stdio.h>
#include <math.h>
double mcon=PAICONST/180.0;
%}

%token NL NUM LP RP END
%left ADD SUB
%left MUL DIV
%left Pai Abs Sqrt Sin Cos Tan Log Exp NEG
%%
s : list
;
list : /* empty */
| list expr NL { printf ("result: %lf\n", $2);}
| list END { return;}
;
expr: expr ADD expr {$$ = $1 + $3;}
| expr SUB expr {$$ = $1 - $3;}
| expr MUL expr {$$ = $1 * $3;}
| expr DIV expr {$$ = $1 / $3;}
| SUB expr %prec NEG {$$ = -$2;}
| LP expr RP {$$ = $2;}
| NUM {$$ = $1;}
| Pai {$$=PAICONST;}
| Abs "(" expr ")"{$$=abs($3);}
| Sqrt "(" expr ")"{$$=sqrt($3);}
| Sin "(" expr ")" {$$=sin($3*mcon);}
| Cos "(" expr ")" {$$=cos($3*mcon);}
| Tan "(" expr ")" {$$=tan($3*mcon);}
| Log "(" expr ")" {$$=log($3);}
| Exp "(" expr ")" {$$=exp($3);}
;
%%
yyerror(s) char *s; { printf ("%s\n",s);}
main() {
yyparse();
}

#include "lex.yy.c"



■lexの.lファイル■
%{
#include <math.h>
#include <ctype.h>
%}

%%
"+" return (ADD);
"-" return (SUB);
"*" return (MUL);
"/" return (DIV);
"(" return (LP);
")" return (RP);
"." return (END);
(pai|PAI) return(Pai);
(abs|ABS) return(Abs);
(sqrt|SQRT) return(Sqrt);
(sin|SIN) return(Sin);
(cos|COS) return(Cos);
(tan|TAN) return(Tan);
(log|LOG) return(Log);
(exp|EXP) return(Exp);

[0-9]+\.[0-9]*|[0-9]+{
sscanf (yytext, "%lf", &yylval); return (NUM);
}
[ \t] ;
^\n return (END);
\n return (NL);
. return (yytext[0]);
%%

A 回答 (4件)

ちょっと気になるのですが, YACC ソースで, 例えば


| Abs "(" expr ")" {$$=abs($3);}
となっているのが怪しい気がします. ひょっとして
| Abs LP expr RP {$$=abs($3);}
だったりしません?
    • good
    • 0
この回答へのお礼

回答どうもありがとうございます!
まさにご指摘の通りで、カッコをLP、RPに直した所無事動作しました!うれしいです。
本当にありがとうございました!

お礼日時:2008/07/15 19:43

そうだ, ついでに 1点.


「π」は英語では pi と綴ります.
    • good
    • 0
この回答へのお礼

なるほど・・・、勉強になります!
Tacosanさんには本当にお世話になりました。

これにて締め切りとさせていたがきます。
皆様どうもありがとうございました!

お礼日時:2008/07/16 16:22

syntax error が出てるからおかしいなぁと思ったんだけど, やっぱりね.


レクサで ( や ) を LP/RP に置き換えてるので, パーザが (/) を受け取れないんです.
    • good
    • 0

全く自信無しですが、


#define PAICONST 3.14159265358979の直後に
#define mcon (PAICONST/180.0) を定義し、
double mcon=PAICONST/180.0;を削除して下さい。
それで、どうなりますか?
だめだったら、ごめんなさい。
    • good
    • 0
この回答へのお礼

回答ありがとうございます!動作に変化なしでした><しかし他の回答者様の指摘を参考に修正したところ動作しました!
どうもありがとうございました!

お礼日時:2008/07/15 19:36

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!