Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
If statement ANTLR4:if语句的代码生成_If Statement_Compiler Construction_Code Generation_Antlr_Antlr4 - Fatal编程技术网

If statement ANTLR4:if语句的代码生成

If statement ANTLR4:if语句的代码生成,if-statement,compiler-construction,code-generation,antlr,antlr4,If Statement,Compiler Construction,Code Generation,Antlr,Antlr4,如何为ANTLR4中定义的“if”语句发出分支代码 statement : // stuff | If LPar cond=expression RPar trueBlock=statement (Else falseBlock=statement)? # IfStatement ; 基本上,它就像我用作参考的示例一样(请参见“语句”和“表达式”规则) 问题是,我不知道如何在侦听器中为它发出分支代码,我试图避免在语法文件中添加任何{code}。例如,如果IEnterIf

如何为ANTLR4中定义的“if”语句发出分支代码

statement
    : // stuff
    | If LPar cond=expression RPar trueBlock=statement (Else falseBlock=statement)? # IfStatement
    ;
基本上,它就像我用作参考的示例一样(请参见“语句”和“表达式”规则)

问题是,我不知道如何在侦听器中为它发出分支代码,我试图避免在语法文件中添加任何{code}。例如,如果I
EnterIfStatement
,那么发出分支还为时过早,因为条件代码尚未生成。当I
ExitIfStatement
时,为时已晚,因为整个if块代码已经创建。ANTLR4不会创建任何
EnterTrueBlock
事件或类似事件


我想到了一些可能的解决方法,使用字典来记住上下文,并在捕获相关表达式时生成跳转指令,但这感觉并不自然。

今天,我了解到访问者模式更适合编译任务

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;
}