2010-05-01 4 views
1

다음은 내 DSL의 Xtext 문법입니다.Xtext 기반 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' | ',')+; 

그리고 위의 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) 

Predicate 노드는 null getPredicateType() 수익률을 보여줍니다 생성 된 Switch 클래스의 내 서브 클래스입니다. 나는 위 프로그램에 해당하는 EMF 개체 모델을 통과하는 ModelPrinter 클래스를 사용하는 경우

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

} 

, 나는 노드가 제대로 서로 연결되지 않는 것을 깨달았다. 예를 들어 Predicate 노드의 getPredicateType() 메서드는 null을 반환합니다. Xtext 사용자 가이드를 읽었을 때, Xtext의 기본 연결 의미가 내 DSL에서 작동해야한다고 생각합니다. 그러나 어떤 이유로 DSL의 AST 노드가 제대로 연결되지 않습니다. 누구든지이 문제를 진단하는 데 나를 도울 수 있습니까?

답변

1

마지막으로, 문제를 파악했습니다. 모델을 제대로로드하지 않아 링크가 제대로 설정되지 않았습니다. 방금 파서를 사용하여 모델을로드했습니다. 그래서, 나는 링크를 얻지 못했습니다. 따라서 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); 
0

나는 그것을 사용해 봤지만 스위치에 익숙하지 않은 대신, Xpand/Xtend를 사용하여 Predicate에서 predicateTypes에 액세스하고 이름을 생성했습니다.

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 

나는이 예상되는 동작입니다 같아요.

+0

@Gabriel Ščerbák, 내 DSL에서 코드를 생성하고 싶지 않습니다. 대신, 필자는 입력 된 DSL 프로그램의 의미 론적 모델을 다른 도메인 모델로 변환하려고합니다. 링크가 올바르게 설정되지 않았 음을 나타내는 코드 조각으로 내 질문을 업데이트했습니다. – reprogrammer

+0

@reprogrammer 다른 질문에 대한 답변에서 언급했듯이 Xtend를 사용하여 모델 변환을 수행 할 수 있습니다 (메타 모델이 지원되는 한 동일한 메타 모델을 공유하는 경우 모델에서 모델로 변환 가능). 이제 Xpand의 일부가 된 것 같습니다.) 그리고 Java를 통한 접근 방식에 비해 몇 가지 장점이 있습니다. 그러나 Sebastian Zarnekow의 말을 듣고 좋은 질문을하면 그는 Xtext AFAIK의 핵심 개발자입니다. –