如何在JAPE语法的纯Java代码块中使用模板?
JAPE语法中Java代码块无法使用模板的解决方案
问题说明
在JAPE语法里使用模板时,发现模板仅能在常规规则结构中生效,放到规则右侧的Java代码块里就完全不起作用。
可行的常规结构示例
Phase: FooPhase Input: Token Options: control=Appelt Template: variable_name = "testing" Rule: foo_1 ( {Token.string == "foo"} ):annot --> :annot.Foo = {var_name = [variable_name]}
Java代码块中失效的示例
Phase: FooPhase Input: Token Options: control=Appelt Template: variable_name = "testing" Rule: foo_1 ( {Token.string == "foo"} ):annot --> : annot{ FeatureMap newFeatures = Factory.newFeatureMap(); newFeatures.put("var_name", [variable_name]); outputAS.add(bindings.get("annot").firstNode(),bindings.get("annot").lastNode(),"Foo", newFeatures); }
解决办法
JAPE的模板机制**只支持在规则右侧的常规特征赋值语法(:annot.Type = {key = [template]})**中使用,Java代码块里没法直接用[variable_name]引用模板变量。要在Java代码块里复用模板值,有两种实用方式:
- 通过前置规则把模板值存入临时标注特征
先写一个前置规则,将模板值绑定到临时标注的特征上,再在目标规则的Java代码块里读取这个特征值:
Phase: FooPhase Input: Token Options: control=Appelt Template: variable_name = "testing" # 前置规则:存储模板值到临时标注 Rule: store_template_val ( {Token.string == "foo"} ):annot --> :annot.TempMarker = {temp_var = [variable_name]} # 主规则:从临时标注读取模板值 Rule: foo_1 ( {Token.string == "foo", TempMarker.temp_var != null} ):annot --> : annot{ FeatureMap tempFeatures = bindings.get("annot").firstNode().getFeatures(); String templateValue = tempFeatures.get("temp_var").toString(); FeatureMap newFeatures = Factory.newFeatureMap(); newFeatures.put("var_name", templateValue); outputAS.add(bindings.get("annot").firstNode(),bindings.get("annot").lastNode(),"Foo", newFeatures); }
- 在Java代码块中直接定义常量替代模板
如果模板值是固定字符串,直接在Java代码里定义常量,效果和模板完全一致:
Phase: FooPhase Input: Token Options: control=Appelt Rule: foo_1 ( {Token.string == "foo"} ):annot --> : annot{ final String VARIABLE_NAME = "testing"; // 用常量替代模板 FeatureMap newFeatures = Factory.newFeatureMap(); newFeatures.put("var_name", VARIABLE_NAME); outputAS.add(bindings.get("annot").firstNode(),bindings.get("annot").lastNode(),"Foo", newFeatures); }
原理补充
JAPE的模板是编译器预处理阶段解析的语法糖,只会在规则右侧的特征赋值表达式中被替换展开。而Java代码块会被当作原生Java代码直接处理,编译器不会对其中的[variable_name]做模板解析,自然无法识别。
内容的提问来源于stack exchange,提问作者Nicholas Sunderland
相关产品推荐
相关产品推荐

