Exemple #1
0
Type TypeCheck_::check_binop( AST_Expression l , AST_Expression r , BinOpType op  )
{
  Type t1 = check_expression(l);
  Type t2 = check_expression(r);
  switch (op) {
  case BINOPLOWER:
  case BINOPLOWEREQ:
  case BINOPGREATER:
  case BINOPGREATEREQ:
  case BINOPCOMPNE:
  case BINOPCOMPEQ:
    if (check_equal(t1,t2) and !check_equal(t1 , T("Boolean")) ) 	return T("Boolean");
    else throw "Type Error (0)";
  case BINOPDIV:
  case BINOPELDIV:
  case BINOPMULT:
  case BINOPELMULT:
  case BINOPADD:
  case BINOPELADD:
  case BINOPSUB:
  case BINOPELSUB:
  case BINOPEXP:
  case BINOPELEXP:
    if (check_equal(t1,t2) and ( check_equal(t1 , T("Real"))  or check_equal(t1 , T("Integer")) )  )
      return t1;
    else throw "Type Error (1)"	;
  case BINOPAND:
  case BINOPOR:
    if (check_equal(t1,t2) and check_equal(t1 , T("Boolean")) ) return t1;
    throw "Type Error (2)";
  }
  throw "Error! (TypeCheck_::check_binop)";
}
Exemple #2
0
void semantic_analysis(struct tree_node * ptr) {
	if (!ptr) return;
	int i;

	if (ptr -> unit_name == NODE_EXTDEF) {
		if (ptr -> flags == FLAG_EXTDEF_VARIABLES) {
			
			struct tree_node * spec = ptr -> children[0];
			struct tree_node * declist = ptr -> children[1];
            
            push_anonymous_struct();
			// handle type first: if define struct, add struct; if basic, just use it, skip
			if (spec -> flags == FLAG_SPECIFIER_STRUCT && 
				spec -> children[0] -> flags == FLAG_STRUCTSPECIFIER_DEF) {
				symtab_add_struct(spec -> children[0]);
			}
			// whether or not spec is successfully added, just use them.
			while (declist -> flags == FLAG_EXTDECLIST_MORE) {
				symtab_add_variable(spec, declist -> children[0]);
				declist = declist -> children[2];
			}
			symtab_add_variable(spec, declist -> children[0]);
			
			pop_anonymous_struct();
			
			return;
			// end of EXTDEF_VARIABLES
		} else if (ptr -> flags == FLAG_EXTDEF_FUNCTION) {

			if (function_field != NULL) {
				semerrorpos(ERROR_OTHER, ptr->line);
				printf("nested function definition \'%s\' inside another function definition\'%s\'\n",
						ptr -> children[1] -> children[0] -> id_extra -> name,
						function_field -> name);
				return;
			}

			// register in the symbol table
			//   all the names in parameter list
			struct tree_node * spec = ptr -> children[0];
			struct tree_node * id = ptr -> children[1] -> children[0];
			struct func_entry * f = symtab_add_function(ptr -> children[1]);
			if (!f) {
				f = search_func_entry(id -> id_extra -> name);
				semerrorpos(ERROR_FUNCTION_CONFLICT, ptr -> line);
				printf("function \'%s\' already defined at %d\n",
					id -> id_extra -> name, f -> defined_at);
			}
			function_field = f;
			// check return type: if spec is a struct definition, add that.
            if (spec -> flags == FLAG_SPECIFIER_STRUCT) {
        	    struct struct_entry * se = NULL;
        	    push_anonymous_struct();
        		se = symtab_add_struct(spec -> children[0]);
        		f -> return_type_flag = TYPE_STRUCT;
        		f -> return_type.struct_type = se;
        		// return type may be NULL, checked by expression analysis
        		pop_anonymous_struct();
        	} else {
        	    assert(spec -> flags == FLAG_SPECIFIER_BASIC);
        	    f -> return_type_flag = TYPE_BASIC;
        	    f -> return_type.basic_type = spec -> children[0] -> type_name;
        	}
			// recursive analyze the definitions and statements in the compst
			struct tree_node * deflist = ptr -> children[2] -> children[1];
			while (deflist -> flags == FLAG_DEFLIST_MORE) {
				semantic_analysis(deflist -> children[0]);
				deflist = deflist -> children[1];
			}
			struct tree_node * stmtlist = ptr -> children[2] -> children[2];
			while (stmtlist -> flags == FLAG_STMTLIST_MORE) {
				semantic_analysis(stmtlist -> children[0]);
				stmtlist = stmtlist -> children[1];
			}
			function_field = NULL;
			// end of EXTDEF_FUNCTION
		} else if (ptr -> flags == FLAG_EXTDEF_TYPE) {
			if (ptr -> children[0] -> flags == FLAG_SPECIFIER_BASIC) return;
			else if (ptr -> children[0] -> flags == FLAG_SPECIFIER_STRUCT)
				symtab_add_struct(ptr -> children[0] -> children[0]);
			else assert(0);
		} else {
			assert(0);
		}
	} else if (ptr -> unit_name == NODE_EXP) {
		check_expression(ptr);
	} else if (ptr -> unit_name == NODE_DEF) {
		struct tree_node * spec = ptr -> children[0];
		struct tree_node * declist = ptr -> children[1];
		while (declist -> flags == FLAG_DECLIST_MORE) {
			symtab_add_variable(spec, declist -> children[0] -> children[0]);
			if (declist -> children[0] -> flags == FLAG_DEC_INITIALIZED) {
				check_expression(declist -> children[0] -> children[2]);
			}
			declist = declist -> children[2];
		}
		symtab_add_variable(spec, declist -> children[0] -> children[0]);
		if (declist -> children[0] -> flags == FLAG_DEC_INITIALIZED) {
			check_expression(declist -> children[0] -> children[2]);
		}
	} else if (ptr -> unit_name == NODE_STMT) {
		if (ptr -> flags == FLAG_STMT_EXP) {
			check_expression(ptr -> children[0]);
		} else if (ptr -> flags == FLAG_STMT_COMPST) {
			struct tree_node * deflist = ptr -> children[0] -> children[1];
			while (deflist -> flags == FLAG_DEFLIST_MORE) {
				semantic_analysis(deflist -> children[0]);
				deflist = deflist -> children[1];
			}
			struct tree_node * stmtlist = ptr -> children[0] -> children[2];
			while (stmtlist -> flags == FLAG_STMTLIST_MORE) {
				semantic_analysis(stmtlist -> children[0]);
				stmtlist = stmtlist -> children[1];
			}
		} else if (ptr -> flags == FLAG_STMT_IF) {
			check_expression(ptr -> children[2]);
			if (ptr -> children[2] -> exp_type_flag != TYPE_BASIC ||
				ptr -> children[2] -> exp_type.basic_type != TYPE_INT) {
				semerrorpos(ERROR_OTHER, ptr -> line);
				printf("non-integer in condition expression\n");
			}
			semantic_analysis(ptr -> children[4]);
		} else if (ptr -> flags == FLAG_STMT_IFELSE) {
			check_expression(ptr -> children[2]);
			if (ptr -> children[2] -> exp_type_flag != TYPE_BASIC ||
				ptr -> children[2] -> exp_type.basic_type != TYPE_INT) {
				semerrorpos(ERROR_OTHER, ptr -> line);
				printf("non-integer in condition expression\n");
			}
			semantic_analysis(ptr -> children[4]);
			semantic_analysis(ptr -> children[6]);
		} else if (ptr -> flags == FLAG_STMT_WHILE) {
			check_expression(ptr -> children[2]);
			if (ptr -> children[2] -> exp_type_flag != TYPE_BASIC ||
				ptr -> children[2] -> exp_type.basic_type != TYPE_INT) {
				semerrorpos(ERROR_OTHER, ptr -> line);
				printf("non-integer in condition expression\n");
			}
			semantic_analysis(ptr -> children[4]);
		} else if (ptr -> flags == FLAG_STMT_RETURN) {
			// done
			check_expression(ptr -> children[1]);
			if (function_field == NULL) {
				semerrorpos(ERROR_OTHER, ptr -> line);
				printf("no corresponding block to return operation\n");
				return;
			}
			int c = compare_type(ptr -> children[1] -> exp_type_flag, &(ptr -> children[1] -> exp_type),
				function_field -> return_type_flag, &(function_field -> return_type));
			if (c == COMPARE_GOOD) {
				// good
			} else {
				semerrorpos(ERROR_RETURN_MISMATCH, ptr -> line);
				printf("return type error: %s\n", compare_str[c]);
			}
			// end of return
		} else {
			assert(0);
		}
	} else {
		for (i = 0; i < ptr -> num_of_children; ++i) {
			assert(ptr -> children[i]);
			semantic_analysis(ptr -> children[i]);
		}
	}
	
}
Exemple #3
0
int check_expression(struct tree_node * exp) {
	assert(exp -> unit_name == NODE_EXP);
	
	if (exp -> flags == FLAG_EXP_ID) {					// terminal
		const char * id_name = exp -> children[0] -> id_extra -> name;
		struct var_entry * ve = search_var_entry(id_name);
		if (ve == NULL) {
			semerrorpos(ERROR_VARIABLE_UNDEFINED, exp -> children[0] -> line);
			printf("identifier \'%s\' not exist\n", id_name);
		} else {
			// check the ve's type and its flags
			exp -> exp_type_flag = ve -> type_flag;
			exp -> exp_type = ve -> t;
			exp -> exp_is_lvalue = 1;
		}
	} else if (exp -> flags == FLAG_EXP_INT) {			// terminal
		assert(exp -> children[0] -> unit_name == TOKEN_INTEGER);
		exp -> exp_type_flag = TYPE_BASIC;
		exp -> exp_type.basic_type = TYPE_INT;
		exp -> exp_is_lvalue = 0;
	} else if (exp -> flags == FLAG_EXP_FLOAT) {		// terminal
	    assert(exp -> children[0] -> unit_name == TOKEN_FLOAT);
	    exp -> exp_type_flag = TYPE_BASIC;
		exp -> exp_type.basic_type = TYPE_FLOAT;
		exp -> exp_is_lvalue = 0;
	} else if (exp -> flags == FLAG_EXP_ASSIGN) {		// NON-terminal
		// TODO: check left-value, then check type confliction
		check_expression(exp -> children[0]);
		check_expression(exp -> children[2]);
		if (exp -> children[0] -> exp_is_lvalue == 0) {
			semerrorpos(ERROR_ASSIGN_NONLEFT, exp -> children[0] -> line);
			printf("expression on the left side is not left-value\n");
		}
		exp -> exp_is_lvalue = exp -> children[2] -> exp_is_lvalue;
		// whether or not the left side is left-value or not, better to check type first.
		int c = compare_type(
			exp -> children[0] -> exp_type_flag, &(exp -> children[0] -> exp_type),
			exp -> children[2] -> exp_type_flag, &(exp -> children[2] -> exp_type));
		if (c != COMPARE_GOOD) {
			semerrorpos(ERROR_ASSIGN_MISMATCH, exp -> children[1] -> line);
			printf("type mismatch in assignment: %s\n", compare_str[c]);
		} else {
			exp -> exp_type_flag = exp -> children[0] -> exp_type_flag;
			exp -> exp_type = exp -> children[0] -> exp_type;
		}

		// end of assignment
	} else if (exp -> flags == FLAG_EXP_BINOP) {		// NON-terminal
		check_expression(exp -> children[0]);
		check_expression(exp -> children[2]);

		// prune: non-basic types cannot take binary operations whatsoever
		if (exp -> children[0] -> exp_type_flag == TYPE_ARRAY  ||
			exp -> children[0] -> exp_type_flag == TYPE_STRUCT) {
			semerrorpos(ERROR_OTHER, exp -> children[1] -> line);
			printf("%s (on the left side) cannot take binary operation\n", 
				type_str[exp -> children[0] -> exp_type_flag]);
			exp -> exp_type_flag = exp -> children[0] -> exp_type_flag;
			return -1;
		}
		if (exp -> children[2] -> exp_type_flag == TYPE_ARRAY  ||
			exp -> children[2] -> exp_type_flag == TYPE_STRUCT) {
			semerrorpos(ERROR_OTHER, exp -> children[1] -> line);
			printf("%s (on the right side) cannot take binary operation\n", 
				type_str[exp -> children[2] -> exp_type_flag]);
			exp -> exp_type_flag = exp -> children[2] -> exp_type_flag;
			return -1;
		}

		// now they are both basic types.
		exp -> exp_type_flag = TYPE_BASIC;
		exp -> exp_type.basic_type = exp -> children[0] -> exp_type.basic_type;
		if (exp -> children[1] -> unit_name == TOKEN_RELOP)
			exp -> exp_type.basic_type = TYPE_INT;
		exp -> exp_is_lvalue = 0;
		int type_left = exp -> children[0] -> exp_type.basic_type;
		int type_right = exp -> children[2] -> exp_type.basic_type;
		// assert(type_left == TYPE_INT || type_left == TYPE_FLOAT);
		// assert(type_right == TYPE_INT || type_right == TYPE_FLOAT);
		if (type_left == type_right) {	
			// printf("types: %d, %d\n", type_left, type_right);
		} else {
			semerrorpos(ERROR_OPERAND_MISMATCH, exp->children[1] -> line);
			printf("expression type not match: %d and %d\n", type_left, type_right);
		}
		// end of binary operators: + - * / && || relop
	} else if (exp -> flags == FLAG_EXP_PAREN) {		// NON-terminal
		check_expression(exp -> children[1]);
		exp -> exp_type_flag = exp -> children[1] -> exp_type_flag;
		exp -> exp_type = exp -> children[1] -> exp_type;
		exp -> exp_is_lvalue = exp -> children[1] -> exp_is_lvalue;
		// end of parentheses
	} else if (exp -> flags == FLAG_EXP_UNOP) {			// NON-terminal
		check_expression(exp -> children[1]);

		if (exp -> exp_type_flag == TYPE_ARRAY || exp -> exp_type_flag == TYPE_STRUCT) {
			semerrorpos(ERROR_OTHER, exp -> line);
			printf("%s cannot take unary operator\n", type_str[exp -> exp_type_flag]);
		}

		exp -> exp_is_lvalue = 0;
		exp -> exp_type_flag = exp -> children[1] -> exp_type_flag;
		exp -> exp_type = exp -> children[1] -> exp_type;
		// end of unary operator
	} else if (exp -> flags == FLAG_EXP_CALL_ARGS) {	// NON-self-recursive
		// DONE: check arguments
		const char * f_name = exp -> children[0] -> id_extra -> name;
		struct func_entry * f = search_func_entry(f_name);
		struct tree_node * arguments = exp -> children[2];
		struct list_head * parameters_head = NULL;
		if (f == NULL) {
			semerrorpos(ERROR_FUNCTION_UNDEFINED, exp -> children[0] -> line);
			printf("function \'%s\' not defined\n", f_name);
			exp -> exp_type_flag = TYPE_ERROR;
			return -1;
		} else { // checking parameters_head
			parameters_head = &(f -> param_list);
			struct list_head * param_l = NULL;
			struct var_entry * param_ve = NULL;
/*for loop*/list_for_each(param_l, parameters_head) {
				struct tree_node * a = arguments -> children[0];
				param_ve = list_entry(param_l, struct param_entry, list_ptr) -> param_ptr;
				check_expression(a);
				int c = compare_type(param_ve -> type_flag, &(param_ve -> t),
					a -> exp_type_flag, &(a -> exp_type));
				if (c != COMPARE_GOOD) {
					semerrorpos(ERROR_PARAM_MISMATCH, a -> line);
					printf("argument and parameter type mismatch: %s\n", 
						compare_str[c]);
				}
				if (arguments -> flags == FLAG_ARGS_SINGLE) {
					// param_ve should be the last parameter
					if (param_l -> next != parameters_head) {
						semerrorpos(ERROR_PARAM_MISMATCH, a -> line);
						printf("more params not matched\n");
					}
					break;
				} else {
					assert(arguments -> flags == FLAG_ARGS_MORE);
					// but if parameters has reached its end...
					if (param_l -> next == parameters_head) {
						semerrorpos(ERROR_PARAM_MISMATCH, a -> line);
						printf("more arguments not matched\n");
						break;
					}
				}
				arguments = arguments -> children[2];
			}
		}
		while (arguments -> flags == FLAG_ARGS_MORE) {
			check_expression(arguments -> children[0]);
			arguments = arguments -> children[2];
		}

		exp -> exp_type_flag = f -> return_type_flag;
		exp -> exp_type = f -> return_type;
		// end of function calling with args
	} else if (exp -> flags == FLAG_EXP_CALL_NOARGS) {	// NON-self-recursive
Exemple #4
0
Type TypeCheck_::check_expression(AST_Expression e)
{
  Type ct,t1,t2,t;
  switch (e->expressionType()) {
  case EXPBINOP:
  {
    AST_Expression_BinOp b = e->getAsBinOp();
    return check_binop(b->left() , b->right() , b->binopType());
  }
  case EXPUMINUS:
  {
    AST_Expression_UMinus b = e->getAsUMinus();
    t = check_expression(b->exp());
    if ( check_equal(t , T("Integer")) or check_equal(t , T("Real")) ) return t;
    throw "Type Error (3)";
  }

  case EXPOUTPUT :
  {
    AST_Expression_Output b = e->getAsOutput();
    return check_expression(b->expressionList()->front() );
  }

  case EXPIF:
  {
    AST_Expression_If b = e->getAsIf();
    ct = check_expression(b->condition() );
    t1 = check_expression(b->then() );
    t2 = check_expression(b->else_exp()); // Falta el elseIF
    if ( !check_equal(ct, T("Boolean")) ) throw "Type Error (4)";
    if ( !check_equal(t1,t2) ) throw "Type Error (5)";
    return t1;

  }

  case EXPCALL:
  {
    // Añadir las funciones en la listaaaa de variables
    AST_Expression_Call c = e->getAsCall();
    if ( toStr(c->name()) == "sample" ) return  T("Boolean");
    if ( toStr(c->name()) == "pre" ) 		
		return  check_expression(c->arguments()->front());
	return T("Real");
  }

  case EXPCOMPREF:
  {
    AST_Expression_ComponentReference b = e->getAsComponentReference();

    VarInfo  tt = varEnv->lookup(  toStr(b->names()->front()) );

    if (tt == NULL) {
      cerr << "Var:" <<  b->names()->front() << ":";
      throw "Variable no existe (8)";
    }
    if (b->indexes()->front()->size() == 0)
      return tt->type();
    else {
      Type t = tt->type();
      AST_ExpressionListIterator exit;
      foreach(exit , b->indexes()->front() )
      if (t->getType() == TYARRAY)
        t = t->getAsArray()->arrayOf();
      else throw "Type Error (7)";
      return t;
    }

    break;
  }
  case EXPDERIVATIVE:
    return T("Real");
  case EXPBOOLEAN:
    return T("Boolean");
  case EXPSTRING:
    return T("String");
  case EXPREAL:
    return T("Real");
  case EXPINTEGER:
    return T("Integer");
  case EXPBOOLEANNOT:
  {
    AST_Expression_BooleanNot b = e->getAsBooleanNot();
    t = check_expression(b->exp());
    if ( !check_equal(t, T("Boolean")) ) throw "Type Error (6)";
    return t;
  }
  default:
    throw "No implrementado aun! (check_expression)";

  }
}
Exemple #5
0
	int main_i(const std::vector<std::string> &argv)
	{
		int argc = argv.size();
		if (argc == 1 || (argc == 2 && argv[1] == "-h")) {
			std:: cout << "Picosel ver. 1.5 (C) 2009-2010 AIST" "\n"
				"Usage 1: picosel OPTION from inputfile select column where EXPRESSION" "\n"
				"Usage 2: picosel OPTION from inputfile select column order by column" "\n"
				"Option" "\n"
				"  -o outputfile: specify output file." "\n";
			return 0;
		}

		if (argc == 3 && argv[1] == "--text") {
			return convert_binary_file_to_text(argv[2]);
		}

		int r = analyze_commandline(argv);
		if (r != 0) {
			return r;
		}

		std:: ifstream input;
		input.open(fromFile.c_str(), std:: ios::in | std:: ios::binary);
		if (! input.is_open()) {
			std:: cerr << "error: can not open file '" << fromFile << "'" << std:: endl;
			return 1;
		}
		std:: istream *pInput = &input;

		r = get_column_names(pInput);
		if (r != 0) {
			return r;
		}
		
		int selectColIndex = findNamedColumn(selectCol);
		if (selectColIndex == -1) {
			std:: cerr << "error: unknown column name '" << selectCol << "'" << std:: endl;
			return 1;
		}

		r = check_expression();
		if (r != 0) {
			return r;
		}

		std:: ostream *pOutput = &std:: cout;
		std:: ofstream output;
		if (! outputFile.empty()) {
			output.open(outputFile.c_str(), binaryOutputFactor != 0 ? (std:: ios::out | std:: ios::binary) : std:: ios::out);
			if (! output.is_open()) {
				std:: cerr << "error: can not create file '" << outputFile << "'" << std:: endl;
				return 1;
			}
			pOutput = &output;
		}

		if (! orderByAsc.empty()) {
			int orderColIndex = findNamedColumn(orderByAsc);
			if (orderColIndex == -1) {
				std:: cerr << "error: unknown column name '" << orderByAsc << "'" << std:: endl;
				return 1;
			}
			r = do_sorting(pInput, pOutput, selectColIndex, orderColIndex, 1/* asc */, outputFile);
		}
		else if (! orderByDesc.empty()) {
			int orderColIndex = findNamedColumn(orderByDesc);
			if (orderColIndex == -1) {
				std:: cerr << "error: unknown column name '" << orderByDesc << "'" << std:: endl;
				return 1;
			}
			r = do_sorting(pInput, pOutput, selectColIndex, orderColIndex, -1/* desc */, outputFile);
		}
		else {
			r = do_selecting(pInput, pOutput, selectColIndex);
		}

		output.close();
		input.close();

		return r;
	}