使用 graco 生成上下文敏感代码
Context sensitve code generation with grako
我的情况是我已经使用 grako 的模型构建器语义构建了一个抽象语法树 (AST)。现在我需要从该 AST 生成 javascript 代码。我已经定义了几个模板,但我意识到并非所有情况都可以用简单的模板来处理。我坚持的具体规则是:
fcall::FunctionCall = name:identifier '(' ','.{args:expression} ')' ;
此规则同时匹配简单的函数调用和构造函数调用,因为无法从词法上确定哪个是哪个,这取决于该范围内是否定义了具有该名称的 class。
例如"a = Func();"
在 javascript 中,这两种情况需要不同的语法(“a = new Func();”或“a = Func();”)
所以我需要一个符号 table 来记录哪个是哪个。有没有办法用 grako 实现这个目标?
附加信息:
我对如何做到这一点的想法:
创建一个 walker class,构建一个符号 table,当它处理 FunctionCall 对象时,检查它是否实际上是一个构造函数调用,在这种情况下用 ConstructorCall 节点替换 FunctionCall 节点。那就干脆有两个模板吧。
我不喜欢这种方法的地方在于它感觉过于分离,并且每个模板都需要一个新的 class。
您可以在运行时更改模板和呈现的字段。因为 ModelRenderer
的实例是为每个 AST 节点创建的,所以您所做的更改只会影响单个 Node
:
的呈现
def render_fields(self, fields):
if self.is_constructor_call():
self.template = self.constructor_template
注意赋值给一个实例变量,ClassName.template
保持不变。
我的情况是我已经使用 grako 的模型构建器语义构建了一个抽象语法树 (AST)。现在我需要从该 AST 生成 javascript 代码。我已经定义了几个模板,但我意识到并非所有情况都可以用简单的模板来处理。我坚持的具体规则是:
fcall::FunctionCall = name:identifier '(' ','.{args:expression} ')' ;
此规则同时匹配简单的函数调用和构造函数调用,因为无法从词法上确定哪个是哪个,这取决于该范围内是否定义了具有该名称的 class。
例如"a = Func();"
在 javascript 中,这两种情况需要不同的语法(“a = new Func();”或“a = Func();”)
所以我需要一个符号 table 来记录哪个是哪个。有没有办法用 grako 实现这个目标?
附加信息:
我对如何做到这一点的想法: 创建一个 walker class,构建一个符号 table,当它处理 FunctionCall 对象时,检查它是否实际上是一个构造函数调用,在这种情况下用 ConstructorCall 节点替换 FunctionCall 节点。那就干脆有两个模板吧。
我不喜欢这种方法的地方在于它感觉过于分离,并且每个模板都需要一个新的 class。
您可以在运行时更改模板和呈现的字段。因为 ModelRenderer
的实例是为每个 AST 节点创建的,所以您所做的更改只会影响单个 Node
:
def render_fields(self, fields):
if self.is_constructor_call():
self.template = self.constructor_template
注意赋值给一个实例变量,ClassName.template
保持不变。