まつもと ゆきひろです

In message "[ruby-list:10269] Re: for が修飾子だったら"
    on 98/10/23, Shin-ichro Hara <sinara / blade.nagaokaut.ac.jp> writes:

|原です。

||そういう話をしてるんじゃなくて、foo.eachのあとに文の集まりが続くか否かを
||パーザーがgreedyに見に行かないのはなんでなの?と質問しています。
|
|文法に合っている最長を取るとか?(^^;

うーむ.

|これとちょっと違うんだけど、文法エラーになるときエラーにならない解釈が
|あるならそれを採用するようにしてもらえるとありがたいですね。

現在でもできるだけ「善意に解釈する」ような文法にはしてます.
たとえば

   foo{1}

なんてのはブロックが来てるんだか,第一引数にハッシュが来てる
のか分からないんで,当初エラーにしてたんですが,これはブロッ
クが来てるとみなすようにしてます.

|それが LALR(1) (なんだっけこれ ^^;) に外れるんですか、、、いち token 読
|んで文法的に完結していなければもういち token 読んでみるけど、いち token
|読んで文法エラーならエラーにならない様にそれ以前を解釈し直すというのは
|できないって事かな。

LALR(1)のLALRってのは文法のクラスです.LALR(1)はやや乱暴にい
えばyaccの取り扱える文法って意味ですね.で,(1)は1トークンの
先読みで文法が解釈できるという意味です.で,たとえば改行を越
えてgreedyに見に行くとすると

   obj.each
   do .. end

はeachまで読み込んだ後,改行にぶつかった後,doがあるかチェッ
クしないと構文が決定できません.ということは,「改行」,「do」
の2トークン読まないといけなくなるのでyaccでは構文解析できま
せん.これがブロックが { } だともっと大変で

  obj.each
  {2 => 5}

は2行目は実はブロックではなくハッシュなのですが,この構文を
決定するためには「改行」,「{」,「2」,「=>」の4トークン読
み込まないと構文が決定できません.

たとえ手書きのパーザを書くにしても2個以上のトークンを先読み
する必要のあるパーザは1トークン先読みするものに対して,書く
のが飛躍的に困難です.

たとえば,改行による文区切りを禁止すればこれらも1トークンの
先読みで解釈できますが,おそらく今まで書かれたRubyスクリプト
の99.98%が動作しなくなるでしょう.いまさらそれだけ大きな文法
の変更が許容されるとは思いません.

というわけで,たかだか「改行の後ろにブロックを置く」というこ
とを実現するために

  * yaccをあきらめて手書きのパーザを書く

  * 過去のRubyスクリプト全部に書き換えが必要な文法の変更

のいずれも割に合わないな,というのが私の感想です.

もちろん,Rubyのソースは公開されていますので,ここの部分だけ
を変更した別の言語が新たに生まれるというのは推奨したいとは思
いますが,私自身はやらないと思います.

# 私は言語がいっぱいあるのは望ましいと思ってます.

                                まつもと ゆきひろ /:|)