0

Grako のモデル ビルダー セマンティクスを使用して抽象構文ツリー (AST) を構築した状況にいます。次に、その AST から JavaScript コードを生成する必要があります。いくつかのテンプレートを定義しましたが、単純なテンプレートですべてのケースを処理できるわけではないことに気付きました。私がこだわっている具体的なルールは次のとおりです。

fcall::FunctionCall   = name:identifier '(' ','.{args:expression} ')' ;

このルールは、単純な関数呼び出しとコンストラクター呼び出しの両方に一致します。どちらがどちらであるかを字句的に判断する方法がないため、その名前を持つクラスがそのスコープ内で定義されているかどうかによって異なります。

たとえば、「a = Func();」

JavaScript では、2 つのケースで異なる構文が必要です (「a = new Func();」または「a = Func();」)。

そのため、どれがどれであるかを追跡するためのシンボル テーブルが必要です。グラコでこれを達成する方法はありますか?

追加情報:

これを行う方法に関する私の考え: シンボル テーブルを構築する walker クラスを作成し、それが FunctionCall オブジェクトを処理するときに、それが実際にコンストラクター呼び出しであるかどうかを確認し、その場合は FunctionCall ノードを ConstructorCall ノードに置き換えます。次に、2 つのテンプレートを 2 つ用意します。

このアプローチについて私が気に入らないのは、分離しすぎているように感じられ、テンプレートごとに新しいクラスが必要になることです。

4

1 に答える 1

1

テンプレートとレンダリングされたフィールドは、実行時に変更できます。のインスタンスはModelRendererAST ノードごとに作成されるため、加えた変更はその単一の のレンダリングにのみ影響しますNode

def render_fields(self, fields):
   if self.is_constructor_call():
      self.template = self.constructor_template

割り当てはインスタンス変数に対するものであり、それClassName.templateは同じままであることに注意してください。

于 2016-12-05T11:30:56.733 に答える