Xtext/EMF how to do model-to-model transform? - dsl

I have a DSL in Xtext, and I would like to reuse the rules, terminals, etc. defined in my .xtext file to generate a configuration file for some other tool involved in the project. The config file uses syntax similar to BNF, so it is very similar to the actual Xtext content and it requires minimal transformations. In theory I could easily write a script that would parse Xtext and spit out my config...
The question is, how do I go about implementing it so that it fits with the whole ecosystem? In other words - how to do a Model to Model transform in Xtext/EMF?

If you have both metamodels(ecore,xsd,...), your best shot is to use ATL ( http://www.eclipse.org/atl/ ).

If I understand you correct you want to go from an xtext model to its EMF model. Here is a code example that achieves this, substitute your model specific where necessary.
public static BeachScript loadScript(String file) throws BeachScriptLoaderException {
try {
Injector injector = new BeachStandaloneSetup().createInjectorAndDoEMFRegistration();
XtextResourceSet resourceSet = injector.getInstance(XtextResourceSet.class);
resourceSet.addLoadOption(XtextResource.OPTION_RESOLVE_ALL, Boolean.TRUE);
Resource resource = resourceSet.createResource(URI.createURI("test.beach"));
InputStream in = new ByteArrayInputStream(file.getBytes());
resource.load(in, resourceSet.getLoadOptions());
BeachScript model = (BeachScript) resource.getContents().get(0);
return model;
} catch (Exception e) {
throw new BeachScriptLoaderException("Exception Loading Beach Script " + e.toString(),e );
}

Related

How to write scripts to keep punctuation in Stanford dependency parser

In order to get some specific dependency information I write a java script to parse sentences rather than directly use ParserDemo.java that Stanford Parser 3.9.1 provided. But I found punctuation is missing after got typedDependencies. Is there any function to get punctuation in Stanford Parser?
I had to write a script to parse sentences myself for the reason that I need to create a SemanticGraph from a List of TypedDependencies, in order to use methods in SemanticGraph to get evey single tokens dependent information(include punctuation).
public class ChineseFileTest3 {
public static void main(String[] args){
String modelpath = "edu/stanford/nlp/models/lexparser/xinhuaFactored.ser.gz";
LexicalizedParser lp = LexicalizedParser.loadModel(modelpath);
String textFile = "data/chinese-onesent-unseg-utf8.txt";
demoDP(lp,textFile);
}
public static void demoDP(LexicalizedParser lp, String filename){
for(List<HasWord> sentence : new DocumentPreprocessor(filename)) {
Tree t = lp.apply(sentence);
ChineseGrammaticalStructure gs = new ChineseGrammaticalStructure(t);
Collection<TypedDependency> tdl = gs.typedDependenciesCollapsed();
System.out.println(tdl);
}
}
}
I would suggest not using the parser standalone but instead just running a pipeline. That will maintain the punctuation.
There is comprehensive documentation about using the Java API for pipelines here:
https://stanfordnlp.github.io/CoreNLP/api.html
You need to set the properties for Chinese. A quick way to do that is with this line of code
Properties props = StringUtils.argsToProperties("-props", "StanfordCoreNLP-chinese.properties");

How to use Apache OpenNLP in a node.js application

What is the best way to use Apache Open NLP with node.js?
Specifically, I want to use Name Entity Extraction API. Here is what is says about it - the documentation is terrible (new project, I think):
http://opennlp.apache.org/documentation/manual/opennlp.html#tools.namefind
From the docs:
To use the Name Finder in a production system its strongly recommended
to embed it directly into the application instead of using the command
line interface. First the name finder model must be loaded into memory
from disk or an other source. In the sample below its loaded from
disk.
InputStream modelIn = new FileInputStream("en-ner-person.bin");
try {
TokenNameFinderModel model = new TokenNameFinderModel(modelIn);
}
catch (IOException e) {
e.printStackTrace();
}
finally {
if (modelIn != null) {
try {
modelIn.close();
}
catch (IOException e) {
}
}
}
There is a number of reasons why the model loading can fail:
Issues with the underlying I/O
The version of the model is not compatible with the OpenNLP version
The model is loaded into the wrong component, for example a tokenizer
model is loaded with TokenNameFinderModel class.
The model content is not valid for some other reason
After the model is loaded the NameFinderME can be instantiated.
NameFinderME nameFinder = new NameFinderME(model);
The initialization is now finished and the Name Finder can be used.
The NameFinderME class is not thread safe, it must only be called from
one thread. To use multiple threads multiple NameFinderME instances
sharing the same model instance can be created. The input text should
be segmented into documents, sentences and tokens. To perform entity
detection an application calls the find method for every sentence in
the document. After every document clearAdaptiveData must be called to
clear the adaptive data in the feature generators. Not calling
clearAdaptiveData can lead to a sharp drop in the detection rate after
a few documents. The following code illustrates that:
for (String document[][] : documents) {
for (String[] sentence : document) {
Span nameSpans[] = find(sentence);
// do something with the names
}
nameFinder.clearAdaptiveData()
}
the following snippet shows a call to find
String sentence = new String[]{
"Pierre",
"Vinken",
"is",
"61",
"years"
"old",
"."
};
Span nameSpans[] = nameFinder.find(sentence);
The nameSpans arrays contains now exactly one Span which marks the
name Pierre Vinken. The elements between the begin and end offsets are
the name tokens. In this case the begin offset is 0 and the end offset
is 2. The Span object also knows the type of the entity. In this case
its person (defined by the model). It can be retrieved with a call to
Span.getType(). Additionally to the statistical Name Finder, OpenNLP
also offers a dictionary and a regular expression name finder
implementation.
Checkout this NodeJS library.
https://github.com/mbejda/Node-OpenNLP
https://www.npmjs.com/package/opennlp
Just do NPM install opennlp
And look at the examples on the Github.
var nameFinder = new openNLP().nameFinder;
nameFinder.find(sentence, function(err, results) {
console.log(results)
});

The Cucumber JVM's (Groovy) "World (Hooks)" object mixin and Intellij navigation

I am developing cucumber scenarios using Cucumber JVM (Groovy) in intellij. Things are much better than doing the same in eclipse I must say.
I'd like to resolve one small problem to make things even better for my team. But since I am new to Intellij, I need help with the following please:
When I am in a step def file (groovy), Intellij can't seem to see variables and methods defined in the cucumber "World" object. So don't get IDE support (auto-complete, etc) for those which is a bit annoying. How can I fix that?
IntelliJ IDEA expects an object inside World closure. So, you could define the folloing block in EACH step definitions file:
World {
new MockedTestWorld()
}
MockedTestWorld.groovy:
class MockedTestWorld implements TestWorld {
#Lazy
#Delegate
#SuppressWarnings("GroovyAssignabilityCheck")
private TestWorld delegate = {
throw new UnsupportedOperationException("" +
"Test world mock is used ONLY for syntax highlighting in IDE" +
" and must be overridden by concrete 'InitSteps.groovy' implementation.")
}()
}
To cleanup duplicated world definitions we use last-glue initializers and a bit of copy-paste:
real/InitSteps.groovy
def world
GroovyBackend.instance.#worldClosures.clear()
GroovyBackend.instance.registerWorld {
return world ?: (world = new RealTestWorld1()) // Actual initialization is much longer
}
legacy/InitSteps.groovy
def world
GroovyBackend.instance.#worldClosures.clear()
GroovyBackend.instance.registerWorld {
return world ?: (world = new LegacyTestWorld1())
}
Finally, run configurations would be like this (with different glues):
// Real setup
glue = { "classpath:test/steps", "classpath:test/real", },
// Legacy setup
glue = { "classpath:test/steps", "classpath:test/legacy", },

DSL Add Root Element to Serialization

I am looking for help to achieve the following
The Diagram represents a car, users can add engine and colour
when I view the XML it looks like this:
<Car>
<Engine>BigEngine</Engine>
<Colour>Pink</Colour>
</Car>
What I would like to do is to wrap the car inside 'vehicle', i.e
<Vehicle>
<Car>
<Engine>BigEngine</Engine>
<Colour>Pink</Colour>
</Car>
</Vehicle>
I am not sure of the best way to achieve this. I want the model explorer and the generated XML to be wrapped in 'vehicle' but for all other intents and purposes the user is working with a car only
Info: Visual Studio 2010, C# and DSL SDK for 2010
I would try two different approaches:
1st: override DSL Package class DocData
In DocData.cs file and override method
protected override void OnDocumentSaved(System.EventArgs e)
and then I would create the wrapper
afterwards I'd override in DocData.cs
protected override void OnDocumentLoading(System.EventArgs e)
and before calling the base method base.OnDocumentLoading(e); i would delete from the file.
2nd: Under DSL Explorer go to XML Serialization Behaviour and set Car Domain Class "Is Custom = true".
This solution is not straightforward but it's not as complicated as it seems at the first place. You'll must define every single method but for each custom method you can call a DSL generated method called "DefaulMethod" which has the default DSL serializer behaviour.
I am currently using VS 2005, so some things might have changed...
I have fixed this by the following. I am double deriving the Car class and in the Car serializer I am doing this:
Writing the extra elements:
public partial class CarSerializer : CarSerializerBase
{
public override void Write(SerializationContext serializationContext, ModelElement element, XmlWriter writer, RootElementSettings rootElementSettings)
{
// Adds the Model and LobSystem root elements to match that required by the SharePoint BCS
writer.WriteStartElement("Garage");
writer.WriteStartElement("Cars");
base.Write(serializationContext, element, writer, rootElementSettings);
writer.WriteEndElement();
writer.WriteEndElement();
}
}
To be able to read this back in I am overriding the Car LoadModel method in the SerializationHelper and where it is getting the reader I am reading the elements until I get to Car.
....
XmlReader reader = XmlReader.Create(fileStream, settings);
reader.MoveToContent();
while (!reader.EOF && !reader.Name.Equals("Car"))
{
reader.Read();
}
reader = reader.ReadSubtree();
// using (global::System.Xml.XmlReader reader = global::System.Xml.XmlReader.Create(fileStream, settings))
using (reader)
{
....

SubSonic2.2 SharedDbConnectionScope and TransactionScope Transaction Confusion

ARGH!!!
There seems to be a little confusion surrounding the SharedDbConnectionScope and TransactionScope objects to enable wrapping your SubSonic queries within a transaction.
The docs suggest specifying the using SharedDbConnectionScope wrapped around the using TransactionScope...
using(SharedDbConnectionScope scope = new SharedDbConnectionScope())
{
using(TransactionScope ts = new TransactionScope())
{
// do something
ts.Complete();
}
}
Then other question here such as Subsonic: Using SharedDbConnectionScope together with TransactionScope seems to be broken suggest the docs are wrong and the two objects should be the other way around...
using(TransactionScope ts = new TransactionScope())
{
using(SharedDbConnectionScope scope = new SharedDbConnectionScope())
{
// do something
ts.Complete();
}
}
But looking into the source code I am even more confused.
In the SqlQuery.cs code file it has a number of ExecuteTransaction overloads. For example...
public static void ExecuteTransaction(List<SqlQuery> queries)
{
using(SharedDbConnectionScope scope = new SharedDbConnectionScope())
{
using(TransactionScope ts = new TransactionScope())
{
foreach(SqlQuery q in queries)
q.Execute();
}
}
}
Umm... Interesting... Matches the docs but... Where's the ts.Complete() call?
How is that supposed to commit the transaction? As far as I can see it will always rollback. And it is the same for all the ExecuteTransaction overloads!
But here is the real kicker...
In the TransactionWithDtcOffTests.cs code has some nice tests except they have set up the SharedDbConnectionScope and TransactionScope around the other way!
using(TransactionScope ts = new TransactionScope())
{
using(SharedDbConnectionScope connScope = new SharedDbConnectionScope())
{
// <snip />
}
}
I haven't had the opportunity to run the tests for SubSonic 2.2 but I assume someone has and they passed..
Finally...
Can someone give me the definitive answer to how Transactions in SubSonic2.2 should be set up? Are the docs indeed wrong? Does the source for the ExecuteTransaction overloads and tests be aligned to whichever way is actually correct?
The SharedConnectionScope (SCS) block must be inside a TransactionScope (TS).
The purpose of the SCS is to prevent escalating the transaction to the MSDTC if possible, so having the TS using block inside of a SCS using block makes little sense to me.
In any case, every TS block must have a Complete() call for the transaction to be committed.
Personally i found that when using SQL 2005, SCS must be inside TS
and when using SQL 2000 (with MSDTC), SCS must wrap TS.
I hope this helps...

Resources