[英]Execution of extended Xbase interpreter leads to runtime exception
I am currently writing an interpreter for an Xtext language that extends Xbase. 我目前正在为扩展Xbase的Xtext语言编写解释器。
To do so I am inheriting from XbaseInterpreter, adding my own run
method and override the dispatch method doEvaluateProgram
with my new abstract concepts. 为此,我继承自XbaseInterpreter,添加了自己的run
方法并使用新的抽象概念覆盖了dispatch方法doEvaluateProgram
。
The problem arises in the interpretation of the CondStmt
. 问题出现在对CondStmt
的解释中。 Its semantics is to evaluate the exp XExpression
and call the stmts statements only if the evaluation of exp returns true. 它的语义是评估exp XExpression
并仅在exp评估返回true时才调用stmts语句。
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. 调用解释器时(例如下面的测试用例),exp XExpression
失败,并出现java.lang.IllegalArgumentException: Segment cannot be null
异常。
Both sides of the ==
statement, eg _inPort
and inSide
are supposed to be variables defined in the interpretation context using the newValue
method. ==
语句的两端(例如_inPort
和inSide
应该是使用newValue
方法在解释上下文中定义的变量。
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. PS:下面是完整的堆栈跟踪。
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 这是不使用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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.