PHPのTokenizer関数の紹介
お久しぶりです。Plaggerの件の続きが書きにくくて更新止まってました。ごめんなさい。リハビリがてら、書きたいことを書いてみます。
「自動型変換 - PHP重箱の隅」を読みました。ナイスな記事ですね。筆者の方はPHPのundocumentedな部分の多さが不満のようですが、僕も似た不満を持っていた頃があった気がします。今後も(少なくとも僕にとって)楽しい記事を書いてもらえそうで、期待してます!
記事の内容としてはご推察の通りだと思います。この記事に関連して、PHPがトークン分解をどうやっているのか、Tokenizer関数を使ってPHPから調べる方法について紹介してみます。(もちろん、本気で調べたいならzend_language_scanner.lやzend_language_parser.yを読むべきです)
PHPがどうトークン分解をするのかは、token_get_all関数を使って調べられます。
$ php -r 'var_dump(token_get_all("<?php -2147483648;?>"));' array(5) { [0]=> array(3) { [0]=> int(367) [1]=> string(6) "<?php " [2]=> int(1) } [1]=> string(1) "-" [2]=> array(3) { [0]=> int(306) [1]=> string(10) "2147483648" [2]=> int(1) } [3]=> string(1) ";" [4]=> array(3) { [0]=> int(369) [1]=> string(2) "?>" [2]=> int(1) } }
値の返し方が少々特徴的ですが、どうトークン分解しているかは一目瞭然かと思います。1文字のトークン以外のトークンはトークンの種類が数値で帰ってきますが、これが何を意味するかはtoken_name関数で調べることができます。例えば「"2147483648"」はトークンとしては「int(306)」だそうですから、調べてみます。
$ php -r 'var_dump(token_name(306));' string(9) "T_DNUMBER"
このトークンのシンボル名の意味は「パーサトークンの一覧」に列挙してあります。T_DNUMBERというのはdoubleのリテラルですね。これらから、"-2147483648"はトークン分解の時点で単項マイナス演算子とdoubleのリテラルの2つのトークンとして解釈されていることがわかります。
これ、PHPの中身を覗く取っ掛かりとしては面白い機能だと思います。連休も残り一日ですが、興味のある方は少し遊んでみてはいかがでしょうか。(こんなことに興味がある人ならいずれソースコードを読む事になると思いますが…)