From: Minero Aoki Date: 2002-08-07T04:39:32+09:00 Subject: [ruby-dev:17952] Re: next parser (Re: parenthesize argument(s) for future version) あおきです。 In mail "[ruby-dev:17937] Re: next parser (Re: parenthesize argument(s) for future version)" matz@ruby-lang.org (Yukihiro Matsumoto) wrote: > まつもと ゆきひろです > メール出した後考え直して、やっと理解できました。部分的にパー > ズしてネストのレベルを知るとか、irb相当を実装するのいはスト > リーム的なAPIが欲しいだろうということですね。もっともです。 そゆことです。 すみません、相変わらず言葉足らずで…。 ruby_dyna_vars うんぬんと言ったのは、 [ruby-dev:17895] Re: next parser > yacc以外にもCのコードからグローバルアクセスをなくすことは無 > 理なので、あちこちにロックを入れることになると思います。です の部分を誤解してて、「いずれにしろパーサからはグローバル変数に アクセスしているので、パース中はロックをかけなくてはいけない」 と受けとったからでした。でもよく考えると「Cのコードからは」と あるのでパーサだけの話ではないわけですね。 なのでそこは忘れてください。 > でも、それはパーザのエラーコードの一部としてネストレベルとか > の情報を含めばよいような気もします。で、毎回あたまからパーズ > すると。 それでは別の視点で……。その構文木からは 「インデックス n から始まる長さ 3 のトークンが予約語 def である」 というような情報は取れますか? それと同等のなにかでもいいですが。 たとえば Ruby でエディタを書いたとして、いちいちパーサを書き直さずに Ruby プログラムをリアルタイムで色付けできるくらいの速度と情報が 得られるのなら文句はありません。 > ||# いちおう対案も用意してはあるんですが、 > > 対案も聞いてみたいです、ぜひ。 んではぼくの案を。 これはストリーム系 API を提供することを核とした案です。 まずこれまで通り yacc ベースで作るのを前提とします。 ただしユーザの用意した yacc は使わず、byacc なり bison なりを 改造して同梱します。その改造の内容は…… 1. 常にマシンスタック上にパーサスタックを確保することで GC セーフにする。 2. yyparse をリエントラントにする。 3. アクションの内容を yyparse 埋め込みでなく関数に分離し、 しかも関数ポインタテーブル (atbl と仮称) 経由で呼ぶようにする。 4. atbl はパーサインスタンスごとに指定可能とする。 この結果、たとえば stmts : none | stmt { $$ = newline_node($1); } | stmts terms stmt { $$ = block_append($1, newline_node($3)); } というコードは次のように書いたものとして実行されます。 stmts : none { $$ = (*parser->atbl[5])(parser); } | stmt { $$ = (*parser->atbl[6])(parser,$1); } | stmts terms stmt { $$ = (*parser->atbl[7])(parser,$1,$2,$3); } (parser はパーサインスタンスごとの情報を格納した構造体です。) あとは適切に atbl を作ってやれば C or Ruby レベルで好きなように 振舞いを変更できます。 ripper を書いたときは文字列埋め込み式のまわりをかなり改造しな いとうまくイベントを拾えなかったんですが、こないだの仕様変更で それがほとんど必要なくなり、自動化が非常に簡単になっていると思 います。 利点 * いちいち手書きでイベントを起こす必要がないので (まつもとさんの) 手間が少ない。 * 複数のパーサインスタンスを同時に動かせる。 * 規則が多少変わっても atbl の先でアレコレすれば ruby とは 独立に互換性を保てる。 * すぐにでも実装できる。 欠点 * 相変わらず yacc の先読みとスキャナの状態遷移の競合で 苦しむことになる。 * Rite が出たときに「コア全体をスクラッチから書き直しました!」 という派手な宣伝文句が使えなくなる (笑) ------------------------------------------------------------------- 青木峰郎