def handle_if(): ice9_parser_global.logger.debug("Entering handle_if") stmt_node = ice9_node.stmt_node() stmt_node.rule = 'IF' # The condition expression expr_node = ice9_parser_expressions.expr(None) if expr_node.return_data_type != 'bool': print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, \ "if condition must return a 'bool'" sys.exit() if expr_node.dimension != 0: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, \ "if condition cannot be a array variable, must return a 'bool'" sys.exit() stmt_node.condition = expr_node if ice9_parser_global.tok.type == 'ARROW': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting '->'" sys.exit() if ice9_parser_statements.in_first_of_statement(): stmt_node.pre_child = ice9_parser_statements.statements() else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting a statement" sys.exit() if ice9_parser_global.tok.type == 'BOX': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) stmt_node.post_child = elseif_or_else() if ice9_parser_global.tok.type == 'FI': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting fi" sys.exit() ice9_parser_global.logger.debug("Exiting handle_if") return stmt_node
def do(): ice9_parser_global.logger.debug("Entering do") ice9_parser_global.loop_depth += 1 stmt_node = ice9_node.stmt_node() stmt_node.rule = 'DO' stmt_node.condition = ice9_parser_expressions.expr(None) if stmt_node.condition.return_data_type != 'bool': print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, \ "if condition must return a 'bool'" sys.exit() if stmt_node.condition.dimension != 0: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, \ "if condition cannot be a array variable, must return a 'bool'" sys.exit() if ice9_parser_global.tok.type == 'ARROW': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting '->'" sys.exit() stmt_node.pre_child = ice9_parser_statements.statements() if ice9_parser_global.tok.type == 'OD': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting od" sys.exit() ice9_parser_global.loop_depth -= 1 ice9_parser_global.logger.debug("Exiting do") return stmt_node
def statements(): ice9_parser_global.logger.debug("Entering statements") stmt_node = ice9_node.stmt_node() stmt_node_list = list() # CODE-GENERATED if ice9_parser_global.tok.type == 'IF': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) stmt_node = ice9_parser_if.handle_if() # CODE-GENERATED elif ice9_parser_global.tok.type == 'DO': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) stmt_node = ice9_parser_loops.do() # CODE-GENERATED elif ice9_parser_global.tok.type == 'FA': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) stmt_node = ice9_parser_loops.fa() # CODE-GENERATED elif ice9_parser_global.tok.type == 'EXIT': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) stmt_node.rule = 'EXIT' # CODE-GENERATED elif ice9_parser_global.tok.type == 'BREAK': stmt_node.rule = ice9_parser_global.tok.type ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) if stmt_node.rule == 'BREAK' and ice9_parser_global.loop_depth < 1: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, \ "break statement permitted only inside loops" sys.exit() if ice9_parser_global.tok.type == 'SEMI': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting ';'" sys.exit() # CODE-GENERATED elif ice9_parser_global.tok.type == 'SEMI': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) # CODE-GENERATED elif ice9_parser_global.tok.type == 'MINUS': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) expr_node = ice9_node.expr_node() expr_node.pre_child = ice9_parser_expressions.expr(None) expr_node.operation = 'UN_MINUS' expr_node.operand_data_type = expr_node.pre_child.return_data_type expr_node.dimension = expr_node.pre_child.dimension # Check if the operand are either bool or int if expr_node.operand_data_type not in ['bool', 'int']: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, \ "unary minus operator expects a 'bool' or 'int' operand" sys.exit() # Check if the operands have dimension 0 if expr_node.dimension != 0: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, \ "unary minus operator does not expect array datatypes" sys.exit() expr_node.return_data_type = expr_node.operand_data_type stmt_node.pre_child = expr_node stmt_node.rule = 'UN_MINUS' if ice9_parser_global.tok.type == 'SEMI': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting ';'" sys.exit() # CODE-GENERATED elif ice9_parser_global.tok.type == 'QUEST': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) expr_node = ice9_node.expr_node() expr_node.pre_child = ice9_parser_expressions.expr(None) expr_node.operation = 'QUEST' expr_node.operand_data_type = expr_node.pre_child.return_data_type expr_node.dimension = expr_node.pre_child.dimension # Check if the operand is bool if expr_node.operand_data_type != 'bool': print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, \ "unary ? operator expects a 'bool' operand" sys.exit() # Check if the operands have dimension 0 if expr_node.dimension != 0: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, \ "unary ? operator does not expect array datatypes" sys.exit() expr_node.return_data_type = 'int' stmt_node.pre_child = expr_node stmt_node.rule = 'QUEST' if ice9_parser_global.tok.type == 'SEMI': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting ';'" sys.exit() # CODE-GENERATED elif ice9_parser_global.tok.type in ['WRITE', 'WRITES']: stmt_node.rule = ice9_parser_global.tok.type ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) stmt_node.pre_child = ice9_parser_expressions.expr(None) # Check if the operands have dimension 0 if stmt_node.pre_child.dimension != 0: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, \ "write(s) operator does not expect array datatypes" sys.exit() if ice9_parser_global.tok.type == 'SEMI': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting ';'" sys.exit() # CODE-GENERATED elif ice9_parser_global.tok.type == 'ID': id_node = ice9_node.expr_node() id_node.value = ice9_parser_global.tok.value id_node.operation = 'ID' ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) #Look ahead and determine if operation was proc_call, then set id_node properties from st_proc if ice9_parser_global.tok.type == 'LPAREN': if id_node.value not in ice9_st_proc.st_proc: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, \ "procedure '" + id_node.value + "' not defined" sys.exit() id_node.return_data_type = ice9_st_proc.st_proc[id_node.value].return_type id_node.dimension = 0 #If not, set id_node properties from st_var else: if id_node.value not in ice9_st_var.st_var: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, \ "variable '" + id_node.value + "' not defined" sys.exit() id_node.return_data_type = ice9_st_var.st_var[id_node.value][-1].basic_data_type id_node.dimension = ice9_st_var.st_var[id_node.value][-1].dimension result_node = ice9_parser_expressions.assign_or_expr(id_node) stmt_node = ice9_node.stmt_node() stmt_node.pre_child = result_node stmt_node.rule = 'EXPR' if ice9_parser_global.tok.type == 'SEMI': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting ';'" sys.exit() # CODE-GENERATED elif ice9_parser_global.tok.type == 'LPAREN': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) expr_node = ice9_parser_expressions.expr() if ice9_parser_global.tok.type == 'RPAREN': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting ')'" sys.exit() result_node = ice9_parser_expressions.half_expr(expr_node) if ice9_parser_global.tok.type == 'SEMI': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting ';'" stmt_node.pre_child = expr_node stmt_node.rule = 'EXPR' # CODE-GENERATED elif ice9_parser_global.tok.type in ['INT', 'FALSE', 'TRUE']: stmt_node.rule = ice9_parser_global.tok.type # Create node for the first entity expr_node = ice9_node.expr_node() expr_nodedimension = 0 expr_node.value = ice9_parser_global.tok.value expr_node.operation = ice9_parser_global.tok.type; if ice9_parser_global.tok.type == 'INT': expr_node.return_data_type = 'int' else: expr_node.return_data_type = 'bool' ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) # Get the entire expression tree from half_expr result_node = ice9_parser_expressions.half_expr(expr_node) # Attach expression tree to stmt_node stmt_node.pre_child = result_node # CODE-GENERATED elif ice9_parser_global.tok.type == 'SLIT': stmt_node.rule = 'EXPR' stmt_node.pre_child = ice9_node.expr_node() stmt_node.pre_child.operation = 'SLIT' stmt_node.pre_child.return_data_type = 'string' stmt_node.pre_child.operand_data_type = 'string' stmt_node.pre_child.value = str(ice9_parser_global.tok.value) stmt_node.pre_child.dimension = 0 stmt_node.pre_child.length = len(stmt_node.pre_child.value) - 2 if ice9_parser_global.tok.value not in ice9_parser_global.string_location_dict: ice9_parser_global.string_location_dict[ice9_parser_global.tok.value] = ice9_parser_global.string_location_pointer ice9_parser_global.string_location_pointer += stmt_node.pre_child.length ice9_parser_global.string_location_pointer += 1 ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) # CODE-GENERATED elif ice9_parser_global.tok.type == 'READ': stmt_node.rule = 'READ' ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) # Handle post-child stmt_node.pre_child = ice9_parser_expressions.expr(None) if stmt_node.pre_child.operation not in ['ID', 'ARRAY_REF']: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, \ "read can be performed only on variables, not expressions" sys.exit() if ice9_parser_global.tok.type == 'SEMI': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting ';'" sys.exit() stmt_node_list.append(stmt_node) if in_first_of_statement(): stmt_node_list += statements() ice9_parser_global.logger.debug("Exiting statements") return stmt_node_list
def fa(): ice9_parser_global.logger.debug("Entering fa") stmt_node = ice9_node.stmt_node() stmt_node.rule = 'FA' ice9_parser_global.loop_depth += 1 if ice9_parser_global.tok.type == 'ID': fa_loop_id = ice9_parser_global.tok.value ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting id" sys.exit() loop_id_node = ice9_node.expr_node() loop_id_node.operation = 'LOOP_ID' loop_id_node.value = fa_loop_id if ice9_parser_global.tok.type == 'ASSIGN': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting ':='" sys.exit() loop_id_node.pre_child = ice9_parser_expressions.expr(None) if loop_id_node.pre_child.return_data_type != 'int': print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, \ "fa loop variable must be a 'int'" sys.exit() if loop_id_node.pre_child.dimension != 0: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, \ "fa loop variable cannot be a array, must be a 'int'" sys.exit() if ice9_parser_global.tok.type == 'TO': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting to" sys.exit() loop_id_node.post_child = ice9_parser_expressions.expr(None) if loop_id_node.post_child.return_data_type != 'int': print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, \ "fa loop variable must be a 'int'" sys.exit() if loop_id_node.post_child.dimension != 0: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, \ "fa loop expression cannot be a array , must be a 'int'" sys.exit() ice9_parser_global.fa_loop_variable.append(fa_loop_id) ''' Might be un-necessary # Obtain the location to store the fa loop variable if ice9_parser_global.scope[-1] == 'GLOBAL': address = ice9_parser_global.get_next_global_address() else: address = ice9_st_proc.st_proc[ice9_parser_global.scope[-1]].parameter_count + 2 + \ ice9_st_proc.st_proc[ice9_parser_global.scope[-1]].local_variable_count st_var_entry = ice9_st_var.st_var_entry('int', 0, address) ''' st_var_entry = ice9_st_var.st_var_entry('int', 0, 1, 1) st_var_entry.basic_data_type = 'int' # Bypass the checks in st_var.add_entry_to_st_var # If variable not previously used, make an entry for it if fa_loop_id not in ice9_st_var.st_var: fa_loop_id_stack = list() ice9_st_var.st_var[fa_loop_id] = fa_loop_id_stack ice9_st_var.st_var[fa_loop_id].append(st_var_entry) if ice9_parser_global.tok.type == 'ARROW': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting '->'" sys.exit() stmt_node.pre_child = loop_id_node stmt_node.post_child = ice9_parser_statements.statements() if ice9_parser_global.tok.type == 'AF': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting af" sys.exit() # Clean up ice9_parser_global.fa_loop_variable.pop() ice9_parser_global.loop_depth -= 1 ice9_st_var.st_var[fa_loop_id].pop() if len(ice9_st_var.st_var[fa_loop_id]) == 0: del ice9_st_var.st_var[fa_loop_id] ice9_parser_global.logger.debug("Exiting fa") return stmt_node
def elseif_or_else(): ice9_parser_global.logger.debug("Entering elseif_or_else") stmt_node = ice9_node.stmt_node() stmt_node.rule = 'IF' if ice9_parser_global.tok.type == 'ELSE': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) # Create dummy expression that always evaluates to true expr_node = ice9_node.expr_node() expr_node.operation = 'TRUE' expr_node.return_data_type = 'bool' stmt_node.condition = expr_node if ice9_parser_global.tok.type == 'ARROW': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting '->'" sys.exit() if ice9_parser_statements.in_first_of_statement(): stmt_node.pre_child = ice9_parser_statements.statements() else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting a statement" sys.exit() else: # Condition expression expr_node = ice9_parser_expressions.expr(None) if expr_node.return_data_type != 'bool': print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, \ "if condition must return a 'bool'" sys.exit() if expr_node.dimension != 0: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, \ "if condition cannot be a array variable, must return a 'bool'" sys.exit() stmt_node.condition = expr_node if ice9_parser_global.tok.type == 'ARROW': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting ';'" sys.exit() if ice9_parser_statements.in_first_of_statement(): stmt_node.pre_child = ice9_parser_statements.statements() else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting a statement" sys.exit() if ice9_parser_global.tok.type == 'BOX': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) stmt_node.post_child = elseif_or_else() ice9_parser_global.logger.debug("Exiting elseif_or_else") return stmt_node