开发者

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

开发者 https://www.devze.com 2022-12-29 01:18 出处:网络
The following is the Xtext grammar for my DSL. Model: variableTypes=VariableTypes predicateTypes=PredicateTypes variableDeclarations=

The following is the Xtext grammar for my DSL.

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.

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.

public class ModelPrinter extends MyDSLSwitch<Object> {

    protected Object visitChildren(EObject objec开发者_如何学Got) {
        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. For example, the getPredicateType() method on a Predicate node returns null. Having read the Xtext user's guide, my impression is that the Xtext default linking semantics should work for my DSL. But, for some reason, the AST nodes of my DSL don't get linked together properly. 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. Then, I passed the returned model to my switch class.

// "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.

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:

Path
Path

I guess this is the expected behaviour.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号