简体   繁体   English

为什么链接在基于Xtext的DSL中不起作用?

[英]Why doesn't linking work in my Xtext-based DSL?

The following is the Xtext grammar for my DSL. 以下是我的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' | ',')+;

And, the following is a program in the above DSL. 并且,以下是上述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)

The following is my subclass of the generated Switch class that demonstrates the getPredicateType() returns null on a Predicate node. 以下是我生成的Switch类的子类,该类演示getPredicateType()Predicate节点上返回null。

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);
    }

}

When I used the ModelPrinter class to traverse the EMF object model corresponding to the above program, I realized that the nodes are not linked together properly. 当我使用ModelPrinter类遍历与上述程序相对应的EMF对象模型时,我意识到节点未正确链接在一起。 For example, the getPredicateType() method on a Predicate node returns null . 例如, Predicate节点上的getPredicateType()方法返回null Having read the Xtext user's guide, my impression is that the Xtext default linking semantics should work for my DSL. 阅读Xtext用户指南后,我的印象是Xtext默认链接语义应适用于我的DSL。 But, for some reason, the AST nodes of my DSL don't get linked together properly. 但是,由于某种原因,我的DSL的AST节点无法正确链接在一起。 Can anyone help me in diagnosing this problem? 谁能帮助我诊断这个问题?

Finally, I figured out the problem. 最后,我找出了问题所在。 The links were not set properly because I wasn't loading the model properly. 链接设置不正确,因为我没有正确加载模型。 I had just used the parser to load the model. 我刚刚使用解析器加载了模型。 So, I didn't get the links. 因此,我没有得到链接。 Therefore, I used the following code snippet from Xtext FAQ to load the model correctly. 因此,我使用了Xtext FAQ中的以下代码片段来正确加载模型。 Then, I passed the returned model to my switch class. 然后,我将返回的模型传递给我的switch类。

// "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);

I have tried it out, but I am not familiar with the Switch, I rather used Xpand/Xtend to access predicateTypes from Predicate and generated their names. 我已经尝试过了,但是我对Switch不熟悉,而是使用Xpand / Xtend从Predicate访问predicateType并生成它们的名称。

Template.xpt: 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»

and the output.txt: 和output.txt:

Path
Path

I guess this is the expected behaviour. 我想这是预期的行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM