Hi all. I have create grammar and codegenerator(see below), but I don't know how to detect brackets in my expression and add it to the generated expression. I.e. I want to make my test passed.
Why I can't just put the expression string? Just imagine that I want to change '&&' on 'AND' in the my expression.
My grammar
grammar org.casualintellect.CasualIntellect with org.eclipse.xtext.common.Terminals
generate casualIntellect "http://www.casualintellect.org/CasualIntellect"
Model:
list_of_states+=State+;
State:
'state' name=ID '{' before=ProcessBeforeState after=ProcessAfterState? inProcess=ProcessInState transitions=Transitions? '}';
Transitions:
'transitions' ':' '{' list+=Transition? (',' list+=Transition)* '}';
TransitionsList:
transitions+=Transition (';' transitions+=Transition)*;
Transition:
'transition' ':' name=ID ';' 'condition' ':' condition=Expression ';' ('methods' ':' methods+= ID (',' methods+=ID)*)?;
ProcessInState:
'in_process' ':' methods+=ID? (',' methods+=ID)* ';';
ProcessAfterState:
'after' ':' methods+=ID? (',' methods+=ID)* ';';
ProcessBeforeState:
'before' ':' methods+=ID? (',' methods+=ID)* ';';
Expression: Or;
Or returns Expression:
And ({Or.left=current} "||" right=And)*;
And returns Expression:
Primary ({And.left=current} "&&" right=Primary)*;
Primary returns Expression:
'(' Expression ')' |
{Not} "!" expression=Primary |
Atomic;
Atomic returns Expression:
{StringConstant} value=ID |
{BoolConstant} value=('true' | 'false');
My code generator
/*
* generated by Xtext
*/
package org.casualintellect.generator
import java.util.List
import org.casualintellect.casualIntellect.And
import org.casualintellect.casualIntellect.BoolConstant
import org.casualintellect.casualIntellect.Expression
import org.casualintellect.casualIntellect.Not
import org.casualintellect.casualIntellect.Or
import org.casualintellect.casualIntellect.State
import org.casualintellect.casualIntellect.StringConstant
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.xtext.generator.IFileSystemAccess
import org.eclipse.xtext.generator.IGenerator
/**
* Generates code from your model files on save.
*
* see http://www.eclipse.org/Xtext/documentation.html#TutorialCodeGeneration
*/
class CasualIntellectGenerator implements IGenerator {
override void doGenerate(Resource resource, IFileSystemAccess fsa) {
var states = "";
for (e : resource.allContents.toIterable.filter(typeof(State))) {
states = states + e.compile;
states = states + "\n"
}
fsa.generateFile("states/states" + ".xml", states)
}
def compile(State state) {
'''<state name="«state.name»">
<before methods="«if(state.before != null) processMethodsList(state.before.methods)»"/>
<after methods="«if(state.after != null) processMethodsList(state.after.methods)»"/>
<in_process methods="«if(state.inProcess != null) processMethodsList(state.inProcess.methods)»"/>
<transitions>«IF (state.transitions != null)»
«FOR transition : state.transitions.list»
<transition>
«FOR method : transition.methods»
<method>«method»</method>
«ENDFOR»
<condition function="«transition.condition.compile»"/>
</transition>
«ENDFOR»
«ENDIF»</transitions>
</state>'''
}
def compile(Expression expression) {
switch (expression) {
Or: {
compile(expression.left) + ' || ' + compile(expression.right);
}
And: {
compile(expression.left) + ' && ' + compile(expression.right);
}
Not: expression.expression.compile
BoolConstant:
Boolean::parseBoolean(expression.value)
StringConstant:
expression.value
}
}
def processMethodsList(List<String> methods) {
var methodsStr = "";
for (var i = 0; i < methods.length; i++) {
methodsStr = methodsStr + methods.get(i);
if (i < methods.length - 1) {
methodsStr += ',';
}
}
methodsStr;
}
}
Test what I want to be passed
@Test
def void testWithBrackets() {
'''state state1{
before: salo, pivo, vodka;
after:salo,pivo,vodka;
in_process:pivo, vodka, salo;
transitions: {transition:salo; condition:(f1 || f2)&&!false;}
}'''.
assertCompilesTo(
'''<state name="state1">
<before methods="salo,pivo,vodka"/>
<after methods="salo,pivo,vodka"/>
<in_process methods="pivo,vodka,salo"/>
<transitions>
<transition>
<condition function="(f1 || f2) && false"/>
</transition>
</transitions>
</state>
''')
}