PHPのソースを覗いて、字句解析と構文解析がある事を知る
TOP > てきとうにこらむ > ゲーム作りとプログラミング日記 > PHPのソースを覗いて、字句解析と構文解析がある事を知る
構文解析
メモ。Zend/zend_language_scanner.cのcompile_string関数にて。bisonの使い方を調べるか。
とりあえず、電卓をつくった
構文解析で、電卓をつくった。
ソース
https://github.com/youkidearitai/calc-modoki
構文解析
PHPでは、字句解析を行った後に構文解析を行うという手順になっている。
bison
ためしに、bisonを使って電卓を作ってみる。構文が結構簡単に処理できるのはいいと思った。しかしこれでは、構文解析だけで行けるんじゃね?という謎が出てきた。
字句解析
例えば式に対してインデントやスペースを混ぜてみたいとかなると、yylex関数の中にその処理を入れないといけなくなる。構文が増えれば増えるほど、yylex関数にはどんどんルールがたまっていくので、結構たいへんになる気がする。
その問題を解消するために、字句解析器(re2c)を使ってみることにする。今までyylexにはC言語でガリガリ書いていたのだけど、これをre2cに任せる。すると、拡張子が.reのファイルからre2cプログラムでC言語のソースに変換されるのである。
変換されたソースは、goto文だらけ。時々PHPのソースを漁るとでてくるソースみたいだと思った。
字句解析でスペースをとり、数値や特定の記号をシンボルに変換したものを構文解析に回す。字句解析のおかげで、記法を追加するのも調整するのもだいぶ楽になったと思う。
結果
$ ./calc
38 + 24 * (222 - 22)
4838
999 + 1 / 100
999
999 + (1 / 100)
999
(999 + 1) / 100
10
残っている問題
- すべて整数として扱っているので、3 / 4といった答えが小数点以下の計算に対応していない。小数点以下は切り捨てられるので、この例では0になる。
- 構文解析時の具体的な計算と表示を分離するべきだと思う。
- 3 / 0といった、ゼロ除算に対してのエラー処理がない。構文解析器は構文解析に対して責任を持つべきであって、計算結果に対しての責任を持つべきではないと思う。
- printfしている部分を分離すべきかなと思っている。
さんこう
- http://akkera102.sakura.ne.jp/gbadev/index.php?Doc.19%20%BB%FA%B6%E7%B2%F2%C0%CF%A5%C4%A1%BC%A5%EBre2c
- http://www.tokumaru.org/yacc/