⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 php_syntree.cpp

📁 电驴的MAC源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//// This file is part of the aMule Project.//// Copyright (c) 2003-2008 aMule Team ( admin@amule.org / http://www.amule.org )// Copyright (C) 2005-2008 Froenchenko Leonid ( lfroen@amule.org )//// Any parts of this program derived from the xMule, lMule or eMule project,// or contributed by third-party developers are copyrighted by their// respective authors.//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.// // You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA//#include <string> // Do_not_auto_remove (g++-4.0.1)#ifdef PHP_STANDALONE_EN	#include <map>	#include <list>	#include <stdarg.h>#else	#include "WebServer.h"#endif#include "php_syntree.h"#include "php_core_lib.h"PHP_SYN_NODE *g_syn_tree_top = 0;/* scope table */PHP_SCOPE_TABLE g_global_scope = 0;PHP_SCOPE_TABLE g_current_scope = 0;PHP_SCOPE_STACK g_scope_stack = 0;//// Known named constant valuesstd::map<std::string, int> g_known_const;PHP_EXP_NODE *make_zero_exp_node(){	PHP_EXP_NODE *node = new PHP_EXP_NODE;	memset(node, 0, sizeof(PHP_EXP_NODE));	return node;}PHP_EXP_NODE *make_const_exp_dnum(int number){	PHP_EXP_NODE *node = make_zero_exp_node();	node->op = PHP_OP_VAL;	node->val_node.type = PHP_VAL_INT;	node->val_node.int_val = number;		return node;}PHP_EXP_NODE *make_const_exp_fnum(float number){	PHP_EXP_NODE *node = make_zero_exp_node();	node->op = PHP_OP_VAL;	node->val_node.type = PHP_VAL_FLOAT;	node->val_node.float_val = number;		return node;}PHP_EXP_NODE *make_const_exp_str(char *s, int unescape){	PHP_EXP_NODE *node = make_zero_exp_node();	node->op = PHP_OP_VAL;	node->val_node.type = PHP_VAL_STRING;	if ( unescape ) {		node->val_node.str_val = (char *)malloc(strlen(s)+1);		// copy and unescape string		char *p = node->val_node.str_val;		while(*s) {			if ( *s == '\\' ) {				switch ( *(++s) ) {					case 'n' : *p++ = '\n'; s++; break;					case 't' : *p++ = '\t'; s++; break;					default  : *p++ = *s++; break;				}			} else {				*p++ = *s++;			}		}		*p = 0;	} else {		node->val_node.str_val = strdup(s);	}		return node;}PHP_EXP_NODE *make_const_exp_int_obj(void *obj){	PHP_EXP_NODE *node = make_zero_exp_node();	node->op = PHP_OP_VAL;	node->val_node.type = PHP_VAL_INT_DATA;	node->val_node.ptr_val = obj;		return node;}PHP_EXP_NODE *make_exp_1(PHP_EXP_OP op, PHP_EXP_NODE *operand){	PHP_EXP_NODE *node = make_zero_exp_node();	node->op = op;	node->tree_node.left = operand;	return node;}PHP_EXP_NODE *make_exp_2(PHP_EXP_OP op, PHP_EXP_NODE *left, PHP_EXP_NODE *right){	PHP_EXP_NODE *node = make_zero_exp_node();	node->op = op;	node->tree_node.left = left;	node->tree_node.right = right;	return node;}PHP_EXP_NODE *make_exp_2_self(PHP_EXP_OP op, PHP_EXP_NODE *self, PHP_EXP_NODE *right){	PHP_EXP_NODE *clone_self = make_zero_exp_node();	*clone_self = *self;	return make_exp_2(op, clone_self, right);}PHP_EXP_NODE *make_known_const(char *name){	int const_id = -1;	if ( g_known_const.count(name) ) {		const_id = g_known_const[name];	}	return make_const_exp_dnum(const_id);}//// Create function parameter (in declaration)//PHP_EXP_NODE *make_func_param(PHP_EXP_NODE *list, PHP_EXP_NODE *var_exp_node, char *class_name, int byref){	PHP_FUNC_PARAM_DEF *param = new PHP_FUNC_PARAM_DEF;	memset(param, 0, sizeof(PHP_FUNC_PARAM_DEF));	param->si_var = var_exp_node->var_si_node;	param->si_var->type = PHP_SCOPE_PARAM;	//printf("mark %p->%p as param\n", param->si_var, param->si_var->var);		param->var = param->si_var->var;		delete var_exp_node;	param->class_name = class_name ? strdup(class_name) : 0;	param->byref = byref;		PHP_EXP_NODE *curr_node = make_const_exp_int_obj(param);		if ( list ) {		PHP_EXP_NODE *p = list;		while ( p->next) {			p = p->next;		}		p->next = curr_node;		return list;	} else {		return curr_node;	}}/* * Syntax tree generation */PHP_SYN_NODE *make_expr_syn_node(PHP_STATMENT_TYPE type, PHP_EXP_NODE *expr){	PHP_SYN_NODE *syn_node = new PHP_SYN_NODE;	memset(syn_node, 0, sizeof(PHP_SYN_NODE));		syn_node->type = type;	syn_node->node_expr = expr;		return syn_node;}PHP_SYN_NODE *make_ifelse_syn_node(PHP_EXP_NODE *expr,	PHP_SYN_NODE *then_node, PHP_SYN_NODE *elseif_list, PHP_SYN_NODE *else_node){	PHP_SYN_NODE *syn_node = new PHP_SYN_NODE;	memset(syn_node, 0, sizeof(PHP_SYN_NODE));		syn_node->type = PHP_ST_IF;	syn_node->node_if.cond = expr;	syn_node->node_if.code_if = then_node;		if ( elseif_list ) {		syn_node->node_if.code_else = elseif_list;			PHP_SYN_NODE *curr_if = elseif_list;		while ( curr_if->node_if.code_else ) {			curr_if = curr_if->node_if.code_else;		}		curr_if->node_if.code_else = else_node;	} else {		syn_node->node_if.code_else = else_node;	}	return syn_node;}PHP_SYN_NODE *make_while_loop_syn_node(PHP_EXP_NODE *cond, PHP_SYN_NODE *code, int do_while){	PHP_SYN_NODE *syn_node = new PHP_SYN_NODE;	memset(syn_node, 0, sizeof(PHP_SYN_NODE));		syn_node->type = do_while ? PHP_ST_WHILE : PHP_ST_DO_WHILE;	syn_node->node_while.cond = cond;	syn_node->node_while.code = code;		return syn_node;}PHP_SYN_NODE *make_for_syn_node(PHP_EXP_NODE *start, PHP_EXP_NODE *cond,	PHP_EXP_NODE *next, PHP_SYN_NODE *code){	PHP_SYN_NODE *syn_node = new PHP_SYN_NODE;	memset(syn_node, 0, sizeof(PHP_SYN_NODE));	syn_node->type = PHP_ST_FOR;	syn_node->node_for.do_start = start;	syn_node->node_for.cond = cond;	syn_node->node_for.do_next = next;	syn_node->node_for.code = code;		return syn_node;}PHP_SYN_NODE *make_foreach_loop_syn_node(PHP_EXP_NODE *elems,	PHP_EXP_NODE *i_key, PHP_EXP_NODE *i_val, PHP_SYN_NODE *code, int byref){	PHP_SYN_NODE *syn_node = new PHP_SYN_NODE;	memset(syn_node, 0, sizeof(PHP_SYN_NODE));		syn_node->type = PHP_ST_FOREACH;	syn_node->node_foreach.elems = elems;	syn_node->node_foreach.code = code;	syn_node->node_foreach.i_key = i_key ? i_key->var_si_node : 0;	syn_node->node_foreach.i_val = i_val->var_si_node;	syn_node->node_foreach.byref = byref;		if ( i_key ) {		delete i_key;	}	delete i_val;		return syn_node;}PHP_SYN_NODE *make_func_decl_syn_node(const char *name, PHP_EXP_NODE *param_list){	PHP_SYN_NODE *syn_node = new PHP_SYN_NODE;	memset(syn_node, 0, sizeof(PHP_SYN_NODE));		syn_node->type = PHP_ST_FUNC_DECL;		syn_node->func_decl = new PHP_SYN_FUNC_DECL_NODE;	memset(syn_node->func_decl, 0, sizeof(PHP_SYN_FUNC_DECL_NODE));	syn_node->func_decl->name = strdup(name);		if ( param_list ) {		PHP_EXP_NODE *curr_param = param_list;		// count parameters first		while ( curr_param ) {			syn_node->func_decl->param_count++;			curr_param = curr_param->next;		}		syn_node->func_decl->params = new PHP_FUNC_PARAM_DEF[syn_node->func_decl->param_count];		curr_param = param_list;		for(int i = 0; param_list; param_list = param_list->next, i++) {			syn_node->func_decl->params[i] = *(PHP_FUNC_PARAM_DEF *)param_list->val_node.ptr_val;			// param has been copied to array, so it's no longer needed			delete (PHP_FUNC_PARAM_DEF *)param_list->val_node.ptr_val;		}		// dispose linked list as well		while ( curr_param ) {			PHP_EXP_NODE *p = curr_param->next;			delete curr_param;			curr_param = p;		}	}		return syn_node;}PHP_SYN_NODE *make_class_decl_syn_node(){	PHP_SYN_NODE *syn_node = new PHP_SYN_NODE;	memset(syn_node, 0, sizeof(PHP_SYN_NODE));		syn_node->type = PHP_ST_CLASS_DECL;		syn_node->class_decl = new PHP_SYN_CLASS_DECL_NODE;	memset(syn_node->class_decl, 0, sizeof(PHP_SYN_CLASS_DECL_NODE));		return syn_node;}PHP_SYN_NODE *make_switch_syn_node(PHP_EXP_NODE *cond, PHP_EXP_NODE *case_list){	PHP_SYN_NODE *syn_node = new PHP_SYN_NODE;	memset(syn_node, 0, sizeof(PHP_SYN_NODE));		syn_node->type = PHP_ST_SWITCH;		//	// Bind all statement lists into single one for	// simplier execution	//	PHP_SYN_NODE *stat_list_tail = 0;	for(PHP_EXP_NODE *cur_case = case_list; cur_case; cur_case = cur_case->next) {		PHP_SYN_NODE *cur_stat_list = cur_case->exp_node->tree_node.syn_right;		if ( stat_list_tail ) {			while ( stat_list_tail->next_node ) stat_list_tail = stat_list_tail->next_node;			stat_list_tail->next_node = cur_stat_list;		} else {			stat_list_tail = cur_stat_list;		}	}			syn_node->node_switch.cond = cond;	syn_node->node_switch.case_list = case_list;		return syn_node;}PHP_VAR_NODE *make_var_node(){	PHP_VAR_NODE *node = new PHP_VAR_NODE;	memset(node, 0, sizeof(PHP_VAR_NODE));	node->value.type = PHP_VAL_NONE;		return node;}PHP_VAR_NODE *make_array_var(){	PHP_VAR_NODE *node = make_var_node();	cast_value_array(&node->value);		return node;}/* * Called from lexer when ${IDENT} is recognized */PHP_EXP_NODE *get_var_node(const char *name){	PHP_EXP_NODE *node = make_zero_exp_node();	node->op = PHP_OP_VAR;		PHP_SCOPE_ITEM *si = get_scope_item(g_current_scope, name);	if ( si ) {		if ( (si->type == PHP_SCOPE_VAR) || (si->type == PHP_SCOPE_PARAM) ) {			node->var_si_node = si;		} else {			//			// Error: symbol already defined as different entity			//			php_report_error(PHP_ERROR,				"symbol [%s] already defined as different entity (%d)", name, si->type);		}	} else {		add_var_2_scope(g_current_scope, make_var_node(), name);		node->var_si_node = get_scope_item(g_current_scope, name);	}		return node;}void free_var_node(PHP_VAR_NODE *v){	delete v;}/* * Init function scope table before transferring control there. *  1. Evaluate all by-value params *  2. Lvalue-evaluate all by-ref params and adjust pointers */void func_scope_init(PHP_FUNC_PARAM_DEF *params, int param_count,	PHP_SCOPE_TABLE_TYPE * /*scope_map*/, PHP_VALUE_NODE *arg_array,	std::map<std::string, PHP_VAR_NODE *> &saved_vars){	//	// Step 1: save origival vars	PHP_SCOPE_TABLE_TYPE *curr_scope_map = (PHP_SCOPE_TABLE_TYPE *)g_current_scope;	for(PHP_SCOPE_TABLE_TYPE::iterator i = curr_scope_map->begin(); i != curr_scope_map->end();i++) {		if ( (i->second->type == PHP_SCOPE_VAR) || (i->second->type == PHP_SCOPE_PARAM) ) {			if ( !(i->second->var->flags & PHP_VARFLAG_STATIC) ) {				//printf("Saving %s = %p->%p\n", i->first.c_str(), i->second, i->second->var);				saved_vars[i->first] = i->second->var;			}		}	}	//	// Step 2: calculate new values of call parameters	PHP_VAR_NODE *call_params[PHP_MAX_FUNC_PARAM];	for(int i = 0; i < param_count; i++) {		PHP_VAR_NODE *curr_arg_val = array_get_by_int_key(arg_array, i);		if ( curr_arg_val->value.type != PHP_VAL_NONE ) {			if ( (curr_arg_val->flags & PHP_VARFLAG_BYREF) || params[i].byref ) {				call_params[i] = php_expr_eval_lvalue((PHP_EXP_NODE *)curr_arg_val->value.ptr_val);				if ( !call_params[i] ) {					php_report_error(PHP_ERROR, "Byref parameter is not lvalue");					return;				}			} else {				call_params[i] = make_var_node();				call_params[i]->ref_count = 1;				//printf("alloc var for callparam %d -> %p\n", i, call_params[i]);				php_expr_eval((PHP_EXP_NODE *)curr_arg_val->value.ptr_val, &call_params[i]->value);			}		} else {			// put default value			php_report_error(PHP_WARNING, "Default parameters are not implemented yet");			call_params[i] = make_var_node();			call_params[i]->ref_count = 1;		}	}	//	// Step 3: assign new values to call parameters	for(int i = 0; i < param_count; i++) {		//printf("assign new param si=%p var=%p -> %p\n", params[i].si_var, params[i].si_var->var, call_params[i]);		params[i].si_var->var = call_params[i];	}	//	// Step 4: allocate new stack local vars	for(PHP_SCOPE_TABLE_TYPE::iterator i = curr_scope_map->begin(); i != curr_scope_map->end();i++) {		if ( !((i->second->type == PHP_SCOPE_PARAM) || (i->second->type == PHP_SCOPE_VAR)) ) {			continue;		}		//printf("in scope: %p %s [ %s ] with flags %02x\n", i->second, i->second->type == PHP_SCOPE_PARAM ? "param" : "var",		//	i->first.c_str(), i->second->var->flags);		if ( !(i->second->var->flags & PHP_VARFLAG_STATIC) && (i->second->type != PHP_SCOPE_PARAM) ) {			//printf("alloc new for %s [ %p->%p ]\n", i->first.c_str(), i->second, i->second->var);			i->second->var = make_var_node();			i->second->var->ref_count = 1;		}	}}/* * Since by-ref params changes pointers in scope table, we need to restore them * to original objects, so: *  1. Memory will not leak *  2. Next call may be using same params by-value, so it need independent varnode */void func_scope_copy_back(PHP_FUNC_PARAM_DEF *params, int param_count,	PHP_SCOPE_TABLE_TYPE * /*scope_map*/, PHP_VALUE_NODE *arg_array,	std::map<std::string, PHP_VAR_NODE *> &saved_vars){	/*	if ( param_count < array_get_size(arg_array) ) {		param_count = array_get_size(arg_array);	}	*/	PHP_VAR_NODE *call_params[PHP_MAX_FUNC_PARAM];	int call_param_2free_count = 0;	for(int i = 0; i < param_count; i++) {		PHP_VAR_NODE *curr_arg_val = array_get_by_int_key(arg_array, i);		if ( !((curr_arg_val->flags & PHP_VARFLAG_BYREF) || params[i].byref) ) {			//printf("Delete param %d %p->%p\n", i, params[i].si_var, params[i].si_var->var);			call_params[call_param_2free_count++] = params[i].si_var->var;		}		params[i].si_var->var = params[i].var;	}		PHP_SCOPE_TABLE_TYPE *curr_scope_map = (PHP_SCOPE_TABLE_TYPE *)g_current_scope;	for(PHP_SCOPE_TABLE_TYPE::iterator i = curr_scope_map->begin(); i != curr_scope_map->end();i++) {		if ( (i->second->type == PHP_SCOPE_VAR) || (i->second->type == PHP_SCOPE_PARAM) ) {			if ( !(i->second->var->flags & PHP_VARFLAG_STATIC) ) {				//printf("Restoring %s = %p->%p\n", i->first.c_str(), i->second, i->second->var);				//assert(saved_vars[i->first]);				if (i->second->type == PHP_SCOPE_VAR) {					value_value_free(&i->second->var->value);					delete i->second->var;				}				i->second->var = saved_vars[i->first];			}		}	}	for(int i = 0; i < call_param_2free_count; i++) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -