Skip to main content



      Home
Home » Modeling » TMF (Xtext) » Trying to generate DSL files using Java(I want to geenrate files following a DSL using a Java program)
Trying to generate DSL files using Java [message #1777723] Sat, 02 December 2017 18:09 Go to next message
Eclipse UserFriend
Hi !

I need to create a program able to generate files following a DSL i made using Xtext. I have some problems saving the file and I can't have it using my DSL syntax. The only thing I manage to obtain is a XMI file containing the data of the object.
My project is focusing on charts so my DSL extension is ".chart".

This part is where I instantiate a Java object containing the data :
	ChartPackage.eINSTANCE.eClass();
        ChartFactory factory = ChartFactory.eINSTANCE;
        Chart myChart = factory.createChart();
        myChart.setTitle("Population of countries");
        Data data = factory.createData();
        data.setType("Population (millions)");
        
        DataEntry entry1 = factory.createDataEntry();
        entry1.setName("France");
        entry1.getValues().add(66);
        data.getEntries().add(entry1);
        
        DataEntry entry2 = factory.createDataEntry();
        entry2.setName("Canada");
        entry2.getValues().add(31);
        data.getEntries().add(entry2);
        
        DataEntry entry3 = factory.createDataEntry();
        entry3.setName("USA");
        entry3.getValues().add(300);
        data.getEntries().add(entry3);
        
        myChart.setData(data);


And then I am able to create an XMI file using this :
        Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE;
        Map<String, Object> m = reg.getExtensionToFactoryMap();
        m.put("chart", new XMIResourceFactoryImpl());
        ResourceSet resSet = new ResourceSetImpl();
        Resource resource = resSet.createResource(URI
                .createURI("charts/test.chart"));
        resource.getContents().add(myChart);
        
        try {
            resource.save(Collections.EMPTY_MAP);
            System.out.println("File saved!");
        } catch (IOException e) {
            e.printStackTrace();
        }


The problem is that I want the data in my DSL syntax, not in XMI. I tried this code I found on the forum but it didn't work. The s variable is supposed to contains the text of the object following my syntax ;
        new ChartStandaloneSetup().createInjectorAndDoEMFRegistration();
        Injector injector = Guice.createInjector(new ChartRuntimeModule());  
        Serializer serializer = injector.getInstance(Serializer.class);
        String s = serializer.serialize(myChart);

When executing the previous code I have the following exception (ExecutionPerso is the name of the class where I have my main method) :
Exception in thread "main" java.lang.RuntimeException: No Context for Chart could be found
	at org.eclipse.xtext.serializer.impl.Serializer.getIContext(Serializer.java:165)
	at org.eclipse.xtext.serializer.impl.Serializer.serialize(Serializer.java:126)
	at org.eclipse.xtext.serializer.impl.Serializer.serialize(Serializer.java:178)
	at org.eclipse.xtext.serializer.impl.Serializer.serialize(Serializer.java:55)
	at ExecutionPerso.main(ExecutionPerso.java:62)


I also tried to write it that way :
		Injector injector = new ChartStandaloneSetup().createInjectorAndDoEMFRegistration();
		ResourceSet rs = injector.getInstance(ResourceSet.class);
		Resource r = rs.createResource(URI.createURI("charts/test2.chart"));
                r.getContents().add(myChart);
		try {
			r.save(null);
		} catch (IOException e) {
			e.printStackTrace();
		}

But I have the following exception :
Exception in thread "main" java.lang.NullPointerException: Invalid context: Chart returns Chart
	at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:787)
	at org.eclipse.xtext.serializer.sequencer.AbstractSyntacticSequencer.init(AbstractSyntacticSequencer.java:442)
	at org.eclipse.xtext.serializer.impl.Serializer.serialize(Serializer.java:111)
	at org.eclipse.xtext.serializer.impl.Serializer.serialize(Serializer.java:128)
	at org.eclipse.xtext.serializer.impl.Serializer.serialize(Serializer.java:192)
	at org.eclipse.xtext.resource.XtextResource.doSave(XtextResource.java:386)
	at org.eclipse.emf.ecore.resource.impl.ResourceImpl.save(ResourceImpl.java:1430)
	at org.eclipse.emf.ecore.resource.impl.ResourceImpl.save(ResourceImpl.java:999)
	at ExecutionPerso.main(ExecutionPerso.java:54)


Can you help me find what is the problem please ? Thank you !
Re: Trying to generate DSL files using Java [message #1777787 is a reply to message #1777723] Mon, 04 December 2017 10:58 Go to previous messageGo to next message
Eclipse UserFriend
can you please provide a complete hello would example?

Injector injector = new ChartStandaloneSetup().createInjectorAndDoEMFRegistration();
ResourceSet rs = injector.getInstance(ResourceSet.class);
Resource r = rs.createResource(URI.createURI("charts/test2.chart"));
r.getContents().add(myChart);
try {
r.save(null);
} catch (IOException e) {
e.printStackTrace();
}

should have worked (when this is te only thing you do)

[Updated on: Mon, 04 December 2017 10:59] by Moderator

Re: Trying to generate DSL files using Java [message #1777830 is a reply to message #1777787] Tue, 05 December 2017 02:10 Go to previous messageGo to next message
Eclipse UserFriend
Is the DSL's root element actually Chart or some other "Model" type?
Re: Trying to generate DSL files using Java [message #1836750 is a reply to message #1777723] Wed, 13 January 2021 05:23 Go to previous messageGo to next message
Eclipse UserFriend
I am also facing same exception with serialization. Has anyone got a fix for this issue.

Exception in thread "main" java.lang.NullPointerException: Invalid context: Chart returns Chart
at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:787)
at org.eclipse.xtext.serializer.sequencer.AbstractSyntacticSequencer.init(AbstractSyntacticSequencer.java:442)
Re: Trying to generate DSL files using Java [message #1836751 is a reply to message #1836750] Wed, 13 January 2021 05:26 Go to previous messageGo to next message
Eclipse UserFriend
can you provide a minimal reproducible testcase?
Re: Trying to generate DSL files using Java [message #1842059 is a reply to message #1836751] Tue, 08 June 2021 05:35 Go to previous messageGo to next message
Eclipse UserFriend
Hi Christian,

We are facing same issue with xText serializer when we try to save a file with our DSL syntax. We are creating our language construct programmatically and trying to save it to DSL file. But while saving it we are getting error from Serializer.

Here is a small example to reproduce this issue.
Grammar:
================================================
grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals

generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"

//the model is the root container
Model: {Model}(objects+=ModelObject)*;
//model objects
ModelObject:
//model element objects
Cstic
;
//each model object needs an ID
NameRule returns ModelObject: name = ID;

//ID with upper case only
terminal ID: ('^')?('A'..'Z'|'_') ('A'..'Z'|'_'|'0'..'9')*;

//the cstic
Cstic: ('characteristic'|'cstic') name = ID'{'
(
(desc = 'name' name=(STRING))? )'}';
===================================================

Java program to reproduce error:
===================================================
package com.sap.test;

import java.io.IOException;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.xtext.example.mydsl.MyDslStandaloneSetup;
import org.xtext.example.mydsl.myDsl.Cstic;
import org.xtext.example.mydsl.myDsl.MyDslFactory;
import com.google.inject.Injector;

public class TestSerialization {
public static void main(String[] args) {
Cstic newCstic = MyDslFactory.eINSTANCE.createCstic();
newCstic.setDesc("MyNewCstic");
newCstic.setName("MyNewCstic");
Injector injector = new MyDslStandaloneSetup().createInjectorAndDoEMFRegistration();
ResourceSet rs = injector.getInstance(ResourceSet.class);
Resource r = rs.createResource(URI.createURI("charts/test2.mydsl"));
r.getContents().add(newCstic);
try {
r.save(null);
System.out.println("saved successfully");
} catch (IOException e) {
System.out.println("failed with exception" + e);
e.printStackTrace();
}
}
}
=====================================================
Th exception we observed on save :
Exception in thread "main" java.lang.NullPointerException: Invalid context: Model returns Cstic
at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:897)
at org.eclipse.xtext.serializer.sequencer.AbstractSyntacticSequencer.init(AbstractSyntacticSequencer.java:442)
at org.eclipse.xtext.serializer.impl.Serializer.serialize(Serializer.java:114)
at org.eclipse.xtext.serializer.impl.Serializer.serialize(Serializer.java:131)
at org.eclipse.xtext.serializer.impl.Serializer.serialize(Serializer.java:201)
at org.eclipse.xtext.resource.XtextResource.doSave(XtextResource.java:386)
at org.eclipse.emf.ecore.resource.impl.ResourceImpl.save(ResourceImpl.java:1475)
at org.eclipse.emf.ecore.resource.impl.ResourceImpl.save(ResourceImpl.java:1044)
at com.sap.test.TestSerialization.main(TestSerialization.java:28)

Re: Trying to generate DSL files using Java [message #1842060 is a reply to message #1842059] Tue, 08 June 2021 05:53 Go to previous messageGo to next message
Eclipse UserFriend
you need to put a model to the resource, not a Cstic
Re: Trying to generate DSL files using Java [message #1842063 is a reply to message #1842059] Tue, 08 June 2021 06:31 Go to previous messageGo to next message
Eclipse UserFriend
Hello Christian,

We debugged the framework code to identify the issue, following is our observation on this.It is because the org.eclipse.xtext.serializer.impl.Serializer.getIContext(EObject semanticObject) method does not return the correct context. In case of above example for Cstic object it returns the context as "Model returns Cstic" (which is the root context), where as it should return the context as "ModelObject returns Cstic" which is there in the grammar. Because of this issue the serialization fails at later stage. The actual issue is with the following method of ContextFinder.

protected Iterable<ISerializationContext> findContextsByContainer(EObject sem, Iterable<ISerializationContext> contextCandidates) {
if (sem.eResource() != null && sem.eResource().getContents().contains(sem))
return Collections.singleton(getRootContext(sem));
.
.
The if condition here seems not to be correct and because of this it returns the root context instead of the actual context. When in debug mode we skip this condition(using force return),then the serialization works fine and the dsl file is generated as expected. Because when we force return then it finds the context using ContextFinder.findByContents(semanticObject, contextCandidates) which works fine.
Can you confirm if this is a framework error and could be fixed in future releases. We observed this issue with xtext 2.25 release as well.

Moreover we tried to find some way to override the behavior of ContextFinder methods, but unable to find any way to do this. Can you please help us with this.


Re: Trying to generate DSL files using Java [message #1842064 is a reply to message #1842060] Tue, 08 June 2021 06:40 Go to previous messageGo to next message
Eclipse UserFriend
Hello Christian,

Can you please elaborate more about the fix you are suggesting.
We were earlier using xText 2.7.3 and with that the same code was working fine. After we upgraded to latest xText version we are facing this issue.

[Updated on: Tue, 08 June 2021 06:42] by Moderator

Re: Trying to generate DSL files using Java [message #1842067 is a reply to message #1842064] Tue, 08 June 2021 08:29 Go to previous messageGo to next message
Eclipse UserFriend
Model: {Model}(objects+=ModelObject)*;

=>

Model m = MyDslFactory.eINSTANCE.createModel();
m.getObjects().add(newCstic);
r.getContents().add(m)

i have no overview what has changed over the last 20 Xtext versions
Re: Trying to generate DSL files using Java [message #1842077 is a reply to message #1842067] Tue, 08 June 2021 10:28 Go to previous messageGo to next message
Eclipse UserFriend
Hello Christian,

I did this change but the serialization is still failing, now with a different error.
Please see below my code and the exception I received.

public static void main(String[] args) {
Model model = MyDslFactory.eINSTANCE.createModel();
ModelObject newCstic = MyDslFactory.eINSTANCE.createCstic();
model.getObjects().add(newCstic);
((Cstic)newCstic).setDesc("MyNewCstic");
newCstic.setName("MyNewCstic");
Injector injector = new MyDslStandaloneSetup().createInjectorAndDoEMFRegistration();
ResourceSet rs = injector.getInstance(ResourceSet.class);
Resource r = rs.createResource(URI.createURI("charts/test2.mydsl"));
r.getContents().add(model);
try {
r.save(null);
}catch (IOException e) {
e.printStackTrace();
}
}

==============================================================
Error stacktrace:

Exception in thread "main" java.lang.RuntimeException: Could not serialize Cstic via backtracking.
Constraint: Cstic_Cstic returns Cstic: (name=ID (desc='name' name=STRING)?);
Values: name(1), desc(1)
Semantic Object: Model.objects[0]->Cstic'MyNewCstic'
URI: charts/test2.mydsl
Context: ModelObject returns Cstic
at org.eclipse.xtext.serializer.diagnostic.ISerializationDiagnostic$ExceptionThrowingAcceptor.accept(ISerializationDiagnostic.java:131)
at org.eclipse.xtext.serializer.sequencer.BacktrackingSemanticSequencer.createSequence(BacktrackingSemanticSequencer.java:513)
at org.xtext.example.mydsl.serializer.MyDslSemanticSequencer.sequence_Cstic(MyDslSemanticSequencer.java:60)
at org.xtext.example.mydsl.serializer.MyDslSemanticSequencer.sequence(MyDslSemanticSequencer.java:38)
at org.eclipse.xtext.serializer.sequencer.AbstractSemanticSequencer.createSequence(AbstractSemanticSequencer.java:67)
at org.eclipse.xtext.serializer.acceptor.SequenceFeeder.acceptEObjectRuleCall(SequenceFeeder.java:326)
at org.eclipse.xtext.serializer.acceptor.SequenceFeeder.acceptRuleCall(SequenceFeeder.java:353)
at org.eclipse.xtext.serializer.acceptor.SequenceFeeder.accept(SequenceFeeder.java:264)
at org.eclipse.xtext.serializer.sequencer.BacktrackingSemanticSequencer.accept(BacktrackingSemanticSequencer.java:444)
at org.eclipse.xtext.serializer.sequencer.BacktrackingSemanticSequencer.createSequence(BacktrackingSemanticSequencer.java:511)
at org.xtext.example.mydsl.serializer.MyDslSemanticSequencer.sequence_Model(MyDslSemanticSequencer.java:72)
at org.xtext.example.mydsl.serializer.MyDslSemanticSequencer.sequence(MyDslSemanticSequencer.java:41)
at org.eclipse.xtext.serializer.sequencer.AbstractSemanticSequencer.createSequence(AbstractSemanticSequencer.java:67)
at org.eclipse.xtext.serializer.impl.Serializer.serialize(Serializer.java:118)
at org.eclipse.xtext.serializer.impl.Serializer.serialize(Serializer.java:131)
at org.eclipse.xtext.serializer.impl.Serializer.serialize(Serializer.java:201)
at org.eclipse.xtext.resource.XtextResource.doSave(XtextResource.java:386)
at org.eclipse.emf.ecore.resource.impl.ResourceImpl.save(ResourceImpl.java:1475)
at org.eclipse.emf.ecore.resource.impl.ResourceImpl.save(ResourceImpl.java:1044)
at com.sap.test.TestSerialization.main(TestSerialization.java:26)
Re: Trying to generate DSL files using Java [message #1842080 is a reply to message #1842077] Tue, 08 June 2021 12:33 Go to previous messageGo to next message
Eclipse UserFriend
your grammar is ambigous

Cstic: ('characteristic'|'cstic') name = ID'{'
(
(desc = 'name' name=(STRING))? )'}';

is the double name intended?

also shouldnt the name be MYNEWCSTIC with that ID?

[Updated on: Tue, 08 June 2021 12:40] by Moderator

Re: Trying to generate DSL files using Java [message #1842081 is a reply to message #1842080] Tue, 08 June 2021 13:00 Go to previous messageGo to next message
Eclipse UserFriend
alternatively you can try to adapt serialization to deal with your very strange grammar

			serializer = {
				generateStub = true
			}


public class MyDslSemanticSequencer extends AbstractMyDslSemanticSequencer {
	
	@Inject MyDslGrammarAccess grammarAcess;
	
	@Override
	protected void sequence_Cstic(ISerializationContext context, Cstic semanticObject) {
		SequenceFeeder feeder = createSequencerFeeder(context, semanticObject);
		feeder.accept(grammarAcess.getCsticAccess().getNameIDTerminalRuleCall_1_0(), semanticObject.getName());
		if (semanticObject.getDesc() != null) {
			feeder.accept(grammarAcess.getCsticAccess().getDescNameKeyword_3_0_0(), semanticObject.getDesc());
			feeder.accept(grammarAcess.getCsticAccess().getNameSTRINGTerminalRuleCall_3_1_0(), semanticObject.getName());
			
		}
		feeder.finish();
	}
}
Re: Trying to generate DSL files using Java [message #1842095 is a reply to message #1842081] Wed, 09 June 2021 02:26 Go to previous messageGo to next message
Eclipse UserFriend
Hello Christian,

This is not the original grammar we have, it is just a small example I have created to reproduce the issue. The fix that you have suggested to add model to the resource instead of cstic worked fine for us. However the original issue we observed with serializer when we add cstic to resource, looks to be a bug and can be fixed in future releases.

The following fix resolved the issue.
Model m = MyDslFactory.eINSTANCE.createModel();
m.getObjects().add(newCstic);
r.getContents().add(m)

Thanks for your help.
Re: Trying to generate DSL files using Java [message #1842101 is a reply to message #1842095] Wed, 09 June 2021 06:15 Go to previous message
Eclipse UserFriend
i dont get this.
grammar does not say root can be cstic
maybe this was working on old version was a bug and fixed.
Previous Topic:How to import EOL for syntax highlighting
Next Topic:How to export custom hovers as plug in ?
Goto Forum:
  


Current Time: Thu Apr 24 23:50:46 EDT 2025

Powered by FUDForum. Page generated in 0.04300 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top