有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么链接在我基于XTEXT的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' | ',')+;

下面是上述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()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);
    }

}

当我使用ModelPrinter类遍历与上述程序对应的EMF对象模型时,我意识到节点没有正确地链接在一起。例如,Predicate节点上的getPredicateType()方法返回null。阅读了《Xtext用户指南》,我的印象是Xtext默认链接语义应该适用于我的DSL。但是,由于某些原因,我的DSL的AST节点没有正确地连接在一起。有人能帮我诊断这个问题吗


共 (2) 个答案

  1. # 1 楼答案

    最后,我解决了这个问题。链接设置不正确,因为我没有正确加载模型。我刚刚使用了解析器来加载模型。所以,我没有得到链接。因此,我使用了来自Xtext FAQ的以下代码片段来正确加载模型。然后,我将返回的模型传递给我的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);
    
  2. # 2 楼答案

    我已经试过了,但我不熟悉这个开关,而是使用Xpand/Xtend从谓词访问谓词类型并生成它们的名称

    模板。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»
    

    以及输出。txt:

    Path
    Path
    

    我想这是意料之中的行为