为什么不将基于XTEXT的DSL中的工作链接起来?
-
02-10-2019 - |
题
以下是我的DSL的Xtext语法。
Model:
variableTypes=VariableTypes predicateTypes=PredicateTypes variableDeclarations=
VariableDeclarations rules=Rules;
VariableType:
name=ID;
VariableTypes:
'var types' (variableTypes+=VariableType)+;
PredicateTypes:
'predicate types' (predicateTypes+=PredicateType)+;
PredicateType:
name=ID '(' (variableTypes+=[VariableType|ID])+ ')';
VariableDeclarations:
'vars' (variableDeclarations+=VariableDeclaration)+;
VariableDeclaration:
name=ID ':' type=[VariableType|ID];
Rules:
'rules' (rules+=Rule)+;
Rule:
head=Head ':-' body=Body;
Head:
predicate=Predicate;
Body:
(predicates+=Predicate)+;
Predicate:
predicateType=[PredicateType|ID] '(' (terms+=Term)+ ')';
Term:
variable=Variable;
Variable:
variableDeclaration=[VariableDeclaration|ID];
terminal WS:
(' ' | '\t' | '\r' | '\n' | ',')+;
而且,以下是上述DSL中的程序。
var types
Node
predicate types
Edge(Node, Node)
Path(Node, Node)
vars
x : Node
y : Node
z : Node
rules
Path(x, y) :- Edge(x, y)
Path(x, y) :- Path(x, z) Path(z, y)
以下是我生成的子类 Switch
演示的课程 getPredicateType()
返回null Predicate
节点。
public class ModelPrinter extends MyDSLSwitch<Object> {
protected Object visitChildren(EObject object) {
for (EObject eobj : object.eContents()) {
doSwitch(eobj);
}
return object;
}
@Override
public Object casePredicate(Predicate object) {
System.out.println(object.getPredicateType());
return object;
}
@Override
public Object defaultCase(EObject object) {
return visitChildren(object);
}
}
当我使用 ModelPrinter
跨越与上述程序相对应的EMF对象模型的类,我意识到节点未正确链接在一起。例如, getPredicateType()
A上的方法 Predicate
节点返回 null
. 。阅读了Xtext用户指南后,我的印象是Xtext默认链接语义应该适用于我的DSL。但是,由于某种原因,我的DSL的AST节点无法正确链接在一起。谁能帮助我诊断这个问题?
解决方案
最后,我弄清楚了这个问题。由于我没有正确加载模型,因此无法正确设置链接。我刚刚使用解析器来加载模型。所以,我没有得到链接。因此,我使用了以下代码段 XTEXT FAQ 正确加载模型。然后,我将返回的模型传递给了我的交换机类。
// "workspace" is a string that contains the path to the workspace containing the DSL program.
new org.eclipse.emf.mwe.utils.StandaloneSetup().setPlatformUri(workspace);
Injector injector = new MyDslStandaloneSetup().createInjectorAndDoEMFRegistration();
XtextResourceSet resourceSet = injector.getInstance(XtextResourceSet.class);
resourceSet.addLoadOption(XtextResource.OPTION_RESOLVE_ALL, Boolean.TRUE);
// "DSLProgram" is a string that contains the path to the file of the DSL program relative to the workspace set above.
Resource resource = resourceSet.getResource(URI.createURI("platform:/resource/" + DSLProgram), true);
Model model = (Model) resource.getContents().get(0);
其他提示
我已经尝试了一下,但是我不熟悉开关,而宁愿使用Xpand/Xtend从谓词访问预型并生成其名称。
template.xpt:
«IMPORT myDsl»; «DEFINE main FOR Model-» «FILE "output.txt"-» «FOREACH this.rules.rules.body.last().predicates AS p-» «p.predicateType.name» «ENDFOREACH-» «ENDFILE-» «ENDDEFINE»
和output.txt:
Path Path
我想这是预期的行为。
不隶属于 StackOverflow