• ベストアンサー

yaccとlexで、logや三角関数を含む電卓を作るプログラムの組み方

今、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]); %%

質問者が選んだベストアンサー

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

ちょっと気になるのですが, YACC ソースで, 例えば | Abs "(" expr ")" {$$=abs($3);} となっているのが怪しい気がします. ひょっとして | Abs LP expr RP {$$=abs($3);} だったりしません?

e271828
質問者

お礼

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

その他の回答 (3)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

そうだ, ついでに 1点. 「π」は英語では pi と綴ります.

e271828
質問者

お礼

なるほど・・・、勉強になります! Tacosanさんには本当にお世話になりました。 これにて締め切りとさせていたがきます。 皆様どうもありがとうございました!

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

syntax error が出てるからおかしいなぁと思ったんだけど, やっぱりね. レクサで ( や ) を LP/RP に置き換えてるので, パーザが (/) を受け取れないんです.

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.1

全く自信無しですが、 #define PAICONST 3.14159265358979の直後に #define mcon (PAICONST/180.0) を定義し、 double mcon=PAICONST/180.0;を削除して下さい。 それで、どうなりますか? だめだったら、ごめんなさい。

e271828
質問者

お礼

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

関連するQ&A