C语言前端编译器,yacc/lex编写,可自行修改代码.

源代码在线查看: function.cc

软件大小: 307 K
上传用户: a22aa11a
关键词: yacc lex C语言 编译器
下载地址: 免注册下载 普通下载 VIP

相关代码

				// Copyright 2002 by Keith Vallerio.
				// All rights reserved.
				
				/************************************************************
				  function.cc
				
				  Provides support to database.cc.  This is one of the major files
				in the program.  Defines Var, FuncCall and Function classes.
				These classes store much of the actual info about the input
				source code.
				************************************************************/
				
				#include "function.h"
				#include "ArgPack.h"
				
				//************************************************************
				// Var
				//************************************************************
				
				// Constructor
				Var::Var (string n, string t, RVector s, long elements) :
					name_(n), type_(t), total_size_(-1), num_elements_(elements), stype_(s), 
					is_pointer_(false), is_static_(false)
				{
					Rassert(elements >= 0);
					MAP (x, s.size()) {
						if (s[x] == "pointer") {
							is_pointer_ = true;			
						}
						if (s[x] == "static") {
							is_static_ = true;			
						}
					}
				}
				
				// Determines the size of the variable (type size * number of elements)
				void Var::determine_total_size (long type_size)
				{
					// If it's a pointer, use pre-defined value for pointers
					if (is_pointer_) {
						total_size_ = ArgPack::ap().pointer_size();
					} else {
						total_size_ = num_elements_ * type_size;
					}
				}
				
				//************************************************************
				// FuncCall
				//************************************************************
				
				// Constructor
				FuncCall::FuncCall (string n, long r, long nnode) :
					name_(n), parms_(), commas_(0), root_node_(r), fn_name_node_(nnode)
				{
				}
				
				// Add a dynamic parameter to the func call
				void FuncCall::add_parm(pair p)
				{
				//cout 				//	Rassert(parms_.size() < (commas_ + 1));
				
					if (parms_.size() < (commas_ + 1)) {
						while (parms_.size() < commas_) {
							parms_.push_back(pair (-1, CONST));
						}
						parms_.push_back(p);
					} else {
						long b = parms_.size()-2;
						cerr 																			}
				}
				
				// Add a comma to keep parameters in correct order 
				void FuncCall::add_comma()
				{
					commas_++;
				//cout 				}
				
				// Help keep parameters in order
				void FuncCall::balance_commas()
				{
				//cout 					while (parms_.size() 						parms_.push_back(pair (-1, CONST));
					}
					commas_ = 0;
				}
				
				//************************************************************
				// Function
				//************************************************************
				
				Function::Function (string n, string t, RVector s) :
					name_(n), type_(t), stype_(s), parameter_(), variable_(), var_use_(), 
					action_(), action_type_(), action_tree_node_(),
					func_call_(), assign_node_(),
					defined_(false), self_dependent_(true), vars_touched_(),
					v2v_alias_(), elipses_(false)
				{
				}
				
				//--------------------------------------------------
				// Analysis routines
				//--------------------------------------------------
				// List of names of all functions called by this function
				RVector Function::func_call_names ()
				{
					RVector call_list;
					MAP (x, func_call_.size()) {
						call_list.push_back(func_call_[x].name());
					}
					return call_list;
				}
				
				// Add all variables in 'vars' to 'target' alias set
				void Function::add_aliases (long target, RVector vars, 
								bool clear_old_alias)
				{
					long pointer = target;
					if (clear_old_alias) {
						Rassert(0);
					}
					MAP (x, vars.size()) {
						v2v_alias_[pointer].insert(vars[x]);
						set_union(v2v_alias_[pointer].begin(), v2v_alias_[pointer].end(),
									v2v_alias_[vars[x]].begin(), v2v_alias_[vars[x]].end(),
									inserter(v2v_alias_[pointer], v2v_alias_[pointer].begin()));
					}
				//	cout 				}
				
				// Return the indicies of the variables 'v' can alias to.
				RVector Function::v_alias_vec (long v)
				{
				   RVector ret_val;
				   ret_val.push_back(v);
				   set::iterator i;
				
				   set s = v2v_alias_[v];
				   for (i = s.begin(); i != s.end(); i++) {
				      long t = *i;
				      ret_val.push_back(t);      
				   }
				   return ret_val;
				}
				
				// Return the indicies of the parameters of the function
				set Function::parameter_set()
				{
					set ret_val;
					MAP (x, parameter_.size()) {
						ret_val.insert(parameter_[x]);
					}
				   return ret_val;
				}
				
				// Set the variable-to-variable alias vector size.
				void Function::init_alias_vectors (long v_size)
				{
					v2v_alias_.resize(v_size);
				}
				
				// Check if 'v' is in 'v_set_num' variable alias set
				bool Function::var_in_v_alias (long v, long v_set_num)
				{
					if ((v2v_alias_[v_set_num].find(v)) != (v2v_alias_[v_set_num].end())) {
						return true;
					} else {
						return false;
					}
				}
				
				// Remove 'v' from 'v_set_num' variable alias set
				void Function::remove_from_v_alias (long v, long v_set_num)
				{
					set::iterator i = v2v_alias_[v_set_num].find(v);
					Rassert(i != v2v_alias_[v_set_num].end());
					v2v_alias_[v_set_num].erase(i);
				}
				
				// Add all of 'source_num' aliases to the set for 'target_num'
				void Function::append_to_v_alias (long target_num, long source_num)
				{
					set_union(v2v_alias_[target_num].begin(), v2v_alias_[target_num].end(), 
								v2v_alias_[source_num].begin(), v2v_alias_[source_num].end(),
								inserter(v2v_alias_[target_num], v2v_alias_[target_num].begin()));
				}
				
				// Return variables aliased to parameters and the arguments themselves
				set 
				Function::func_call_cleanup_aliases (RVector p, 
																RVector parms)
				{
					// parms: part of header definition
					// p: dynamic parm binding
				
					// Add to dynamic arg alias set based on func_call's effects
					MAP(x, p.size()) {
						if (p[x].second == VAR) {
							// p is a variable arg to func called
							MAP (y, parms.size()) {
								if (p[y].second == VAR) {
									if ((x < parms.size()) && (y < parms.size())) {
										// x in y: remove x from y(dynamic) and add x(dynamic)
										if (var_in_v_alias(parms[x], parms[y])) {
											append_to_v_alias (p[y].first, p[x].first);
											remove_from_v_alias (parms[x], p[y].first);
										}
									}
								}
							}
						}
					}
				
					// Prepare a return value encompassing: variables aliased to parms,
					//    the arguments themselves, 
					set s;
					MAP (x, p.size()) {
						if (p[x].second == 0) {
							s.insert(p[x].first);
							set_union(s.begin(), s.end(), 
									v2v_alias_[p[x].first].begin(), v2v_alias_[p[x].first].end(),
									inserter(s, s.begin()));
						}
					}
					return s;
				}
				
				//--------------------------------------------------
				// "Function" creation routines
				//--------------------------------------------------
				// Add a function call to the current function
				long Function::add_func_call(string n, long r, long nnode)
				{
					func_call_.push_back(FuncCall(n, r, nnode));
					return (func_call_.size() - 1);
				}
				
				// Add a parameter to the current function
				void Function::add_parameter (long v)
				{
					parameter_.push_back(v);
				}
				
				// Add a variable to the current function
				// (This might not really be useful)
				void Function::add_variable(long v)
				{ 
					variable_.push_back(v);
				}
				
				// Add elipses as a parameter to indicate variable parameters
				void Function::add_elipses()
				{
					elipses_ = true;
				}
				
				// Add an argument to a funciton call
				void Function::add_func_call_arg (long c, long arg, ArgType arg_type)
				{
					func_call_[c].add_parm(pair (arg,arg_type));
				}
				
				// Add an action (actions defined in tree.cc file)
				void Function::add_action (string n, ActionType t, long tn)
				{
					action_.push_back(n);
					action_type_.push_back(t);
					action_tree_node_.push_back(tn);
				}
				
				// To keep arguments in order
				void Function::add_func_call_comma (long fc_num)
				{
					func_call_[fc_num].add_comma();
				}
				
				// To keep arguments in order
				void Function::balance_func_call_commas (long fc_num)
				{
					func_call_[fc_num].balance_commas();
				}
				
				//**************************************************
				// Printout routines
				//**************************************************
				
				ostream &
				operator					os 					os 					os 				
					return os;
				}
				
				ostream &
				operator					MAP (x, vp_a.size()) {
						if (vp_a[x].second == VAR) {
							os 						} else if (vp_a[x].second == FUNC) {
							os 						} else 
							os 					}
					return os;
				}
				
				ostream &
				operator					os 					os 				
					return os;
				}
				
				ostream &
				operator					os 					os 					os 					os 					os 					os 					os 					return os;
				}
				
				
				
							

相关资源