導入

最近、Rustを使うことが多くなってきました。ので、今更ながらに勉強をはじめました。


Rustで実際に開発をした感想

コンパイルが通ればそれなりに動く、というのは素敵だなぁ、と思います。その他はとりたてて感想はありません。


ところで、電卓っていうと

Rustで電卓を書くというと、やはりナウなヤングは、パーサコンビネータで文法を書いてバカうけ、という感じなのでしょうか?


ところで、電卓っていうと

残念ながら私はそんなことはできないので、古風なアプローチをしようと思います。


hocというコマンドを知っていますか?

「UNIXプログラミング環境」という本に出てくる、結構高性能な電卓です。


hocというコマンドを知っていますか?

「UNIXプログラミング環境」という本の中では、5回に渡って機能を追加してく作業が描かれています。


hocというコマンドを知っていますか?

全く関係ないのですが、Plan9では標準コマンドで、man 1 hocにきちんと記されています。

hoc_man_plan9.png

hocというコマンドを知っていますか?

これをRustで5回に分けて作ってみようと思います。


hocというコマンドを知っていますか?

5回分のネタをゲットしたぜ!


hocというコマンドを知っていますか?

前述の本の中では、yaccで文法が書かれているのですが、Rustでこれが書けないかなぁ、と、Rustでyaccを使う方法をググってみました。


grmtoolsというのがあるのですね

クイックスタートガイドもあって最高じゃないですか!

2023-05-22 21.43.28 softdevteam.github.io 3184bf4a1542.png

とりあえずコピペして動かしてみました

デモ


「UNIXプログラミング環境」での第一回の文法は下記の通り(以下引用です)

$ cat hoc.y
%{
#define YYSTYPE double /* data type of yacc stack */
}
%token NUMBER
%left  '+' '-' /* left associative, same precadence */
%left  '*' '/' /* left assoc., higher precedence */
%%
list:    /* nothing */
         | list '\n'
         | list expr '\n'    { printf("\t%.8g\n", $2); }
         ;
expr:      NUMBER            { $$ = $1; }
         | expr '+' expr     { $$ = $1 + $3; }
         | expr '-' expr     { $$ = $1 - $3; }
         | expr '*' expr     { $$ = $1 * $3; }
         | expr '/' expr     { $$ = $1 / $3; }
         ;
$$

grmtoolsとQuickstart Guideにある文法は下記の通り

%start Expr
%%
Expr -> Result<u64, ()>:
      Expr '+' Term { Ok($1? + $3?) }
    | Term { $1 }
    ;

Term -> Result<u64, ()>:
      Term '*' Factor { Ok($1? * $3?) }
    | Factor { $1 }
    ;

Factor -> Result<u64, ()>:
      '(' Expr ')' { $2 }
    | 'INT'
      {
          let v = $1.map_err(|_| ())?;
          parse_int($lexer.span_str(v.span()))
      }
    ;
%%

これに、「UNIXプログラミング環境」のhocの解説の第1回と同様、MINUSを付け加えた

デモ


参考文献

    1. UNIXプログラミング環境 B. Kernighan, R. Pike, (訳 石田晴久)

 

    grmtoolsドキュメント https://softdevteam.github.io/grmtools/master/book/index.html

とりあげたソースコード

https://www.snthtns.jp/gitea/hhh/pseudo_hoc (←自宅サーバなので、いつまであるか分からないです)


ご清聴

ありがとうございました。

bannerAds