不思議なPerlリテラル
ちょっとパーサの実装の参考にするためにPerlの数値リテラルについて調べていたのですが、手元のPerl5.8.3では「1.1.1」のような式を正しく解析できないようです。
予想では「1.1.1」は数値「1.1」と文字列結合演算子「.」と数値「1」と解釈され、「1.1」と「1」を文字列結合した文字列「1.11」になると思っていたんですが、実際に試してみると、なかなか不思議なことになりました。
my $i = 1.1.1; print sprintf("string:'%s' number:'%d' length:%d\n", $i, $i, (length $i)); print join(',', unpack("C*", $i));
最新版のPerlでは修正されてるかもしれませんが、上記のコードはsyntax errorにはならず、手元の環境では謎の値を生成してしまいました。
string:'' number:'0' length:3 1:1:1
処理系のバグでしょうか?
そうでないなら、単に私の知らないリテラル記法があるんでしょうか。
ちなみにPerlのBNFは公開されてないようですが、Perl処理系のtoke.c内にあるscan_num関数のコメントには以下のような記述がありました。
Read a number in any of the formats that Perl accepts: \d(_?\d)*(\.(\d(_?\d)*)?)?[Ee][\+\-]?(\d(_?\d)*) 12 12.34 12. \.\d(_?\d)*[Ee][\+\-]?(\d(_?\d)*) .34 0b[01](_?[01])* 0[0-7](_?[0-7])* 0x[0-9A-Fa-f](_?[0-9A-Fa-f])*