在我的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
我知道如何解析条件跳转等于等等,我知道解析方法将是递归的..但我不知道如何实现这个解析方法..我不需要代码,只是一个想法,如何管理它。
感谢您的帮助。
答案 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?。