Mae向きなブログ

Mae向きな情報発信を続けていきたいと思います。

逆ポーランド記法電卓

今日は、趣を変えてbisonをやってみました。学生時代にやったことはあるのですが、すっかり忘れてしまっています。

http://www.mi.s.osakafu-u.ac.jp/~kada/course-kitami/j3_03/bison.pdf
を参考に、逆ポーランド記法電卓を作成しました。

rpcalc.y

/* 逆ポーランド記法電卓 */

%{
#define YYSTYPE double

#include <stdio.h>
#include <ctype.h>
#include <math.h>

void yyerror(char* s)
{
   printf("%s\n", s);
}
%}

%token NUM 

%%  

input:  /* 空 */
        | input line
        ;
line:    '\n'	
        | exp '\n' { printf("\t%.10g\n", $1); }
        ;
exp:   NUM	{ $$ = $1; }
        | exp exp '+'	{ $$ = $1 + $2; }
        | exp exp '-'	{ $$ = $1 - $2; }
        | exp exp '*'	{ $$ = $1 * $2; }
        | exp exp '/'	{ $$ = $1 / $2; }
        | exp exp '^'	{ $$ = pow($1, $2); }
        | exp 'n' { $$ = -$1; }
        ;
%%

int yylex(void)
{
  int c;
  while ((c = getchar()) == ' ' || c == '\t')
    ;
  if (c == '.' || isdigit(c)) {
    ungetc(c, stdin);
    scanf("%lf", &yylval);
    return NUM;
  }
  if (c == EOF)
    return 0;
  return c;
}

int main(void) {
  yyparse();
  return 0;
}

以下のように流れていきます。

mmasa@debian:~/work/c/bison/rpcalc$ bison rpcalc.y
mmasa@debian:~/work/c/bison/rpcalc$ gcc rpcalc.tab.c -lm -o rpcalc
mmasa@debian:~/work/c/bison/rpcalc$ ./rpcalc
3 7 + 3 4 5 *+-
        -13
mmasa@debian:~/work/c/bison/rpcalc$

「2.4 多機能電卓:mfcalc」は非常に面白い。