1

如何在ANTLR4中爲這樣定義的「if」語句發出分支代碼?ANTLR4:if語句的代碼生成

statement 
    : // stuff 
    | If LPar cond=expression RPar trueBlock=statement (Else falseBlock=statement)? # IfStatement 
    ; 

基本上,它就像在我用作參考的Java.g4例子(見「陳述」和「表達」規則)。

問題是,我無法弄清楚如何在偵聽器中發出分支代碼,並且我試圖避免在語法文件中添加任何{code}。例如,如果我EnterIfStatement,那麼發射分支還爲時尚早,因爲條件代碼尚未生成。當我ExitIfStatement,它已經太晚了,因爲整個如果塊代碼已經被創建。 ANTLR4不會創建任何EnterTrueBlock事件或類似的事情。

我想到了一些可能的解決方法,使用字典來記住上下文並在捕獲相關表達式時生成跳轉指令,但它並不自然。

回答

0

今天我瞭解到訪問者模式更適合編譯任務。

public override string VisitIfStatement(MylangParser.IfStatementContext context) 
{ 
    var hash = context.GetHashCode(); 
    Visit(context.cond); 
    var elseLabel = "else" + hash; 
    var endIfLabel = "end_if" + hash; 
    emitter.Emit(OpCode.Jiz, elseLabel); 
    if (context.trueBlock != null) 
    { 
     Visit(context.trueBlock); 
    } 
    emitter.Emit(OpCode.Jmp, endIfLabel); 
    emitter.Mark(elseLabel); 
    if (context.falseBlock != null) 
    { 
     Visit(context.falseBlock); 
    } 
    emitter.Mark(endIfLabel); 
    return null; 
}