error running JSON2XML_ST - antlr4

i try to run JSON2XML_ST ike this:
bab#maz:~/tpantlr2-code/code/listeners$ antlr4 JSON.g4
bab#maz:~/tpantlr2-code/code/listeners$ javac JSON2XML_ST.java
bab#maz:~/tpantlr2-code/code/listeners$ java JSON2XML_ST t.json
but a i got :
(json (object { (pair "description" : (value "An imaginary server config file")) ,
(pair "logs" : (value (object { (pair "level" : (value "verbose")) , (pair "dir" :
(value "/var/log")) }))) , (pair "host" : (value "antlr.org")) , (pair "admin" : (value
(array [ (value "parrt") , (value "tombu") ]))) , (pair "aliases" : (value (array [
]))) }))
Exception in thread "main" java.lang.IllegalArgumentException: No such group file: XML.stg
at org.stringtemplate.v4.STGroupFile.<init>(STGroupFile.java:69)
at org.stringtemplate.v4.STGroupFile.<init>(STGroupFile.java:48)
at JSON2XML_ST$XMLEmitter.<init>(JSON2XML_ST.java:45)
at JSON2XML_ST.main(JSON2XML_ST.java:140)
why ?? can anybody help me? thank you.

This is an XML.stg that can be used with JSON2XML_ST.java. The source download still doesn't contain XML.stg. It is however a good learning exercise to come up with this file yourself. It was for me.
group XML;
empty() ::= ""
value(x) ::= "<x>"
object(fields) ::= <<
<fields; separator="\n">
>>
enclose_element(x) ::= <<
\<element><x>\</element>
>>
array(values) ::= <<
<values:enclose_element(); separator="\n">
>>
tag(name,content) ::= <<
\<<name>\><content>\</<name>\>
>>

The problem is that XML.stg is not part of the source. i.e. when you run the example the file XML.stg does not exist and therefore cannot be found, hence the error of No such group file.
Exception in thread "main" java.lang.IllegalArgumentException: No such group file: XML.stg
This seems to be a known problem and has been reported in the ANTLR errata:
http://pragprog.com/titles/tpantlr2/errata
50831:
There is a reference to JSON2XML_ST.java source which uses StringTemplate for XML translation. But in the source code itself there is reference to the XML.stg file which absent in the book source archive.
JSON2XML_ST.java (line 45):
STGroup templates = new STGroupFile("XML.stg");
It would be nice if you put it to archive, since (IMHO) it's not very easy to find it elsewhere.
Thanks.
There is a reference to xml.stg here: http://www.antlr.org/wiki/plugins/viewsource/viewpagesrc.action?pageId=16220704 which you could use.
Create a new file and call it XML.stg and put in the following contents:
group XML;
file(props) ::= <<
\<properties>
<props; separator="\n">
\</properties>
>>
prop(ID,v) ::= "\<property id=\"<ID>\"><v>\</property>"
Then rerun the example as you already have and it might work.

Related

How to populate Map in Drools ResponseObject

I have an object defined in .drl :
package drools.types
declare ResponsibilityManager
#propertyReactive
internal : java.lang.Long
attr1 : java.lang.String
band : java.lang.Long
resourceMap : java.util.HashMap
end
My Rule is also defined in DRL :
package drools.rules
import drools.types.*
rule "Third Test Rule"
dialect "mvel"
salience 0
no-loop true
when
$var : ResponsibilityManager( band > 4 )
then
modify($var) { attr1 = "hidden";}
modify($var) { getResourceMap().put("action","edit");}
end
Rule is getting compiled correctly, however when I execute the Rule from my Java application I am getting "NullPointerException" in that line :
modify($var) { getResourceMap().put("action","edit");}
I am able to update and return "attr1" property.
How do I update the Map in the Rule?
Well, clearly the resourceMap was never instantiated.
When you create the ResponsibilityManager, you need to make sure to create the resourceMap inside of it as well.
rule "Whatever creates the ResponsibilityManager instance"
when
// ...
then
ResponsibilityManager r = new ResponsibilityManager();
r.setResourceMap(new HashMap());
// set other fields
insert(r);
end
Then you can modify it normally without getting a null pointer.
Alternatively you could overwrite the value entirely, something like ...
rule "Example with overwrite"
when
$var: ResponsibilityManager( band > 4, $resources: resourceMap != null )
then
$resources.put("new value", "example");
modify($var) {
setAttr1("hidden"),
setResourceMap($resources)
}
end
(Of course you'll need to make sure your resourceMap is instantiated already because of that null-check.)

How to know how much of the same structure i have to parse

I am trying to parse this using ANTLR4 :
FSM
name type String
state type State
Relation
name type String
Mathieu
name type String
Someone helped me, corrected my grammar and i got this thanks to him
grammar Generator;
parse
: classToGenerate+ EOF;
classToGenerate
: name=Name attributes+;
attributes
: attribute=Name 'type' type=Name;
Name : [a-zA-Z]+;
Spaces : [ \t\r\n] -> skip;
I am using the parser generated by ANTLR4 this way :
GeneratorLexer l = new GeneratorLexer(new ANTLRInputStream(GeneratorFactory.class.getResourceAsStream("/example.generator")));
GeneratorParser p = new GeneratorParser(new CommonTokenStream(l));
p.addParseListener(new GeneratorBaseListener() {
#Override public void exitClassToGenerate(GeneratorParser.ClassToGenerateContext ctx) {
System.out.println(ctx.name.getText());
}
#Override
public void exitAttributes(GeneratorParser.AttributesContext ctx) {
System.out.println(ctx.type.getText());
System.out.println(ctx.attribute.getText());
}
});
Here is the result after executing
String
name
State
state
FSM
Where is the rest ?
It didn't print Relation name String // Mathieu name String
Any idea ?
EDIT : Okay it seems i was able to print the rest of the files but i've still have something to figure out.
When i do :
p.classToGenerate();
It parses the first structure which results in the print i had.
If i want to find another structure i need to do another
p.classToGenerate();
The thing is, how should i know how much structure i have to parse?
Imagine i have 5 or 20 same structures, how can i know it ?
Thanks !
In your grammar you've called your main rule parse. The rule classToGenerate only matches a single class. So in order to match all classes in the file, you should call p.parse();, not p.classToGenerate();.

Does positive assert message exist in Groovy?

There is a Negative Groovy Assert with Message like:
def name = "John"
assert name == "Peter" : "Name should be John"
Which gives output:
Caught: java.lang.AssertionError: Name should be John. Expression: (name == Peter). Values: name = John
java.lang.AssertionError: Name should be John. Expression: (name == Peter). Values: name = John
But if the statement is true there is no information in the log. So when you (or your coworker) checks the log later (coworker does not know the checks you implemented) you have no idea about assertions which had place.
So I'd like to log positive assertions. Something like (adding positive message ? "Name is " + name):
def name = "Peter"
assert name == "Peter" : "Name should be John" ? "Name is " + name
Does it exists? I know I can log message after the assertion e.g.: log("Assert is correct: Name is " + name) but I'd like to do it in one line assertion.
There is no such thing like positive assertion message, because it does not make much sense in general. Let's consider example you have posted:
assert name == "Peter" : "Name should be John" ? "Name is " + name
When expression name == "Peter" evaluates to false it is straightforward what happens - java.lang.AssertionError is thrown with message Name should be John. Positive branch in this case is not straightforward - where does the message Name is ${name} should be log to? Using simple println or maybe using slf4j's log.info() or log.debug? Where is explicit decision about that? And what if I don't want to have such information in my logs, because it only produces overhead?
Of course you could define your own method like:
void doAssert(boolean expr1, String errorMessage, Closure<Void> onSuccess = null) {
assert expr : errorMessage
onSuccess?.call()
}
and then do:
doAssert name == "Peter", "Name should be John", {
log.info("Name is ${name}")
}
but in long term this might be an overkill - you create a closure object only for some debugging information. You can always modify this method and comment out onSuccess?.call() to limit some overhead created while calling a closure, although closure's object (and related Java anonymous class) gets created anyway.
But I guess you see that above method requires exactly same amount of effort as:
assert name == "Peter" : "Name should be John"
log.info("Name is ${name}")
I would rather suggest to use assertions as they were designed and don't produce much overhead. You can always log important information, but it has to be something that makes sense for maintainers. I don't see much value in getting informed that specific assertion was satisfied - I know that because program continued computations. Hope it helps you making right decision.

Issues adding source code to a custom DSL file programatically

I currently have a xtext grammar that looks like the following :
Features:
'feature' name = ID
'{'(
('action' '{' action+=Actions (',' action+=Actions)* '}')? &
('dependencies' '{' dependencies = Dependencies '}')? &
('children' '{' children = Children '}')?
)'}'
;
What I want to do with this is add an action to an already existing source file programatically, for that I am using the IUnitOfWork.Void class that I subclass for easier implementation , it currently looks like this (the meaningful part of it) :
final XtextEditor editor = (XtextEditor)sourcepart;
final IXtextDocument document = editor.getDocument();
document.modify(new IUnitOfWork.Void<XtextResource>(){
public void process (XtextResource resource) throws Exception {
IParseResult parseResult = resource.getParseResult();
if(parseResult ==null)
return;
CompositeNode rootNode=(CompositeNode) parseResult.getRootNode();
LeafNode node = (LeafNode)NodeModelUtils.findLeafNodeAtOffset(rootNode, 0);
EObject object =NodeModelUtils.findActualSemanticObjectFor(node);
Through this I traverse the tree of the model and get to my Features object to which I want to add an action to (this is done through a pop up menu in a custom Tree View I'm implementing)
Here's my problem : whenever I want to add an action it screws up the way the tags are placed in the source file , and by that I mean that instead of :
action {
act1.set (foo),
act2.set (bar),
act3.set (baz),
act4.set (booze) //where this is the new action that I add
}
it will add it as
action {
act1.set (foo),
act2.set (bar),
act3.set (baz)
}
action {
act4.set(booze)
}
And this is illegal by the rules of my grammar, and I'm not allowed to change the way it should be written. (I am allowed to make small changes to the way the rules are implemented, but would really want to avoid it as it would mean a whole new amount of work to reimplement other things that depend on them)
I've tried :
adding it directly through Features.getAction().add(*the new action);
copying the items in the list into an array with the toArray() method so as to avoid referencing, adding my action to the array, clearing the list then adding all the elements again one by one
creating an entirely new Features object and setting everything in it to be the same as the currently edited one then replacing the feature with the new one
And I'm out of ideas after that. The frustrating part is that the 3rd method worked for a different kind of object in my grammar and had no errors there.
How could I make this work ?
this is a bug in xtext. (can you please file a ticket?)
as a workaround you may use the following
Features:
'feature' name = ID
'{'(
('action' '{' actionList=ActionList '}')? &
('dependencies' '{' dependencies = Dependencies '}')? &
('children' '{' children = Children '}')?
)'}';
ActionList:
(action+=Action (',' action+=Action)*)
;

JetBrains MPS Shapes tutorial error

I've been following the JetBrains MPS Shapes tutorial:
https://confluence.jetbrains.com/display/MPSD32/Shapes+-+an+introductory+MPS+tutorial
In the tutorial section "A more robust generation for Squares" there is the following definition:
template reduce_Square
input Square
parameters
<< ... >>
content node:
{
Graphics g = null;
<TF {
->$g.setColor(Color.->$red);
->$g.drawRect($10, $10, $10, $10);
} TF>
}
And the reference macro for g (which you can see in the Inspector part of the editor if you put the cursor at ->$g) is:
(outputNode, genContext, operationContext, node)->join(node<VariableDeclaration> | string) {
genContext.get output graphicParam for (node.parent : Canvas);
}
Yet when trying to rebuild the "Shapes" language I get the following error message (4 times, twice for each ->$g):
type node<> is not a subtype of node<VariableDeclaration>
Could you please check that you specify the from and to concepts for the mapping label correctly? It should be
"label graphicsParam : Canvas -> ParameterDeclaration", as specified in the tutorial.

Resources