5

私は github で Zach Carter のreflect.js (素敵な Javascript パーサー) を使用しています。彼のパーサーの動作を変更して、コメントを他のものと同じように解析する必要がある通常のトークンとして処理しようとしています。Reflect.js のデフォルトの動作は、すべてのコメントを追跡し (レクサーがそれらをトークンとして取得します)、作成する AST (抽象構文ツリー) の最後にそれらのリストを追加することです。

ただし、これらのコメントを AST にインプレースで含めてほしいと思います。この変更には、ここで grammar.y ファイルに文法規則を追加することが含まれると思います。現在、コメントに関するルールはありません。私の理解が正しければ、メインの解析コードでコメントが無視されるのはそのためです。

AST にコメントを含めるルールをどのように記述しますか?

4

1 に答える 1

3

単純なバージョンは、元の文法の各ルールを変更します。

      LHS = RHS1 RHS2 ... RHSN ;

することが:

      LHS =  RHS1 COMMENTS RHS2 COMMENTS ... COMMENTS RHSN ;

これは抽象的には機能しますが、LL または LALR ベースの場合、パーサー ジェネレーターが台無しになる可能性があります。そのため、GLR などのより強力なパーサー ジェネレーターに切り替える必要があります。

よりスマートなバージョンは、すべての終端T を非終端記号に (and のみ) 置き換えます。

      T  =  COMMENTS t ;

T の代わりに t を自明に発行するように元の字句解析器を変更します。まだ先読みの問題があります。

しかし、これは本当の解決策の基礎を与えてくれます。

これのより洗練されたバージョンは、レクサーがトークンの前に表示されたコメントを収集し、それが発行する次のトークンにそれらを添付することです。本質的には、文法の最終規則の変更をレクサーで実装しています。

これで、パーサー (テクノロジを切り替える必要はありません) は、最初に見たトークンだけを見るようになりました。トークンはコメントを注釈として保持します。コメントを前のトークンに添付するコメントと次のトークンに添付するコメントに分けると便利ですが、決定する実際的な方法がないため、これをヒューリスティックよりも優れたものにすることはできません。コメントが実際に属しているトークン。

トークンとコメントの位置情報を取得して、元のテキスト (「コメントを適切な場所に配置」) を再生成できるようにする方法を理解するのは楽しいことです。言語の構文規則に違反しない方法で、適切な基数値、文字列エスケープなどを使用して実際にテキストを再生成すると、より楽しくなります。

これは、一般的な言語処理ツールを使用して行いますが、かなりうまく機能します。変換タスクに集中できるように、すべてをまっすぐにするのは驚くべきことです。人々はこれを過小評価しています。

于 2013-07-17T05:54:48.070 に答える