2015-12-23 26 views
0

我有一個XText語法的特定部分,它定義了一個應該打印所有表達式的類的塊。造成這種情況的XTEXT語法部分如下所示:XText - 獲取XExpression的內容(編譯值)

Print: 
    {Print} 
    'print' '{' 
     print += PrintLine* 
    '}'; 
PrintLine: 
    obj += XExpression; 

現在我用下面的推斷器代碼來創建一個print()方法:

Print: { 
    members += feature.toMethod('print', typeRef(void)) [ 
    body = ''' 
     «FOR printline : feature.print» 
      System.out.println(«printline.obj»); 
     «ENDFOR» 
     ''' 
    ] 
} 

好吧,我繼續前進,用下面的測試代碼A類:

print { 
    "hallo" 
    4 
    6 + 7 
} 

而結果是:

public void print() { 
    System.out.println([[email protected] (value: hallo)]); 
    System.out.println([[email protected] (value: 4)]); 
    System.out.println([<XNumberLiteralImpl> + <XNumberLiteralImpl>]);} 

當然,我希望的:

public void print() { 
    System.out.println("hallo"); 
    System.out.println(4); 
    System.out.println(6+7); 
} 

我明白,我有可能以某種方式調用編譯器的推斷器爲«printline.obj»,但我真的不知道怎麼樣。

回答

2

我認爲你是在錯誤的基礎上做這件事。這聽起來像是對xbase的擴展,不僅僅是一個簡單的用法。

import "http://www.eclipse.org/xtext/xbase/Xbase" as xbase 

Print: 
    {Print} 
    'print' 
     print=XPrintBlock 
    ; 

XPrintBlock returns xbase::XBlockExpression: 
    {xbase::XBlockExpression}'{' 
     expressions+=XPrintLine* 
    '}' 
; 

XPrintLine returns xbase::XExpression: 
    {PrintLine} obj=XExpression 

; 

型計算機

class MyDslTypeComputer extends XbaseTypeComputer { 

    def dispatch computeTypes(XPrintLine literal, ITypeComputationState state) { 
     state.withNonVoidExpectation.computeTypes(literal.obj) 
     state.acceptActualType(getPrimitiveVoid(state)) 
    } 

} 

編譯

class MyDslXbaseCompiler extends XbaseCompiler { 

    override protected doInternalToJavaStatement(XExpression obj, ITreeAppendable appendable, boolean isReferenced) { 
     if (obj instanceof XPrintLine) { 
      appendable.trace(obj) 
      appendable.append("System.out.println(") 
      internalToJavaExpression(obj.obj,appendable); 
      appendable.append(");") 
      appendable.newLine 
      return 
     } 

     super.doInternalToJavaStatement(obj, appendable, isReferenced) 
    } 

} 

XExpressionHelper

class MyDslXExpressionHelper extends XExpressionHelper { 

    override hasSideEffects(XExpression expr) { 
     if (expr instanceof XPrintLine || expr.eContainer instanceof XPrintLine) { 
      return true 
     } 
     super.hasSideEffects(expr) 
    } 

} 

JvmModelInferrer

def dispatch void infer(Print print, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) { 
    acceptor.accept(
     print.toClass("a.b.C") [ 
      members+=print.toMethod("demo", Void.TYPE.typeRef) [ 
       body = print.print 
      ] 
     ] 

    ) 
} 

綁定

class MyDslRuntimeModule extends AbstractMyDslRuntimeModule { 

    def Class<? extends ITypeComputer> bindITypeComputer() { 
     MyDslTypeComputer 
    } 

    def Class<? extends XbaseCompiler> bindXbaseCompiler() { 
     MyDslXbaseCompiler 
    } 

    def Class<? extends XExpressionHelper> bindXExpressionHelper() { 
     MyDslXExpressionHelper 
    } 
} 
+0

嗨基督徒,那只是我需要的東西!感謝這個真棒聖誕禮物:) –

+0

嗨,基督徒,我剛剛遇到了這個解決方案的一個問題。當我使用「<=」比較器時,出現問題。這意味着當我使用例如「print {4 <= 5}」時,我得到一個錯誤,指出「在輸入'<='」時沒有可行的選擇。這很奇怪,因爲所有其他比較器都可以正常工作。 –

+0

您確定xbase lib位於模型項目的類路徑中嗎? –