abs*_*abs 5 variables list definition xtext
我尝试根据以下语法定义一些 XText 来指定变量
variables
MyVar1 : Bool at 0x020 value=true;
MyVar2, MyVar3 : Int at 0x030 value 200;
end-variables
Run Code Online (Sandbox Code Playgroud)
所以每个定义在语法上都是
VarName ["," VarName]* ":" Type ["at" HEX]? ["value" VALUE]? ";"
Run Code Online (Sandbox Code Playgroud)
所有变量都应可通过其引用进行访问,大纲中的结果应如下所示:
variables
+-MyVar1 : Bool
+-MyVar2 : Int
+-MyVar3 : Int
Run Code Online (Sandbox Code Playgroud)
编辑: 按照这里的要求,我的实际语法,相当于上面几行的语法定义。
Variable:
name=ID
;
Declaration_Var:
'variables'
vars+=Declaration_Var_Body+
'end-variables' ';'
;
Declaration_Var_Body:
varDecl+=Variable(',' varDecl +=Variable)*
':' type=[TR_Any]
('at' address=HEX)?
;
TR_Any:
...
;
terminal HEX:
...
;
Run Code Online (Sandbox Code Playgroud)
这样,以下字符序列
variables
Test1, Test2, Test3 : DWORD at 0x20;
end_var;
Run Code Online (Sandbox Code Playgroud)
结果是这样的:
<unnamed>
+-- 0x20
| +-- Test1
| +-- Test2
| +-- Test3
Run Code Online (Sandbox Code Playgroud)
这几乎与我的预期相反。我期望的和我想要在大纲中生成的内容与此类似(数据类型和地址不得显示在那里,但至少它们必须可以作为变量声明的生成类的属性进行访问)
Test1
+-- DWORD
+-- 0x20
Test2
+-- DWORD
+-- 0x20
Test3
+-- DWORD
+-- 0x20
Run Code Online (Sandbox Code Playgroud)
请在此处查看涵盖您的案例的截屏视频:http://xtextcasts.org/episodes/18-model-optimization
您需要修改模型和元模型。要修改元模型,您需要定义一个后处理器。以下后处理器将type属性目录添加到Variable类中。
有关更多详细信息,请参阅:http://christiandietrich.wordpress.com/tag/postprocessor/
class MyXtext2EcorePostProcessor implements IXtext2EcorePostProcessor {
override process(GeneratedMetamodel metamodel) {
metamodel.EPackage.process
}
def process(EPackage p) {
for (clazz : p.EClassifiers.filter(typeof(EClass))) {
if (clazz.name == typeof(Variable).simpleName) {
val typeAttribute = EcoreFactory::eINSTANCE.createEAttribute
typeAttribute.name = "type"
typeAttribute.EType = EcorePackage::eINSTANCE.EString
clazz.EStructuralFeatures += typeAttribute
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后你必须Generator像这样绑定它扩展:
public class ExtendedGenerator extends Generator {
public ExtendedGenerator() {
new XtextStandaloneSetup() {
@Override
public Injector createInjector() {
return Guice.createInjector(new XtextRuntimeModule() {
@Override
public Class<? extends IXtext2EcorePostProcessor>
bindIXtext2EcorePostProcessor() {
return MyXtext2EcorePostProcessor.class;
}
});
}
}.createInjectorAndDoEMFRegistration();
}
}
Run Code Online (Sandbox Code Playgroud)
最后ExtendedGenerator在您的 mwe2 工作流程中使用新的:
...
Workflow {
...
bean = StandaloneSetup {
...
component = postprocessor.ExtendedGenerator { // Set ExtendedGenerator!
...
}
...
}
...
}
...
Run Code Online (Sandbox Code Playgroud)
然后你必须type用数据填充你的新属性。您可以通过实现IDerivedStateComputer接口来做到这一点。
class MyDerivedStateComputer implements IDerivedStateComputer {
override discardDerivedState(DerivedStateAwareResource resource) {
resource.allContents.filter(typeof(VariableDefinition)).forEach [
type = null
]
}
override installDerivedState(DerivedStateAwareResource resource,
boolean preLinkingPhase) {
resource.allContents.filter(typeof(VariableDefinition)).forEach [
type = (eContainer as DefinitionBlock).type
]
}
}
Run Code Online (Sandbox Code Playgroud)
然后你必须像这样绑定它(第二个和第三个绑定方法仅对于非 Xbase 项目是必需的)
public class MyDslRuntimeModule extends AbstractMyDslRuntimeModule {
public Class<? extends IDerivedStateComputer> bindIDerivedStateComputer() {
return MyDerivedStateComputer.class;
}
// Not needed for Xbase-projects
@Override
public Class<? extends XtextResource> bindXtextResource() {
return DerivedStateAwareResource.class;
}
// Not needed for Xbase-projects
public Class<? extends IResourceDescription.Manager>
bindIResourceDescriptionManager() {
return DerivedStateAwareResourceDescriptionManager.class;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以更进一步,即时重组模型以满足您的需求。如果您走得太远,请将您的解决方案作为单独的答案发布在这里。