def build_for_statement(self, tree): if tree.getChildCount() < 6: raise RuntimeError("invalid FOR statement: '" + tree.getText() + "'") token = tree.getChild(0).getPayload() # for开头 if not isinstance(token, Token) or token.type != CXLexer.FOR: raise RuntimeError("Invalid FOR statement: '" + tree.getText() + "'") token = tree.getChild(1).getPayload() if not isinstance(token, Token) or token.type != CXLexer.LEFTPARENTHESIS: raise RuntimeError("Invalid FOR statement: '" + tree.getText() + "'") token = tree.getChild(tree.getChildCount() - 2).getPayload() if not isinstance(token, Token) or token.type != CXLexer.RIGHTPARENTHESIS: raise RuntimeError("Invalid FOR statement: '" + tree.getText() + "'") child_index = 2 semicolon_index = 0 init_expression = Expression(None) check_expression = Expression(None) update_expression = Expression(None) while True: token = tree.getChild(child_index).getPayload() if isinstance(token, Token): if token.type == CXLexer.RIGHTPARENTHESIS: break # index=2为分号表示初始语句为空 elif token.type == CXLexer.SEMICOLON: semicolon_index += 1 child_index += 1 if semicolon_index > 2: raise RuntimeError("Invalid FOR statement: '" + tree.getText() + "'") else: raise RuntimeError("Invalid FOR statement: '" + tree.getText() + "'") else: if semicolon_index == 0: init_expression = self.build_expression( tree.getChild(child_index)) elif semicolon_index == 1: check_expression = self.build_expression( tree.getChild(child_index)) else: update_expression = self.build_expression( tree.getChild(child_index)) child_index += 1 self.symbol_table.open_scope() statement = self.build_compound_statement( tree.getChild(tree.getChildCount() - 1)) self.symbol_table.close_scope() return ForStatement(init_expression, check_expression, update_expression, statement, self.symbol_table)
def buildForStatement(self, tree): """Build For Statement""" # FOR LPAREN expression? SEMICOLON expression? SEMICOLON expression? RPAREN statement if (tree.getChildCount() < 6): raise RuntimeError("invalid FOR statement: `" + tree.getText() + "`") # Check if FOR at front token = tree.getChild(0).getPayload() if (not isinstance(token, Token) or token.type != CLexer.FOR): raise RuntimeError("Invalid FOR statement: '" + tree.getText() + "'") # Check if LPAREN at front token = tree.getChild(1).getPayload() if (not isinstance(token, Token) or token.type != CLexer.LPAREN): raise RuntimeError("Invalid FOR statement: '" + tree.getText() + "'") # Check for RPAREN token = tree.getChild(tree.getChildCount() - 2).getPayload() if (not isinstance(token, Token) or token.type != CLexer.RPAREN): raise RuntimeError("Invalid FOR statement: '" + tree.getText() + "'") childIndex = 2 semicolonIndex = 0 initExpression = Expression(None) checkExpression = Expression(None) updateExpression = Expression(None) while (True): token = tree.getChild(childIndex).getPayload() if (isinstance(token, Token)): if (token.type == CLexer.RPAREN): break elif (token.type == CLexer.SEMICOLON): semicolonIndex += 1 childIndex += 1 if (semicolonIndex > 2): raise RuntimeError("Invalid FOR statement: '" + tree.getText() + "'") else: raise RuntimeError("Invalid FOR statement: '" + tree.getText() + "'") else: if (semicolonIndex == 0): initExpression = self.buildExpression( tree.getChild(childIndex)) elif (semicolonIndex == 1): checkExpression = self.buildExpression( tree.getChild(childIndex)) else: updateExpression = self.buildExpression( tree.getChild(childIndex)) childIndex += 1 # build statement self.sym.openScope() statement = self.buildStatement(tree.getChild(tree.getChildCount() - 1)) self.sym.closeScope() return ForStatement(initExpression, checkExpression, updateExpression, statement, self.sym)