[英]Execution of extended Xbase interpreter leads to runtime exception
我目前正在為擴展Xbase的Xtext語言編寫解釋器。
為此,我繼承自XbaseInterpreter,添加了自己的run
方法並使用新的抽象概念覆蓋了dispatch方法doEvaluateProgram
。
問題出現在對CondStmt
的解釋中。 它的語義是評估exp XExpression
並僅在exp評估返回true時才調用stmts語句。
調用解釋器時(例如下面的測試用例),exp XExpression
失敗,並出現java.lang.IllegalArgumentException: Segment cannot be null
異常。
==
語句的兩端(例如_inPort
和inSide
應該是使用newValue
方法在解釋上下文中定義的變量。
我猜測運行時錯誤與無法識別變量的類型和/或值有關,但是我不知道如何解決此問題。
PS:下面是完整的堆棧跟蹤。
語法:
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* ")";
// ...
口譯員
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
}
}
}
測試用例
@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
// ...
}
}
堆棧跟蹤
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)
...
這是不使用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.