0

在我的 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

我知道如何将条件解析为 jump-if-equal 等等,我知道解析方法将是递归的..但我不知道如何实现这个解析方法..我不需要代码,只需一个想法,如何管理这个。

谢谢你的帮助。

4

1 回答 1

2

目前还不清楚你在问什么。据我了解,您在解析源代码或生成代码时遇到了一些问题。

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

在您的示例中,您将拥有一个用于解析逻辑表达式、if 语句、表达式/语句块和 if 语句的函数。当您if在令牌流中看到 时,您就知道后面跟着一个 if 语句,因此您可以调用适当的解析函数,比如parse_if. 由于语法parse_if知道并且if语句应该看起来像if (<logical expression>) <block> [else <block>]--方括号表示可选块,有角度的块是强制性的。因此,您首先递归调用用于解析逻辑表达式的函数,例如parse_logical_exp. 这将返回 if 语句的逻辑表达式的 AST 节点,您可以稍后将其插入最终的 AST。then 块也是如此。如果,在你完成 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)

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

您可能提到的问题称为“悬空其他问题”。基本上你不能告诉如果一个 else 属于哪个。引用维基百科文章:

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

对于代码生成部分,您可能对以下问题的回答感兴趣:在字节码编译器中计算跳转地址的智能解决方案?.

于 2012-11-04T07:07:02.520 回答