Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    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 23:09 Go to next message
Thibaut BERNARD is currently offline Thibaut BERNARDFriend
Messages: 1
Registered: December 2017
Junior Member
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 15:58 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14664
Registered: July 2009
Senior Member
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)


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de

[Updated on: Mon, 04 December 2017 15:59]

Report message to a moderator

Re: Trying to generate DSL files using Java [message #1777830 is a reply to message #1777787] Tue, 05 December 2017 07:10 Go to previous messageGo to next message
Karsten Thoms is currently offline Karsten ThomsFriend
Messages: 762
Registered: July 2009
Location: Dortmund, Germany
Senior Member

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 10:23 Go to previous messageGo to next message
Prerana Doshi is currently offline Prerana DoshiFriend
Messages: 7
Registered: October 2019
Junior Member
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 10:26 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14664
Registered: July 2009
Senior Member
can you provide a minimal reproducible testcase?

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Trying to generate DSL files using Java [message #1842059 is a reply to message #1836751] Tue, 08 June 2021 09:35 Go to previous messageGo to next message
Prerana Doshi is currently offline Prerana DoshiFriend
Messages: 7
Registered: October 2019
Junior Member
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 09:53 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14664
Registered: July 2009
Senior Member
you need to put a model to the resource, not a Cstic

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Trying to generate DSL files using Java [message #1842063 is a reply to message #1842059] Tue, 08 June 2021 10:31 Go to previous messageGo to next message
Prerana Doshi is currently offline Prerana DoshiFriend
Messages: 7
Registered: October 2019
Junior Member
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 10:40 Go to previous messageGo to next message
Prerana Doshi is currently offline Prerana DoshiFriend
Messages: 7
Registered: October 2019
Junior Member
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 10:42]

Report message to a moderator

Re: Trying to generate DSL files using Java [message #1842067 is a reply to message #1842064] Tue, 08 June 2021 12:29 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14664
Registered: July 2009
Senior Member
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


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Trying to generate DSL files using Java [message #1842077 is a reply to message #1842067] Tue, 08 June 2021 14:28 Go to previous messageGo to next message
Prerana Doshi is currently offline Prerana DoshiFriend
Messages: 7
Registered: October 2019
Junior Member
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 16:33 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14664
Registered: July 2009
Senior Member
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?


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de

[Updated on: Tue, 08 June 2021 16:40]

Report message to a moderator

Re: Trying to generate DSL files using Java [message #1842081 is a reply to message #1842080] Tue, 08 June 2021 17:00 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14664
Registered: July 2009
Senior Member
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();
	}
}


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Trying to generate DSL files using Java [message #1842095 is a reply to message #1842081] Wed, 09 June 2021 06:26 Go to previous messageGo to next message
Prerana Doshi is currently offline Prerana DoshiFriend
Messages: 7
Registered: October 2019
Junior Member
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 10:15 Go to previous message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14664
Registered: July 2009
Senior Member
i dont get this.
grammar does not say root can be cstic
maybe this was working on old version was a bug and fixed.


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Previous Topic:How to import EOL for syntax highlighting
Next Topic:How to export custom hovers as plug in ?
Goto Forum:
  


Current Time: Tue Apr 16 08:51:57 GMT 2024

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

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

Back to the top