def _case_statement(self, ast, pt): expr_pt, statement_pt = pt.children expr_ast = get_expression(ast, expr_pt, self) statements_ast = self._statements(ast, statement_pt) return Node(ast, 'case', children = [expr_ast] + statements_ast)
def _statements(self, ast, pt): """ Returns a list of parsed statements from "ast". """ results = None while pt.name == 'statement': pt = pt.children[0] if pt.name == 'jump_statement': results = [self._jump_statement(ast, pt)] elif pt.name == 'expression': results = [get_expression(ast, pt, self)] elif pt.name == 'selection_statement': results = [self._selection_statement(ast, pt)] elif pt.name == 'case_statement': results = [self._case_statement(ast, pt)] elif pt.name == 'default_statement': results = [self._default_statement(ast, pt)] elif pt.name == 'iteration_statement': results = [self._iteration_statement(ast, pt)] elif pt.name == 'compound_statement': results = self._compound_statement(ast, pt) elif pt.name == 'declaration': results = self.declaration(ast, pt) elif pt.name == 'asm_block': results = [UnfinishedNode('asm_block')] elif pt.name == 'blank': results = [] else: pt.print_tree() raise Exception("Unknown statement '%s'" % (pt.name)) return results
def _iteration_statement_while(self, ast, pt): expr_pt, statement_pt = pt.children expr_ast = get_expression(ast, expr_pt, self) statements_ast = Node(ast, "body", source = statement_pt) statements_ast.add_children(self._statements(statements_ast, statement_pt)) return Node(ast, 'while', [expr_ast, statements_ast], source = pt)
def _selection_statement_switch(self, ast, pt): """ Handle "switch" statement. See caller for more info. Output of type switch expression (to switch on) expression (actions) """ # FIXME: Do we handle fall-through switching at all? expr_pt, cases_pt = pt.children expr_ast = get_expression(ast, expr_pt, self) statements_ast = self._statements(ast, cases_pt) return Node(ast, 'switch', children = [expr_ast] + statements_ast)
def _iteration_statement_for(self, ast, pt): init_pt, while_pt, post_pt, body_pt = pt.children # init_pt is an expression or a declaration. if init_pt.name == 'blank': init_ast = Node(ast, 'blank') elif self._is_declaration(init_pt): init_ast = self.declaration(init_pt) else: init_ast = [get_expression(ast, init_pt, self)] if while_pt.name != 'blank': while_ast = get_expression(ast, while_pt, self) else: while_ast = Node(ast, 'blank') if post_pt.name != 'blank': post_ast = get_expression(ast, post_pt, self) else: post_ast = Node(ast, 'blank') body_ast = self._statements(ast, body_pt) return Node(ast, 'for', init_ast + [while_ast, post_ast] + body_ast)
def _selection_statement_if(self, ast, pt): """ Handle "if" statement. See caller for more info. """ condition_pt = pt.children[0] cases_pt = pt.children[1] expr_ast = get_expression(ast, condition_pt, self) statements_ast = Node(ast, "body", source = cases_pt) if_ast = Node(ast, 'if', [expr_ast, statements_ast], source = pt) statements_ast.add_children(self._statements(statements_ast, cases_pt)) # Handle "else" cases. else_clause_pt = pt.get_child('else') if else_clause_pt: else_statements_pt = else_clause_pt.child() else_clause_ast = Node(if_ast, 'else', source = else_clause_pt) if_ast.add_child(else_clause_ast) statements_list = self._statements(else_clause_ast, else_statements_pt) else_clause_ast.add_children(statements_list) return if_ast
def getExpression(self, parent_ast, pt): """ Convert a parse-tree expression to an IDLAST exprsesion. Does not evaluate the expression. """ return astexpr.get_expression(parent_ast, pt)
def init_declarator(self, parentast, pt): """ Return an init_declarator node. We used to return: name expression result indirection This now becomes a Node with name "name", child "expression", attribute "indirection", a result, and possibly other children """ decl = Node(None, 'declarator') if pt.name == 'member_declarator_bitfield': decl.leaf = pt.leaf decl.add_child(pt.get_child('expression')) try: decl.result = evaluate(pt.get_child('expression'), parentast) except Exception: decl.result = pt.get_child('expression').result elif pt.name == 'attribute': attribute_pt = pt.children[0] # FIXME: Attribute support decl.set_name('attribute') decl.set_leaf(attribute_pt.name) elif pt.name in ("init_declarator", "member_declarator"): indirection = '' # Now we want this: # declarator * # direct_declarator ID # # ... or any of these : # direct_declarator ID <- function declaration # parameter_list # type_qualifier # exception_specification # direct_declarator ID <- class instantation / array declaration # expression # direct_declarator ID <- ? # declarator <- function ptr # declarator_suffixes decl_pt = pt.get_child('declarator') direct_decl_pt = pt.get_child('direct_declarator') decl_suffixes_pt = None # We want to get to a direct_declarator if it exists. This is a convoluted # process -- probably best to refer to the relevant grammar section. while decl_pt is not None: if decl_pt.leaf == '*': indirection += '*' direct_decl_pt = decl_pt.get_child('direct_declarator') if direct_decl_pt: break else: decl_pt = decl_pt.get_child('declarator') assert decl_pt decl.add_attribute('indirection', indirection) # Now we are down to direct_declarator. if direct_decl_pt.has_child('declarator'): # This is a function pointer - we don't support these too well. decl_pt = direct_decl_pt.get_child('declarator') direct_decl_pt = decl_pt.get_child('direct_declarator') decl.leaf = direct_decl_pt.leaf expr = pt.get_child('expression') if not expr and pt.has_child('initializer'): expr = pt.get_child('initializer').get_child('expression') ast_expr = None if expr: ast_expr = get_expression(parentast, expr, self) if ast_expr: decl.add_child(ast_expr) return decl