如何解析If-Else括号

时间:2012-11-03 17:55:02

标签: assembly compiler-construction if-statement

在我的C编程语言中,我希望编译器解析If-Else括号。我有一些代码:

if( varA == varB ) {
  if ( varB == varC ) {
   varA = 1;
  } else {
   varB = 1;
  }
};

并希望它解析为这个(虚构的汇编程序):

compare varA with varB
jump if equal to condition_2
jump to else_condition2  ; gets only executed if statement above does not get executed -> else

label condition_2:
compare varB with varC
jump if equal to if_bracket_1
jump to else_bracket_1

label if_bracket_1:
varA = 1;
jump to back_label

label else_bracket_1:
varB = 1;
jump to back_label 

label else_condition2: 
; nothing, because there is no else

label back_label:
nop ; continue main program here

我知道如何解析条件跳转等于等等,我知道解析方法将是递归的..但我不知道如何实现这个解析方法..我不需要代码,只是一个想法,如何管理它。

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

你所要求的并不是很清楚。根据我的理解,您在解析源代码或生成代码时遇到一些问题。

对于解析部分,如果您想手动编写,可以轻松使用recursive descent技术。基本上你编写解析每个语法类的函数 - 例如。表达式,块,if,while和for等语句。你让他们递归地互相打电话。通常,解析器函数返回AST节点,调用者将它们组合在一个更大的节点中。

在您的示例中,您将拥有一个用于解析逻辑表达式,if语句,表达式/语句块和if语句的函数。当您在令牌流中看到if时,您知道后面会出现if语句,因此您调用了相应的解析函数,例如parse_if。感谢语法parse_if知道if语句应该看起来像if (<logical expression>) <block> [else <block>] - 方括号表示一个可选块,有角度的块是强制性的。所以你首先递归调用函数来解析逻辑表达式,比如parse_logical_exp。这将返回AST节点,用于if语句的逻辑表达式,稍后您可以将其插入到最终的AST中。那个块也一样。如果在完成then块之后,在令牌流中遇到else,则再次调用块解析函数。如果没有任何子函数发出错误信号,那么您最终可以为if语句构建AST并将其返回给调用者。在(Python)伪代码中:

def parse_if(tokens):
    # Skip over the if token or signal an error if the current token is not an "if"
    tokens.expect("if")
    logical_condition = parse_logical_exp(tokens)
    if logical_condition is Error:
        raise ParseError(logical_condition.message)
    then_block = parse_block(tokens)
    if then_block is Error:
        raise ParseError(then_block.message)
    else_block = None
    if tokens.current() == "else":
        # Skip over the else token or signal an error
        tokens.expect("else")
        else_block = parse_block(tokens)
        if else_block is Error:
            raise ParseError(else_block.message)
    return IfNode(logical_condition, then_block, else_block)

请注意,这只是一些伪代码,您可能希望以不同的方式进行错误检查/报告。

您可能指的问题称为"dangling else problem"。基本上你不知道一个别人属于哪个。引用维基百科文章:

  

处理悬空的其他约定是将else附加到附近的if语句,特别是允许明确的无上下文语法。像Pascal和C这样的编程语言遵循这个约定,因此语言的语义没有歧义

对于代码生成部分,您可能对此问题的回复感兴趣:Intelligent solution to computing jump addresses in a bytecode compiler?