I am currently writing an interpreter for an Xtext language that extends Xbase.
To do so I am inheriting from XbaseInterpreter, adding my own run
method and override the dispatch method doEvaluateProgram
with my new abstract concepts.
The problem arises in the interpretation of the CondStmt
. Its semantics is to evaluate the exp XExpression
and call the stmts statements only if the evaluation of exp returns true.
When the interpreter is called (let's say from the test case below), the evaluation of the exp XExpression
fails with a java.lang.IllegalArgumentException: Segment cannot be null
exception.
Both sides of the ==
statement, eg _inPort
and inSide
are supposed to be variables defined in the interpretation context using the newValue
method.
I'm guessing the runtime error has something to do with a failure to identify the type and/or the value of the variables, but I can't figure out how to fix this issues.
PS: The full stack trace below.
The grammar:
grammar MyLang with org.eclipse.xtext.xbase.Xbase
generate mylang "http://MyLang"
import "http://www.eclipse.org/xtext/xbase/Xbase" as xbase
// ...
CondStmt returns xbase::XExpression:
{CondStmt} "cond" "(" exp=XExpression "," stmts+=Stmt* ")";
// ...
The interpreter
class MyLangInterpreter extends XbaseInterpreter {
val indicator = CancelIndicator.NullImpl
def run(MyProgram program) {
// ...
val context = this.createContext
// ...
val newContext = context.fork
newContext.newValue(QualifiedName.create("_inPort"), "something"))
myElement.doEvaluate(newContext, indicator)
// ...
}
def dispatch doEvaluateProgram(MyElem elem, IEvaluationContext context, CancelIndicator indicator) {
// ...
}
def dispatch doEvaluateProgram(CondStmt condStmt, IEvaluationContext context, CancelIndicator indicator) {
val exp = this.evaluate(condStmt.exp, context, indicator)
if (Boolean.TRUE == exp) {
condStmt.stmts.map [
this.internalEvaluate(it, context, indicator)
].last
}
}
}
The test case
@RunWith(XtextRunner)
@InjectWith(GpflInjectorProvider)
class GpflInterpreterTest {
@Inject private extension ParseHelper<Program> parseHelper
@Inject private extension GpflInterpreter
@Test
def test1() {
val program = '''
// ...
cond(_inPort == inSide,
// ...
)
// ....
'''.parse
val res = program.run
// ...
}
}
The stack trace
java.lang.IllegalArgumentException: Segment cannot be null
at org.eclipse.xtext.naming.QualifiedName.create(QualifiedName.java:203)
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._invokeFeature(XbaseInterpreter.java:1008)
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeFeature(XbaseInterpreter.java:993)
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:901)
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:864)
at mylang.MyLangInterpreter.doEvaluate(GpflInterpreter.java:414)
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203)
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:900)
at mylang.MyLangInterpreter.doEvaluate(GpflInterpreter.java:450)
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203)
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluate(XbaseInterpreter.java:189)
at mylang.MyLangInterpreter._doEvaluate(GpflInterpreter.java:314)
at mylang.MyLangInterpreter.doEvaluate(GpflInterpreter.java:430)
at mylang.MyLangInterpreter.lambda$3(GpflInterpreter.java:263)
at mylang.MyLangInterpreter$$Lambda$13/974320615.accept(Unknown Source)
at java.lang.Iterable.forEach(Iterable.java:75)
at mylang.MyLangInterpreter.run(GpflInterpreter.java:265)
at fr.mleduc.gpfl.tests.MyLangInterpreterTest.test1(GpflInterpreterTest.java:113)
...
here is an example of loading the model without parsehelper
@RunWith(XtextRunner)
@InjectWith(DomainmodelInjectorProvider)
class DullyTest{
@Inject Provider<XtextResourceSet> rsp
@Inject ValidationTestHelper helper
@Test
def void xxxxx() {
val rs = rsp.get
rs.classpathURIContext = DullyTest
val r = rs.createResource(URI.createURI("dummy.dmodel"))
val text = '''
entity Person {
op xxxx() {
1==1
}
}
'''
r.load(new StringInputStream(text), null)
helper.assertNoIssues(r)
val m = r.contents.head as DomainModel
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.