def _mathexp(caller_node): ice9_parser_global.logger.debug("Entering _mathexp") math_node = ice9_node.expr_node() math_node.operation = ice9_parser_global.tok.type ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) # Set pre child to caller node math_node.pre_child = caller_node # Set post child to term node math_node.post_child = term(None) if caller_node: validate_mathexp(math_node) result_node = math_node else: result_node = math_node.post_child if ice9_parser_global.tok.type in ['PLUS', 'MINUS']: result_node = _mathexp(result_node) ice9_parser_global.logger.debug("Exiting _mathexp") return result_node
def _term(caller_node): ice9_parser_global.logger.debug("Entering _term") term_node = ice9_node.expr_node() term_node.operation = ice9_parser_global.tok.type ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) # Set pre child to caller node term_node.pre_child = caller_node # Set post child to factor node if in_first_of_factor() == True: factor_node = factor() term_node.post_child = factor_node else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting a factor" sys.exit() # If caller_node was None, return the same value obtained in lower depth if caller_node: result_node = term_node validate_term(result_node) else: result_node = term_node.post_child if ice9_parser_global.tok.type in ['STAR', 'SLASH', 'MOD']: result_node = _term(result_node) ice9_parser_global.logger.debug("Exiting _term") return result_node
def dectype(parameters): ice9_parser_global.logger.debug("Entering dectype") paramter_identifier_list = ice9_parser_var.idlist() if ice9_parser_global.tok.type == 'COLON': 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_global.tok.type == 'ID': paramter_identifier_type = ice9_parser_global.tok.value if paramter_identifier_type not in ice9_st_type.st_type: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value \ + " type", paramter_identifier_type, "not defined" sys.exit() 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() for param in paramter_identifier_list: id_node = ice9_node.id_node(str(param), paramter_identifier_type, 0) parameters.append(id_node) ice9_parser_global.logger.debug("Exiting dectype")
def typeid(): global dimension_length # Reset global variable dimension_length dimension_length = None dimension_length = list() ice9_parser_global.logger.debug("Entering typeid") data_type = ice9_parser_global.tok.value ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) # Dimension of the type dimension = 0 # If array variable, store the dimension if ice9_parser_global.tok.type == "LBRACK": dimension = const_array_index() # Create a type node type_node = ice9_node.type_node(data_type, dimension, dimension_length) # Reset global variable dimension_length dimension_length = None dimension_length = list() ice9_parser_global.logger.debug("Exiting typeid") return type_node
def returntype(): ice9_parser_global.logger.debug("Entering returntype") if ice9_parser_global.tok.type == 'ID': foundation_return_type = ice9_parser_global.tok.value return_type = ice9_st_type.get_basic_data_type(foundation_return_type) 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() # Check if return type defined if not return_type: print "Line", ice9_parser_global.tok.lineno, ": on token '" + \ ice9_parser_global.tok.value + "' return type '" + foundation_return_type + \ "' not defined in scope 'GLOBAL'" sys.exit() if return_type not in ice9_st_type.st_type: print "Line", ice9_parser_global.tok.lineno, ": on token '" + \ ice9_parser_global.tok.value + "' return type '" + return_type + \ "' not defined in scope 'GLOBAL'" sys.exit() # Check if foundation_data_type is not an array if ice9_st_type.st_type[foundation_return_type][-1].dimension != 0: print "Line", ice9_parser_global.tok.lineno, ": on token '" + \ ice9_parser_global.tok.value + "'procedure return type '" + foundation_return_type + \ "' cannot be an array" sys.exit() ice9_parser_global.logger.debug("Exiting returntype") return return_type
def arrayindex(): ice9_parser_global.logger.debug("Entering arrayindex") # Create a expression list where each node is an array dimension expr_list = list() expr_list.append(expr(None)) # Array index must be of type int if expr_list[-1].return_data_type != 'int': print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, \ "array index must be an 'int' operand" sys.exit() # Array index must have dimension 0 if expr_list[-1].dimension != 0: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, \ "array index cannot be an array reference" sys.exit() if ice9_parser_global.tok.type == 'RBRACK': 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() # Attach any remaining dimensions if ice9_parser_global.tok.type == 'LBRACK': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) expr_list += arrayindex() ice9_parser_global.logger.debug("Exiting arrayindex") return expr_list
def main(): ice9_parser_global.setup() ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) ice9_parser_global.create_instructions_op_file() ice9_parser_global.create_string_op_file() parse() ice9_parser_global.fix_forward_declarations() ice9_parser_global.generate_output_file() check_undefined_proc()
def _declist(parameters): ice9_parser_global.logger.debug("Entering _declist") dectype(parameters) if ice9_parser_global.tok.type == 'COMMA': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) _declist(parameters) ice9_parser_global.logger.debug("Exiting declist")
def handle_var(): ice9_parser_global.logger.debug("Entering var") var_list_node = varlist() 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() ice9_parser_global.logger.debug("Exiting var")
def _varlist(): ice9_parser_global.logger.debug("Entering _varlist") var_node_list = list() var_node_list.append(vartype()) if ice9_parser_global.tok.type == "COMMA": ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) var_node_list += _varlist() ice9_parser_global.logger.debug("Exiting _varlist") return var_node_list
def handle_forward(): ice9_parser_global.logger.debug("Entering forward") if ice9_parser_global.tok.type == 'ID': proc_identifier = 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() if ice9_parser_global.tok.type == 'LPAREN': 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() parameters = list() if ice9_parser_global.tok.type == 'ID': declist(parameters) 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() return_type = None if ice9_parser_global.tok.type == 'COLON': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) return_type = returntype() parameter_list = list() for param in parameters: parameter_list.append(param.foundation_data_type) st_proc_entry = ice9_st_proc.st_proc_entry(len(parameters), parameters, return_type, False) ice9_st_proc.add_entry_to_st_proc(proc_identifier, st_proc_entry) 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()
def parse(): ice9_parser_global.logger.debug("Entering parse") in_head = False in_body = False # Case for no input if not ice9_parser_global.tok: return type = ice9_parser_global.tok.type stmt_node_list = list() ice9_parser_global.setup_code_generation() while type != 'EOF': in_head = False if in_body == False: if type == 'VAR': in_head = True ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) ice9_parser_var.handle_var() elif type == 'TYPE': in_head = True ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) ice9_parser_type.handle_type() elif type == 'FORWARD': in_head = True ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) ice9_parser_forward.handle_forward() elif type =='PROC': in_head = True ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) ice9_parser_proc.handle_proc() if in_head == False: ice9_parser_global.setup_stmt_section(ice9_parser_global.lno) if ice9_parser_statements.in_first_of_statement() == True: in_body = True stmt_node_list += ice9_parser_statements.statements() else: print "Line", ice9_parser_global.tok.lineno, ": unexpected token -", ice9_parser_global.tok.value sys.exit() type = ice9_parser_global.tok.type # Generate Code for stmt in stmt_node_list: stmt.generate_code() ice9_parser_global.logger.debug("Exiting parse") return
def exprlist(): ice9_parser_global.logger.debug("Entering exprlist") expr_list = list() if ice9_parser_global.tok.type in ['SLIT', 'MINUS', 'READ', 'QUEST', 'ID', 'TRUE', 'INT', 'LPAREN', 'FALSE']: expr_list.append(expr(None)) if ice9_parser_global.tok.type == 'COMMA': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) expr_list += _exprlist() ice9_parser_global.logger.debug("Exiting exprlist") return expr_list
def vartype(): ice9_parser_global.logger.debug("Entering vartype") var_node_list = list() if ice9_parser_global.tok.type == "ID": identifier_list = idlist() else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting id" sys.exit() if ice9_parser_global.tok.type == "COLON": 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_global.tok.type == "ID": type_node = typeid() else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting id" sys.exit() for identifier in identifier_list: # Depending on the scope, calculate location for variable # If scope is GLOBAL, then location is in GLOBAL section # If scope is a procedure, then location is on stack, relative to FP if ice9_parser_global.scope[-1] == "GLOBAL": address = ice9_parser_global.get_next_global_address() ice9_parser_global.global_pointer += type_node.length - 1 else: address = ice9_st_proc.st_proc[ice9_parser_global.scope[-1]].local_variable_line ice9_st_proc.st_proc[ice9_parser_global.scope[-1]].local_variable_line -= type_node.length # Add entry to symbol table identifier_entry = ice9_st_var.st_var_entry( type_node.data_type, type_node.dimension, address, type_node.dimension_length ) ice9_st_var.add_entry_to_st_var(str(identifier), identifier_entry) id_node = ice9_node.id_node(str(identifier), type_node.data_type, type_node.dimension) id_node.set_basic_data_type() var_node_list.append(id_node) var_node = ice9_node.var_node(var_node_list, type_node) ice9_parser_global.logger.debug("Exiting vartype") return var_node
def _exprlist(): ice9_parser_global.logger.debug("Entering _exprlist") expr_list = list() if ice9_parser_global.tok.type in ['SLIT', 'MINUS', 'READ', 'QUEST', 'ID', 'TRUE', 'INT', 'LPAREN', 'FALSE']: expr_list.append(expr(None)) if ice9_parser_global.tok.type == 'COMMA': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) expr_list += _exprlist() else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting an expression" sys.exit() ice9_parser_global.logger.debug("Exiting _exprlist") return expr_list
def logicexp(caller_node): ice9_parser_global.logger.debug("Entering logicexp") logic_node = ice9_node.expr_node() logic_node.operation = ice9_parser_global.tok.type ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) logic_node.pre_child = caller_node logic_node.post_child = mathexp(None) if caller_node: result_node = logic_node validate_logicexp(logic_node) else: result_node = logic_node.post_child ice9_parser_global.logger.debug("Exiting logicexp") return result_node
def _idlist(): ice9_parser_global.logger.debug("Entering _idlist") identifier_list = list() if ice9_parser_global.tok.type == "ID": identifier_list.append(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() if ice9_parser_global.tok.type == "COMMA": ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) identifier_list += _idlist() ice9_parser_global.logger.debug("Exiting _idlist") return identifier_list
def const_array_index(): global dimension_length ice9_parser_global.logger.debug("Entering const_array_index") ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) if ice9_parser_global.tok.type == "INT": dimension_length.append(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 a integer" sys.exit() if ice9_parser_global.tok.type == "RBRACK": 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() dimension = 1 if ice9_parser_global.tok.type == "LBRACK": dimension += const_array_index() ice9_parser_global.logger.debug("Exiting const_array_index") return dimension
def optsuffix(): ice9_parser_global.logger.debug("Entering optsuffix") expr_node = None if ice9_parser_global.tok.type == 'LBRACK': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) expr_node = arrayindex() elif ice9_parser_global.tok.type == 'LPAREN': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) expr_node = exprlist() 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() ice9_parser_global.logger.debug("Exiting optsuffix") return expr_node
def handle_type(): ice9_parser_global.logger.debug("Entering type") if ice9_parser_global.tok.type == 'ID': derived_data_type = 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() if ice9_parser_global.tok.type == 'EQ': 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_global.tok.type == 'ID': type_node = ice9_parser_var.typeid() type_node.derived_data_type = derived_data_type else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting id" 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() data_type_entry = ice9_st_type.st_type_entry(str(type_node.data_type), type_node.dimension) ice9_st_type.add_entry_to_st_type(str(type_node.derived_data_type), data_type_entry) ice9_parser_global.logger.debug("Exiting type")
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 half_expr_or_assign(id_node): ice9_parser_global.logger.debug("Entering half_expr_or_assign") half_expr_or_assign_node = ice9_node.expr_node() if ice9_parser_global.tok.type == 'LBRACK': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) id_node.expr_list.append(expr(None)) # Array index must be of type int if id_node.expr_list[-1].return_data_type != 'int': print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, \ "array index must be an 'int' operand" sys.exit() # Array index must have dimension 0 if id_node.expr_list[-1].dimension != 0: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, \ "array index cannot be an array reference" sys.exit() if ice9_parser_global.tok.type == 'RBRACK': 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() 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 - len(id_node.expr_list) if id_node.dimension < 0: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, \ "array dimension for variable '" + id_node.value + "'exceeded" sys.exit() half_expr_or_assign_node = half_expr_or_assign(id_node) elif ice9_parser_global.tok.type == 'ASSIGN': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) half_expr_or_assign_node.operation = 'ASSIGN' half_expr_or_assign_node.pre_child = id_node half_expr_or_assign_node.post_child = expr(None) half_expr_or_assign_node = validate_assign(half_expr_or_assign_node) else: half_expr_or_assign_node = half_expr(id_node) ice9_parser_global.logger.debug("Exiting half_expr_or_assign") return half_expr_or_assign_node
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 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
def factor(): ice9_parser_global.logger.debug("Entering factor") expr_node = ice9_node.expr_node() if ice9_parser_global.tok.type == 'MINUS': expr_node.operation = 'UN_MINUS' ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) if in_first_of_factor() == True: expr_node.pre_child = factor() 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() # If the operand data type is boolean, then it indicates a NOT operation if expr_node.operand_data_type == 'bool': expr_node.operation = 'NOT' expr_node.return_data_type = expr_node.operand_data_type else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting a factor" sys.exit() elif ice9_parser_global.tok.type == 'QUEST': expr_node.operation = 'QUEST' ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) if in_first_of_factor() == True: expr_node.pre_child = factor() 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 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 = 'int' else: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, "expecting a factor" sys.exit() elif ice9_parser_global.tok.type == 'LPAREN': ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) expr_node = expr(None) 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() elif ice9_parser_global.tok.type == 'INT': expr_node.operation = 'INT' expr_node.operand_data_type = 'int' expr_node.return_data_type = 'int' expr_node.dimension = 0 expr_node.value = ice9_parser_global.tok.value ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) elif ice9_parser_global.tok.type == 'SLIT': expr_node.operation = 'SLIT' expr_node.operand_data_type = 'string' expr_node.return_data_type = 'string' expr_node.value = str(ice9_parser_global.tok.value) expr_node.dimension = 0 expr_node.length = len(expr_node.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 += expr_node.length ice9_parser_global.string_location_pointer += 1 ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) elif ice9_parser_global.tok.type == 'TRUE': expr_node.operation = 'TRUE' expr_node.operand_data_type = 'bool' expr_node.return_data_type = 'bool' expr_node.dimension = 0 expr_node.value = 1 ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) elif ice9_parser_global.tok.type == 'FALSE': expr_node.operation = 'FALSE' expr_node.operand_data_type = 'bool' expr_node.return_data_type = 'bool' expr_node.dimension = 0 expr_node.value = 0 ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) elif ice9_parser_global.tok.type == 'READ': expr_node.operation = 'READ' expr_node.operand_data_type = 'int' expr_node.return_data_type = 'int' expr_node.dimension = 0 expr_node.value = 0 ice9_parser_global.consume() ice9_parser_global.logger.debug(ice9_parser_global.tok) else: if ice9_parser_global.tok.type == 'ID': expr_node.value = 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() # Procedure call if ice9_parser_global.tok.type == 'LPAREN': expr_node.operation = 'PROC_CALL' expr_node.expr_list = optsuffix() validate_proc_call(expr_node) # Array variable elif ice9_parser_global.tok.type == 'LBRACK': expr_node.operation = 'ARRAY_REF' expr_node.expr_list = optsuffix() expr_node = validate_array_ref(expr_node) # Regular variable else: expr_node.operation = 'ID' # Check if variable has been declared if expr_node.value not in ice9_st_var.st_var: print "Line", ice9_parser_global.tok.lineno, ": on token", ice9_parser_global.tok.value, \ "variable '" + expr_node.value + "' not defined" sys.exit() expr_node.return_data_type = ice9_st_var.st_var[expr_node.value][-1].basic_data_type expr_node.dimension = ice9_st_var.st_var[expr_node.value][-1].dimension ice9_parser_global.logger.debug("Exiting factor") return expr_node