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

📄 gvma.cpp

📁 一个RPG术语查询器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <stdlib.h>

#define FILENOTFOUND 1
#define NOPARAMS 2
#define FILEEMPTY 3


#define EMPTY 0
#define TOKENNUM 1
#define TOKENALPH 2
#define TOKENLABEL 3
#define TOKENCOMMENT 4
#define TOKENADD 5
#define TOKENSTRING 6
#define TOKENFLOAT 7
#define TOKENCHAR 8

#define ERRALPHINNUM -1
#define ERRCOLON -2
#define ERRMINUS -3
#define ERRCOMMENT -4
#define ERRINVALIDCHAR -5
#define ERRSTRING -6
#define ERRPERIOD -7

#define KEYEMPTY 0
#define KEYINT 1
#define KEYBYTE 2
#define KEYFLOAT 3


int ERRMSG = 0;
int nkeywords=0;


union CONVERTDOUBLE
{
	char bytes[sizeof(double)];
	double data;
};

union CONVERTINT
{
	char bytes[sizeof(int)];
	int data;
};



class KEYWORD
{
public:
	char *token;
	int type;
	char bvalue;
	int value;
	double fvalue;

	KEYWORD()
	{
		++nkeywords;
		type=KEYEMPTY;
		
		token=NULL;
		value=0;
		fvalue=0;
		bvalue=0;
	}
	
	KEYWORD(char *token, int value)
	{
		++nkeywords;
		type=KEYINT;
		
		KEYWORD::token=token;
		KEYWORD::value=value;
		fvalue=0;
		bvalue=0;
	}

	KEYWORD(char *token, double fvalue)
	{
		
		++nkeywords;
		type=KEYFLOAT;

		KEYWORD::token=token;
		KEYWORD::fvalue=fvalue;
		value=0;
		bvalue=0;
	}
	
	KEYWORD(char *token, char bvalue)
	{
		++nkeywords;
		type=KEYBYTE;
		
		KEYWORD::token=token;
		KEYWORD::bvalue=bvalue;
		
		value=0;
		fvalue=0;
	}

};	

class LUSAGE
{
	public:
		int point;
		LUSAGE *next;

	LUSAGE(int point)
	{
		LUSAGE::point=point;
		next=NULL;
	}
	~LUSAGE()
	{
		if(next!=NULL) delete next;
	}
};


class LFIXUP
{

	public:
		LUSAGE *fixes;
		char token[256];
		int address;
		LFIXUP *next;

	LFIXUP(char *token,int address)
	{
		next=NULL;
		fixes=NULL;		
		LFIXUP::address=address;
		strcpy(LFIXUP::token,token);
	}
	~LFIXUP()
	{
		if(fixes!=NULL) delete fixes;
		if(next!=NULL) delete next;
	}
};


class LABELFIX
{
	public:
		LFIXUP *listfixup;
		
	LABELFIX()
	{
		listfixup=NULL;
	}

	
	void addpoint(LFIXUP *fix, int pointtoadd)
	{
		if(fix==NULL) return;
		
		if(fix->fixes==NULL)
		{
			fix->fixes=new LUSAGE(pointtoadd);
			return;
		}
		
		
		
		LUSAGE *working=fix->fixes;
		while(1)
		{
			if(working->next==NULL)
			{
				working->next=new LUSAGE(pointtoadd);
				return;
			}
			working=working->next;
		}
	}
	
	
	int fixup(unsigned char *code)
	{

		
		if(listfixup==NULL) return 0;

		CONVERTINT writeint;
		int writeiterate;
		LFIXUP *working=listfixup;
		LUSAGE *crawler=NULL;
		
		while(1)
		{

			if(working->fixes!=NULL)
			{
				crawler=working->fixes;
				while(1)
				{
					if(working->address==-1)
					{
						std::cout << "Address used without label : " << working->token << std::endl;
						return -1;
					}

					writeint.data=working->address;
					for(writeiterate=0;writeiterate<sizeof(int);++writeiterate)
					{
						code[crawler->point+writeiterate]=writeint.bytes[writeiterate];
					}
					

					if(crawler->next==NULL) break;
					crawler=crawler->next;
				}
			}

			if(working->next==NULL) return 0;
			working=working->next;

		}






	}
	
	int findaddress(char *label)
	{

		LFIXUP *working=listfixup;
		if(working==NULL) return -1;
		while(1)
		{
			if(strcmp(working->token,label)==0)
			{
				return working->address;

			}
			if(working->next==NULL) return -1;
			working=working->next;
		}


	}
	int addusage(char *label, int address)
	{

		//Get rid of the : and &
		char *token=label+1;

		//Search for a label that matches our address
		//If not found, create a new label with
		//address of -1 for use later :D


		//If we have no entries then
		//make one and stop :D
		if(listfixup==NULL)
		{
			listfixup=new LFIXUP(token,-1);
			addpoint(listfixup,address);
			return 0;
		}	
		
		//Search for an instance for fixup
		//If not found, add a new entry
		LFIXUP *working=listfixup;
		
		
		while(1)
		{
			if(strcmp(working->token,token)==0)
			{
				//Found our label, let's add a point
				if(working->address==-1)
				{
					addpoint(working,address);
					return 0;
				}
				else return working->address;

			}
			
			
			if(working->next==NULL)
			{
				//Make a new entry since one is not found
				working->next = new LFIXUP(token,-1);
				addpoint(working->next,address);
				return 0;

			}
			working=working->next;
		
		}

		
		

	}
	
	
	int addlabel(char *label,int address)
	{
		//Get rid of the : and *
		char *token=label+1;
		
		//If we have no entries then just make this label the first one
		//and exit addlabel :)
		if(listfixup==NULL)
		{
			listfixup =new LFIXUP(token, address);
			return 0;
		
		}	
		
		
		//Search for an instance for fixup
		//If not found, add a new entry
		LFIXUP *working=listfixup;
		while(1)
		{
			
			if(strcmp(working->token,token)==0)
			{
				//If our label has been referenced, but has no address
				//reference our label with this address
				if(working->address==-1)
				{
					working->address=address;
					return 0;
				}
				else return -1;
			}
			if(working->next==NULL) break;
			working=working->next;
		}

		working->next = new LFIXUP(token,address);
		return 0;

	}


	~LABELFIX()
	{
		if(listfixup!=NULL) delete listfixup;
	
	}
};








class TOKEN
{
	
	public:
		
		char *token;
		int type;
		int line;
		TOKEN *next;
	
	TOKEN(int line)
	{
		token = new char[256];
		if(token == NULL) std::cout << "Fatal oopsies, token unable to grab 256 bytes!" << std::endl;
		TOKEN::line=line;
		next=NULL;
		token[0]=0;
		type=EMPTY;
	}
	TOKEN()
	{
		token = new char[256];
		if(token == NULL) std::cout << "Fatal oopsies, token unable to grab 256 bytes!" << std::endl;
		line=0;		
		next=NULL;
		token[0]=0;
		type=EMPTY;
	}
	
	void getbigplease()
	{
		//This is only a request :D
		char *huhu = new char[65536];
		if(huhu != NULL)
		{
			
			memcpy(huhu,token,256);
			delete[] token;
			token=huhu;
		}
		
		else
		{
			std::cout << "Danger Will Robinson!  String can only be 256 chars :D" << std::endl;
		}



	}
	
	
	~TOKEN()
	{
		if(token!=NULL) delete[] token;
		if(next!=NULL) delete next;
	}
};


int findkeyword(char *word, KEYWORD words[], int nkeywords)
{
	int pos=0;
	while(pos<nkeywords)
	{
		if(strcmp(words[pos].token,word)==0) return pos;
		++pos;
	}
	return -1;
}


TOKEN *traverse(TOKEN *root)
{

	if(root->next==NULL) return root;
	else return traverse(root->next);

}

int findbytes(TOKEN *root,KEYWORD words[])
{
	TOKEN *working=root;
	int counter=0;
	int test;
	do
	{
		switch(working->type)
		{
			case TOKENCOMMENT:
			case TOKENLABEL:
			case EMPTY:
				break;
			
			case TOKENALPH:
				test=findkeyword(working->token,words,nkeywords);
				if(test!=-1)
				{
					
					switch (words[test].type)
					{
						case KEYEMPTY:
						break;
						
						case KEYBYTE:
						counter+=sizeof(int);
						break;
						
						case KEYINT:
						counter+=sizeof(int);
						break;
						
						case KEYFLOAT:
						counter+=sizeof(double);
						break;
					}
				}
						
				break;
			case TOKENCHAR:
				counter+=((strlen(working->token)+(sizeof(int)-1))/sizeof(int))*sizeof(int);
				break;
			case TOKENSTRING:
				counter+=((strlen(working->token)+sizeof(int))/sizeof(int))*sizeof(int);
				break;	
			case TOKENADD:
			case TOKENNUM:
				counter+=sizeof(int);
				break;
			case TOKENFLOAT:
				counter+=sizeof(double);
				break;
			
		}
		working=working->next;
	} while(working!=NULL);
	return counter;

}


void converttokens(TOKEN *root, KEYWORD words[], int nkeywords, char *outputfile, int endian)
{
	
	CONVERTINT writeint;
	CONVERTDOUBLE writedouble;
	int writeiterate;
	LABELFIX fixerupper;
	TOKEN *working=root;
	int test=findbytes(root,words);
	if(test<1)
	{
		std::cout << "No usable tokens found in file!" << std::endl;
		return;
	}
	unsigned char *ops = new unsigned char[test];
	if(ops==NULL)
	{
		std::cout << "OUT OF MEMORY" << std::endl;	
		return;

	}
	std::cout << "Found " << test << " bytes" << std::endl;
	int opspos=0;
	
	do
	{
		switch (working->type)
		{
			case EMPTY:
				break;
			case TOKENALPH:
				test=findkeyword(working->token,words,nkeywords);
				if(test!=-1)
				{
					
					switch (words[test].type)
					{
						case KEYEMPTY:
						break;
						
						case KEYBYTE:
						writeint.data=(int)words[test].bvalue;
						for(writeiterate=0;writeiterate<sizeof(int);++writeiterate)
						{
							ops[opspos+writeiterate]=writeint.bytes[writeiterate];
						}	
						opspos+=sizeof(int);
						break;
						
						case KEYINT:
						writeint.data=words[test].value;
						for(writeiterate=0;writeiterate<sizeof(int);++writeiterate)
						{
							ops[opspos+writeiterate]=writeint.bytes[writeiterate];
						}	
						opspos+=sizeof(int);
						break;

						case KEYFLOAT:
						writedouble.data=words[test].fvalue;
						for(writeiterate=0;writeiterate<sizeof(double);++writeiterate)
						{
							ops[opspos+writeiterate]=writedouble.bytes[writeiterate];
						}	
						opspos+=sizeof(double);
						break;

					}
					
					
				}
				else
				{
					std::cout << std::endl << "Token Error(" << working->line << "): Keyword not found - " << working->token << std::endl;
					delete[] ops;
					return;
				}
				break;
			case TOKENNUM:
				if(strcmp(working->token,"-")==0)
				{
					std::cout << std::endl << "Token Error(" << working->line << "): Number missing from '-'"<< std::endl;
					delete[] ops;
					return;

				}
				writeint.data=atoi(working->token);
				for(writeiterate=0;writeiterate<sizeof(int);++writeiterate)
				{
					ops[opspos+writeiterate]=writeint.bytes[writeiterate];
				}	
				opspos+=sizeof(int);
				break;
			case TOKENFLOAT:
				if(strcmp(working->token,"-")==0)
				{
					std::cout << std::endl << "Token Error(" << working->line << "): Number missing from '-'"<< std::endl;
					delete[] ops;
					return;

				}
				if(strcmp(working->token,".")==0)
				{
					std::cout << std::endl << "Token Error(" << working->line << "): Number missing from '.'"<< std::endl;
					delete[] ops;
					return;

				}
				
				writedouble.data=atof(working->token);
				for(writeiterate=0;writeiterate<sizeof(double);++writeiterate)
				{
					ops[opspos+writeiterate]=writedouble.bytes[writeiterate];
				}	
				opspos+=sizeof(double);
				break;
			
			case TOKENSTRING:
				if(strlen(working->token)>0)
				{
					strcpy((char *)(ops+opspos),working->token);
					opspos+=((strlen(working->token)+sizeof(int))/sizeof(int))*sizeof(int);
					
				}
				else
				{
					std::cout << std::endl << "Token Error(" << working->line << "): Quotes contain no string!"<< std::endl;
					delete[] ops;
					return;
				}
				break;


			case TOKENCHAR:
				if(strlen(working->token)>0)
				{
					strcpy((char *)(ops+opspos),working->token);
					opspos+=((strlen(working->token)+(sizeof(int)-1))/sizeof(int))*sizeof(int);
					
				}
				else
				{
					std::cout << std::endl << "Token Error(" << working->line << "): Single quotes contain no string!"<< std::endl;
					delete[] ops;
					return;
				}
				break;
			case TOKENLABEL:
				if(fixerupper.addlabel(working->token,opspos)==-1)
				{
					std::cout << std::endl << "Token Error(" << working->line << "): Duplicate label!" << std::endl;
					std::cout << "Duplicate " << working->token << std::endl;
					delete[] ops;
					return;
				}
				break;
			case TOKENADD:
				//Label fixup later
				if(strcmp(working->token,"&")==0)
				{
					std::cout << std::endl << "Token Error(" << working->line << "): token missing with address '&'"<< std::endl;
					delete[] ops;
					return;

				}
				
				writeint.data=fixerupper.addusage(working->token,opspos);
				for(writeiterate=0;writeiterate<sizeof(int);++writeiterate)
				{
					ops[opspos+writeiterate]=writeint.bytes[writeiterate];
				}	

⌨️ 快捷键说明

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