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

📄 make.cpp

📁 Basic语言的解释器 由于本人没有学过《编译原理》所以做的不好,等我学完《编译原理》后再做个好的. 我正在看《编译原理及实践》,所以把老师写的demo附上.
💻 CPP
字号:
// Make.cpp: implementation of the CMake class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Make.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CMake::CMake(char *Prog,int Proglength)
{
  proglength=Proglength;
  prog=new char[Proglength+1];
  strcpy(prog,Prog);
}

CMake::~CMake()
{
 
}


CToken CMake::get_token(void) 
{
	//register char *temp;
	CToken m_token;
    m_token.token_type=0;
	m_token.tok=0;
	//temp=m_token.token;
	if(*prog=='\0')
	{
		m_token.tokenlength=1;
		m_token.token=new char[m_token.tokenlength];
		*m_token.token='\0';
		m_token.tok=0;
		m_token.token_type=FINISHED;
		return m_token;
	}
	while(iswhite(*prog)) ++prog;
    
	if(*prog=='\r') //如果是换行符
	{
		m_token.tokenlength=2;
		m_token.token=new char[m_token.tokenlength];
		m_token.token[0]=*prog;
		m_token.token[1]='\0';
		m_token.token_type=ENTER;
		prog++;
		return m_token;
	}
	if( isdelim(*prog)) // 如果找得到运算符号标记
	{
	   m_token.tokenlength=2;
	   m_token.token=new char[m_token.tokenlength];
	   *m_token.token=*prog; 
	   *(m_token.token+1)='\0';
	   m_token.tok=0;
	   m_token.token_type=DELIMITER;
	   prog++;
	   return m_token;            // 譬如 token[0]='+' token[1]='\0';
	}

	if(*prog=='"')   // 如果是字符串
	{
		prog++;
		int i=0;
		char token_temp[TOKEN_MAX];
		while(*prog!='"' && *prog!='\r' && i<TOKEN_MAX)
		{
		    token_temp[i]=*prog;
			i++;
			prog++;
		}
		prog++;
		token_temp[i]='\0';
		m_token.tokenlength=i+1;
		m_token.token=new char[m_token.tokenlength];
		memcpy(m_token.token,token_temp,m_token.tokenlength);
		m_token.token_type=QUOTE;
		return m_token;
	}

	if( isdigit(*prog)) //如果找到数字标记
	{
		int i=0;
		char token_temp[TOKEN_MAX];
		while(isdigit(*prog) && i<TOKEN_MAX) //小于token最长为80个字符
		{
			token_temp[i]=*prog;
			i++;
			prog++;
		}
		token_temp[i]='\0';
		m_token.tokenlength=i+1;
		m_token.token=new char[m_token.tokenlength];
		memcpy(m_token.token,token_temp,m_token.tokenlength);
		m_token.token_type=NUMBER;
		return m_token;
	}

	if( isalpha(*prog)) //如果是命令COMMAND或是一般标记STRING
	{
		int i=0;
		char token_temp[TOKEN_MAX];
		while(!isdelim(*prog) && *prog!=' ' && i<=TOKEN_MAX) //不能是运算符号和空格
		{
			token_temp[i]=*prog;
			i++;
			prog++;
		}
		token_temp[i]='\0';
		m_token.tokenlength=i+1;
		m_token.token=new char[m_token.tokenlength];
		memcpy(m_token.token,token_temp,m_token.tokenlength);
		if(look_up(m_token.token)) //如果能查到它是COMMAND标识符
		{
			m_token.token_type=COMMAND;
			m_token.tok=look_up(m_token.token);
		}
		else // 如果不能在COMMAND里查到它,同时它有是string如: GetName 
		{
			m_token.token_type=STRING;
		}
		return m_token;
	}
	

	m_token.token_type=NONE;
	m_token.tokenlength=0;
	prog++;
	return m_token;
}

int CMake::iswhite(char c)
{
	if(c==' '||c=='\t') return 1;
	else return 0;
}

int CMake::isdelim(char c)
{
	if( findchar(STRDELIMITER,*prog) >= 0 || c==9 || c=='\r' || c==0)
		return 1;
	return 0;
}

int CMake::findchar(char *str,char ch) 
{
	int length=strlen(str);
	if(length>0)
	{
		for(int i=0;i<length;i++)
			if(str[i]==ch)
			   return i;
			return -1;
	}
	else return -1;
}

int CMake::look_up(char *c)
{
	if(_strcmpi(c,"Print")==0)
	 return PRINT;
    if(_strcmpi(c,"Integer")==0)
	 return INTEGER;
	if(_strcmpi(c,"Dim")==0)
	 return DIM;
	if(_strcmpi(c,"As")==0)
	 return AS;
	if(_strcmpi(c,"If")==0)
	 return IF;
	if(_strcmpi(c,"Then")==0)
	 return THEN;
	if(_strcmpi(c,"End")==0)
	 return END;
	if(_strcmpi(c,"While")==0)
	 return WHILE;
	if(_strcmpi(c,"Loop")==0)
	 return LOOP;
	if(_strcmpi(c,"Do")==0)
	 return DO;
	if(_strcmpi(c,"Exit")==0)
	 return EXIT;
	if(_strcmpi(c,"Sub")==0)
	 return SUB;
    if(_strcmpi(c,"Call")==0)
	 return CALL;

    return 0;
}

void CMake::Make(void)
{
	CToken m_token;   // 一个临时的token
	vector <CToken> m_tokens; // 装下所有的token集
	CSub m_Sub; // 一个临时的Sub
	///*
    for(;;)  // 依此从源代码中提取token,装到tokens中
	{
		m_token=get_token(); // 得到下一个token
		if(m_token.token_type==NONE)
			continue;

		/////////////////////////////////////////////////
		//   如果是遇到过程定义开头的Sub
		if(m_token.token_type==COMMAND && m_token.tok==SUB)
		{
			   if(m_tokens.size()>=1)
				if(m_tokens.at(m_tokens.size()-1).token_type==COMMAND ||
					m_tokens.at(m_tokens.size()-1).tok==END) // 如果是End Sub中的Sub
					continue;
				
				m_token=get_token();
				while(m_token.token_type==NONE)  // 过滤NONE的token
					m_token=get_token();
				
				if(m_token.token_type==STRING)
				{
					m_Sub.namelength=m_token.tokenlength;
					m_Sub.name=new char[m_Sub.namelength];
					strcpy(m_Sub.name,m_token.token);
				}
				else
				{
					printf("Sub name error!");
					return ;
				}
				m_tokens.clear(); // 清除上个sub的tokens,重新开始记录token
          
				//下面是关于参数的处理
				m_token=get_token();
				if(*m_token.token=='(')
				{
					for(;;)
					{
						m_token=get_token(); // 得到下一个token
						if(m_token.token_type==NONE)
							continue;
						if(*m_token.token==',')
							continue;
						if(m_token.token_type==FINISHED)
							break;
						if(*m_token.token==')') 
							break;
						m_Sub.m_argtokens.push_back(m_token);
					}
				}	  
				continue;
		}

		// 如果遇到End Sub
		if(m_token.token_type==COMMAND && m_token.tok==END)
		{
			m_token=get_token();
			while(m_token.token_type==NONE)  // 过滤NONE的token
				m_token=get_token();
			if(m_token.token_type==COMMAND && m_token.tok==SUB)
			{
				m_Sub.m_tokens=m_tokens;
				m_Subs.push_back(m_Sub);
				continue;
			}
		}
		///////////////////////////////////////////////////////
		m_tokens.push_back(m_token); //将得到的token装到m_tokens集中
		if(m_token.token_type==FINISHED) //如果这是最后的字符,则退出
		  break;
	}
     //*/
}

⌨️ 快捷键说明

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