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

📄 compiler.cpp

📁 GNU ccScript is a C++ class framework for creating a virtual machine execution system for use with a
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Copyright (C) 1999-2005 Open Source Telecom Corporation.//  // 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.// // As a special exception, you may use this file as part of a free software// library without restriction.  Specifically, if other files instantiate// templates or use macros or inline functions from this file, or you compile// this file and link it with other files to produce an executable, this// file does not by itself cause the resulting executable to be covered by// the GNU General Public License.  This exception does not however// invalidate any other reasons why the executable file might be covered by// the GNU General Public License.//// This exception applies only to the code released under the name GNU// ccScript.  If you copy code from other releases into a copy of GNU// ccScript, as the General Public License permits, the exception does// not apply to the code that you add in this way.  To avoid misleading// anyone as to the status of such modified files, you must delete// this exception notice from them.//// If you write modifications of your own for GNU ccScript, it is your choice// whether to permit this exception to apply to your modifications.// If you do not wish that, delete this exception notice.//#include "engine.h"using namespace std;using namespace ost;ScriptCompiler::ScriptCompiler(ScriptCommand *cmd, const char *symset) :ScriptImage(cmd, symset){        inccount = 0;	mlist = NULL;        scrStream = (istream *)&scrSource;}void ScriptCompiler::fastBranch(ScriptInterp *interp){	Line *line;	ScriptInterp::Frame *frame;	Method m;	unsigned maxstep = fastStepping;	bool nongoto = false;	frame = interp->getFrame();	if(frame->line == frame->script->first)		nongoto = true;	while(maxstep-- && NULL != (line = interp->getLine()))	{		m = line->scr.method;		if(line->loop == 0xffff)		{			if(interp->getTrace())				return;			interp->setFrame();			interp->execute(m);		}		else if(m == (Method)&ScriptMethods::scrBegin ||			m == (Method)&ScriptMethods::scrReturn)		{			interp->setFrame();			interp->execute(m);			return;		}		else if(m == (Method)&ScriptMethods::scrGoto ||			m == (Method)&ScriptMethods::scrRestart)		{			if(nongoto)				return;			interp->setFrame();			interp->execute(m);			return;		}		else			return;			}}bool ScriptCompiler::checkSegment(Name *scr){	return true;}const char *ScriptCompiler::preproc(const char *token){        return "unknown keyword";} const char *ScriptCompiler::getDefined(const char *token){	return getLast(token);}void ScriptCompiler::commit(void){	Name *scr, *target;	const char *last = "";	NamedEvent *ev, *from;	unsigned ecount;	const char *en;	char pbuf[65];	char *ep;	while(inccount)		include(incfiles[--inccount]);	while(mlist)	{		scr = getScript(mlist->source);		if(!scr)		{			if(mlist->source != last)				slog.error("include from %s not found", mlist->source);			goto cont;		}		ecount = 0;		en = mlist->prefix;		if(!*en)			en = "*:";		target = mlist->target;		from = scr->events;		while(from)		{			if(!strnicmp(from->name, mlist->prefix, strlen(mlist->prefix)))			{				ev = (NamedEvent *)alloc(sizeof(NamedEvent));				ev->line = from->line;				ev->name = from->name;				ev->type = from->type;				ev->next = target->events;				target->events = ev;				++ecount;			}			from = from->next;		}				if(ecount)		{			setString(pbuf, sizeof(pbuf), en);			ep = strchr(pbuf, ':');			if(ep)				*ep = 0;			slog.debug("included %s from %s; %d events", pbuf, mlist->source, ecount);		}cont:				last = mlist->source;		mlist = mlist->next;	}	ScriptImage::commit();}char *ScriptCompiler::getToken(char **pre){	static char temp[513];	char *cp = temp + 1;	char *base = temp + 1;	char q;	int level;	if(pre)		if(*pre)		{			cp = *pre;			*pre = NULL;			return cp;		}	if(*bp == '=')	{			++bp;       		if(*bp == '{')        	{                	level = -1;                	while(*bp)                	{                        	if(*bp == '}' && !level)                                	break;                        	if(*bp == '{')                                	++level;                        	else if(*bp == '}')                                	--level;                        	*(cp++) = *(bp++);                	}                	if(*bp == '}')                        	++bp;                	*cp = 0;			*base = 0x01;	// special token                	return base;        	}		if(*bp == ' ' || *bp == '\t' || !*bp)			return "";		if(*bp == '\"' || *bp == '\'')		{			q = *(bp++);			while(q)			{				switch(*bp)				{				case '\\':					++bp;					if(!*bp)					{						q = 0;						break;					}					switch(*bp)					{					case 't':						*(cp++) = '\t';						++bp;						break;					case 'b':						*(cp++) = '\b';						++bp;						break;					case 'n':						*(cp++) = '\n';						++bp;						break;					default:						*(cp++) = *(bp++);					}					break;				case 0:					q = 0;					break;				default:					if(*bp == q)					{						++bp;						q = 0;					}					else						*(cp++) = *(bp++);				}			}			*cp = 0;			return base;		}		while(*bp != ' ' && *bp != '\t' && *bp)			*(cp++) = *(bp++);		*cp = 0;		return base;	}	if(!quote)		while(*bp == ' ' || *bp == '\t')			++bp;	if(!quote && *bp == '#' && (!bp[1] || bp[1] == '!' || isspace(bp[1])))		return NULL;	if(!quote && bp[0] == '%' && bp[1] == '%' && (!bp[2] || isspace(bp[2])))		return NULL;	if(!*bp)	{		paren = 0;		quote = false;		return NULL;	}	if(*bp == '\"' && !quote)	{		++bp;		quote = true;	}	if(!quote && *bp == '{')	{		level = -1;		while(*bp)		{			if(*bp == '}' && !level)				break;			if(*bp == '{')				++level;			else if(*bp == '}')				--level;			*(cp++) = *(bp++);		}		if(*bp == '}')			++bp;		*cp = 0;		return base;	}	if(!quote)	{		if(*bp == ',' && paren)		{			++bp;			return ",";		}			retry:		while(*bp && !isspace(*bp) && *bp != ',' && *bp != '=' && *bp != '(' && *bp != ')' )			*(cp++) = *(bp++);		if(*bp == '(')			++paren;		else if(*bp == ')')			--paren;		if(*bp == '=' && cp == base)		{			*(cp++) = *(bp++);			goto retry;		}		if(*bp == '=' && cp == base + 1 && ispunct(*base))		{			*(cp++) = *(bp++);			goto retry;		}		if((*bp == '(' || *bp == ')') && cp == base)			*(cp++) = *(bp++);		*cp = 0;		if(*bp == ',' && !paren)			++bp;		else if(*bp == '=')			*(--base) = *(bp);		if(!strcmp(base, "=="))			return ".eq.";		if(!strcmp(base, "="))			return "-eq";		if(!strncmp(base, "!=", 2))			return ".ne.";		if(!strncmp(base, "<>", 2))			return "-ne";		if(!strcmp(base, "<"))			return "-lt";		if(!strcmp(base, "<="))			return "-le";		if(!strcmp(base, ">"))			return "-gt";		if(!strcmp(base, ">="))			return "-ge";		return base;	}	if(*bp == '\\' && (bp[1] == '%' || bp[1] == '&' || bp[1] == '.' || bp[1] == '#'))	{		++bp;		*(cp++) = '{';		*(cp++) = *(bp++);	}requote:	if(isalnum(*bp) || strchr("~/:,. \t\'", *bp))	{		while(isalnum(*bp) || strchr("~=/:,. \t\'", *bp))			*(cp++) = *(bp++);	}	else while(!isspace(*bp) && *bp && *bp != '\"')		*(cp++) = *(bp++);	if(*bp == '\n' || !*bp)		paren = 0;	if(*bp == '\n' || !*bp || *bp == '\"')		quote = false;	if(*bp == '\\' && bp[1])	{		++bp;		switch(*bp)		{		case 0:			break;		case 't':			*(cp++) = '\t';			++bp;			break;		case 'b':			*(cp++) = '\b';			++bp;			break;		case 'n':			*(cp++) = '\n';			++bp;			break;		default:			*(cp++) = *(bp++);		}		goto requote;	}	if(*bp == '\n' || *bp == '\"')		++bp;	*cp = 0;	return base;}int ScriptCompiler::compile(const char *scrname){	char buffer[129];	char *token;	char *ext;#ifdef	WIN32	char *l1, *l2;	setString(buffer, sizeof(buffer), scrname);	l1 = strrchr(buffer, '/');	l2 = strrchr(buffer, '\\');	if(l1 > l2)		token = l1;	else		token = l2;#else	setString(buffer, sizeof(buffer), scrname);	token = strrchr(buffer, '/');#endif	if(!token)		token = buffer;	else		++token;	ext = strrchr(token, '.');	if(ext)	{		if(strstr(exec_extensions, ext) == NULL)			*ext = 0;	}	return compile(scrname, token);}Script::Name *ScriptCompiler::include(const char *token){	char buffer[256];	const char *local = cmds->getLast("binclude");	const char *prefix = cmds->getLast("include");	const char *cp;	Name *inc = getScript(token);	if(inc)		return inc;	if(!prefix)		return NULL;	snprintf(buffer, sizeof(buffer), "virtual.%s", token);	cp = cmds->getLast(buffer);	if(local)	{                if(cp)                        snprintf(buffer, sizeof(buffer),                                "%s/%s_%s.mac", local, token, cp);                else                        snprintf(buffer, sizeof(buffer),                                "%s/%s.mac", local, token);		if(!isFile(buffer) || !canAccess(buffer))			local = NULL;        }	if(!local)	{		if(cp)			snprintf(buffer, sizeof(buffer), 				"%s/%s_%s.mac", prefix, token, cp);		else			snprintf(buffer, sizeof(buffer), 				"%s/%s.mac", prefix, token);		if(!isFile(buffer) || !canAccess(buffer))			return NULL;	}	compile(buffer, (char *)token);	return getScript(token);}int ScriptCompiler::compileDefinitions(const char *filename){	char buffer[128];	int rtn;	const char *cp = strrchr(filename, '.');	if(!cp || stricmp(cp, ".def"))		return 0;	cp = strrchr(filename, '/');#ifdef	WIN32	if(!cp)		cp = strrchr(filename, '\\');	if(!cp)		cp = strchr(filename, ':');#endif	if(!cp)	{		cp = cmds->getLast("include");		if(cp)		{			snprintf(buffer, sizeof(buffer), "%s/%s",				cp, filename);			filename = buffer;		}	}	if(!isFile(filename) || !canAccess(filename))		return 0;	scrSource.open(filename);	if(!scrSource.is_open())		return 0;	Script::use_definitions = true;	rtn = compile((istream *)&scrSource, "definitions", filename);	scrSource.close();	scrSource.clear();	return rtn;}int ScriptCompiler::compile(const char *scrname, char *name){	int rtn;	scrSource.open(scrname);	if(!scrSource.is_open())		return 0;	rtn = compile((istream *)&scrSource, name, scrname);	scrSource.close();	scrSource.clear();	return rtn;}int ScriptCompiler::compile(istream *str, char *name, const char *scrname){	const char *errmsg = NULL;	const char *basename = name;	char filename[65];	unsigned lnum = 0;	char namebuf[256];	char gvarname[128];	char path[128];	char csname[128];	char *command, *token, *pretoken = NULL;	char *args[SCRIPT_MAX_ARGS + 1];	int maxargs = SCRIPT_MAX_ARGS;	const char *err;	char *cp = (char *)strrchr(scrname, '.');//	const char *var = cmds->getLast("datafiles");	bool trapflag;	int argc, key, tlen, initkey = 0, initcount = 0;	unsigned i;	unsigned short count, number, total = 0;	size_t gvarlen;	NamedEvent *events, *esave;	Name *script, *ds;	Line *line, *last;	unsigned long addmask, submask, trapmask, mask, cmask = 0;	Method handler;	unsigned char loopid, looplevel;	size_t offset = 0;	Name *base = NULL, *init = NULL;	bool sub = false;	streampos pos;	bool ignore;	scrAccess access = scrPUBLIC;	char temp[64];	char *pmode = NULL;	char *ftoken = NULL;	char *filter;	bool bm = false;	bool first = true;	unsigned long addPmask = 0, subPmask = (unsigned long)~0;	unsigned long addPmask1 = 0, subPmask1 = (unsigned long)~0;	char catchname[256];	const char *embed = NULL;	bool mscmd = false, execflag = false;	bool apps = false;	bool defs = false;	bool ripple = cmds->ripple;	bool wrapper = false;	merge_t *merge;	if(strstr(".bat.cmd", cp))		mscmd = true;	if(strstr(apps_extensions, cp))		apps = true;	else if(strstr(exec_extensions, cp))	{		snprintf(namebuf, sizeof(namebuf), "%s:%s", exec_prefix, name);		name = namebuf;		embed = exec_token;		wrapper = true;	}	if(!strnicmp(name, exec_prefix, strlen(exec_prefix)))		wrapper = true;	buffer = (char *)malloc(512);	bufsize = 512;	scrStream = str;	if(cp && !stricmp(cp, ".mac"))	{		bm = true;		ripple = false;	}	if(cp && !stricmp(cp, ".scr"))		ripple = false;#ifdef	WIN32	if(cp && !stricmp(cp, ".ini"))		ripple = true;#endif	if(cp && !stricmp(cp, ".conf"))		ripple = true;	if(cp && !stricmp(cp, ".def"))	{		ripple = false;		defs = true;	}	if(bm || defs)		access = scrPROTECTED;	gvarname[0] = '%';		snprintf(gvarname + 1, 56, "%s.", name);	gvarlen = strlen(gvarname);#ifdef	WIN32	const char *l1 = strrchr(scrname, '/');	const char *l2 = strrchr(scrname, '\\');	if(l1 > l2)		cp = (char *)l1;	else		cp = (char *)l2;#else	cp = (char *)strrchr(scrname, '/');#endif	if(cp)		++cp;	else		cp = (char *)scrname;	snprintf(filename, sizeof(filename), "%s", cp);compile:	trapflag = false;	count = number = 0;	last = NULL;	addmask = submask = trapmask = 0;	handler = NULL;	loopid = looplevel = 0;	bool then = false;	events = NULL;	setString(csname, sizeof(csname), name);	cp = strstr(csname, "::");	if(cp && !stricmp(cp, "::main") && !ripple)	{		initkey = SCRIPT_INDEX_SIZE;		*cp = 0;	}	if(ripple && cp)		initkey = SCRIPT_INDEX_SIZE;         key = Script::getIndex(csname);	if(first && (bm || defs))		initkey = SCRIPT_INDEX_SIZE;	else if(first)		initkey = key;	current = script = (Name *)alloc(sizeof(Name));	memset(script, 0, sizeof(Name));	script->name = alloc(csname);	script->mask = 0;	script->events = NULL;	addPmask1 = addPmask;	subPmask1 = subPmask;	addPmask = 0;	subPmask = (unsigned long)~0;	if(!first)		script->next = index[key];	script->filename = alloc(filename);	if(first)		init = script;	if(pmode)	{		if(!strnicmp(pmode, "pub", 3) || !stricmp(pmode, "program"))			script->access = scrPUBLIC;		else if(!strnicmp(pmode, "priv", 4) || !stricmp(pmode, "state"))			script->access = scrPRIVATE;		else if(!strnicmp(pmode, "prot", 4))			script->access = scrPROTECTED;		else if(!strnicmp(pmode, "fun", 3))			script->access = scrFUNCTION;		else if(!stricmp(pmode, "local"))			script->access = scrLOCAL;		else			script->access = access;	}	else		script->access = access;	if(!first)		index[key] = script;	pmode = NULL;

⌨️ 快捷键说明

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