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

📄 executable.cpp

📁 Basic语言的解释器 由于本人没有学过《编译原理》所以做的不好,等我学完《编译原理》后再做个好的. 我正在看《编译原理及实践》,所以把老师写的demo附上.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	}
	return 0;
}


int CExecutable::Ai_GetVarNo(char *name,int *result,int type)
{
	switch(type)
	{
	case INTEGER:
		{
			if(m_intArray.size()==0)
				return 0;
			for(int i=0;i<=m_intArray.size()-1;i++)
				if(!_strcmpi(name,m_intArray.at(i).name))
					*result=i;
				return 1;
		}
	default: return 0;
	}
	
}

int CExecutable::Ai_GetSubNo(char *name,int *result)
{
    int i;
	for(i=0;i<=m_Subs.size()-1;i++) // 在m_Subs里寻找叫SubName的过程
		if(_strcmpi(m_Subs.at(i).name,name)==0)
		{
			
			*result=i;
			return 1;
		}
		return 0;
}
int CExecutable::Ai_GetNextThen(int *result,int *index)
{
	int if_no=1; //出现If语句的次数
	for(int i=*index;i<=m_tokens.size()-1;i++)
	{
		if(m_tokens.at(i).tok==IF)
		{
			if_no++;
			continue;
		}
        if(m_tokens.at(i).tok==THEN)
		{
			if_no--;
			if(if_no==0)
			{
				*result=i;
				return 1;
			}
		}
	}
	return 0;
}


int CExecutable::Ai_GetNextEndIf(int *result,int *index)
{
	int if_no=1; //出现If语句的次数
	for(int i=*index;i<=m_tokens.size()-1;i++)
	{
		if(m_tokens.at(i).tok==IF)
		{
			if_no++;
			continue;
		}
        if(m_tokens.at(i).tok==END && i+1<=m_tokens.size()-1)
			if(m_tokens.at(i+1).tok==IF)
			{
				if_no--;
				if(if_no==0)
				{
					*result=i+1;
					return 2;
				}
			}
	}
	// 没有找到匹配的End If 则默认为是没有End If的Then后的单语句
    
	if(!Ai_GetNextThen(result,index)) // 先找Then
	{
		serror(8);
		return 0;
	}
	*index=*result+1;
	
	while(m_tokens.at(*index).token_type==ENTER) //跳过换行符
		(*index)++;
	if(!Ai_GetNextLine(result,index)) // 跳过Then后的一跳语句
	{
		serror(0);
		return 0;
	}
    *index=*result;
	return 1;
}

//index必须指到While
int CExecutable::Ai_GetNextLoop(int *result,int *index)
{
	int do_no=1; //出现Do语句的次数
	for(int i=*index;i<=m_tokens.size()-1;i++)
	{
		if(m_tokens.at(i).tok==DO)
		{
			do_no++;
			continue;
		}
        if(m_tokens.at(i).tok==LOOP)
		{
			do_no--;
			if(do_no==0)
			{
				*result=i;
				return 1;
			}
		}
	}
	return 0;
}

int CExecutable::Ai_GetLastDo(int *result,int *index)
{
	int loop_no=1; //出现Loop语句的次数
	if(m_tokens.size()<1 || *index>=m_tokens.size()-1) // 如果index超出范围
		return 0;
	for(int i=*index;i>=0;i--)
	{
		if(m_tokens.at(i).tok==LOOP)
		{
			loop_no++;
			continue;
		}
        if(m_tokens.at(i).tok==DO)
		{
			if(i-1>=0)
				if(m_tokens.at(i-1).tok==EXIT) // 如果是Exit Do中的Do
					continue; 
				loop_no--;
				if(loop_no==0)
				{
					*result=i;
					return 1;
				}
		}
	}
	return 0;
}


int CExecutable::Ai_GetNextLine(int *result,int *index)// result指到下一个ENTER换行符
{
	for(int i=*index;i<=m_tokens.size()-1;i++)
		if(m_tokens.at(i).token_type==ENTER)
		{
			*result=i;
			return 1;
		}
		return 0;
}

int CExecutable::Ai_GetNextSubarg(vector<CToken> &Subarg,int *index)
{
	int subno;
	if(!Ai_GetSubNo(m_tokens.at(*index).token,&subno)) // 先把此过程的index传给subno
	{
		serror(7);
		return 0;
	}
	
	(*index)++;
	if(*m_tokens.at(*index).token=='(')
		(*index)++;
	else
	{	   
		serror(16);
		return 0;
	}
	int l=0,type;
	vector <CToken> argtokens;
	CToken *pA_Subarg; // 单个参数
	argtokens=m_Subs.at(subno).m_argtokens;
	if(argtokens.size()<=0) 
		return 1;
	while(*m_tokens.at(*index).token!=')')
	{
		// 先通过subno在m_Subs里找到参数的定义类型,再通过此类型
		// 调用Ai_GetNextValue得到参数值
		while(l<argtokens.size()-1) // type得到参数类型
		{
			if(argtokens.at(l).token_type==COMMAND &&
				argtokens.at(l).tok==AS)
			{
				l++;
				type=argtokens.at(l).tok;
				break;
			}
			l++;
		}
		pA_Subarg=new CToken;
		switch(type) //  根据type类型来调用Ai_GetNextValue得到参数值
		{
		case INTEGER:
			{
				int result;
				Ai_GetNextValue(&result,INTEGER,index);
				pA_Subarg->tokenlength=sizeof(int);
				pA_Subarg->token=new char[pA_Subarg->tokenlength];
				memcpy(pA_Subarg->token,&result,sizeof(int));
				break;
			}
		default:
			break;
		}
		pA_Subarg->tok=type;
		Subarg.push_back(*pA_Subarg);
		delete pA_Subarg;
		(*index)++;
		while(*m_tokens.at(*index).token==',') // 如果参数后面一个token是','则必须跳过它
			(*index)++;
		
	}
	return 1;
}

void CExecutable::get_exp(int *result,int *index)
{
    if (!*m_tokens.at(*index).token)
	{
        serror(2);
        return;
    }
    level2(result,index);
    
	//putback();  /*return last token read to input stream */
}


/* add or subtract two terms */
void CExecutable::level2(int *result,int *index)
{
    register char op;
    int hold;
    level3(result,index);
    while ((op = *m_tokens.at(*index).token) =='+' || op == '-')  
	{
        (*index)++;
        level3(&hold,index);
        arith(op,result,&hold);
    }
}


/* multiply or divide two factors */
void CExecutable::level3(int *result,int *index)
{
	register char op;
    int hold;
    level4(result,index);
    while ((op = *m_tokens.at(*index).token) == '*' || op == '/' || op == '%')  
	{
        (*index)++;
        level3(&hold,index);
        arith(op,result,&hold);
    }
}


/* process integer exponent */
void CExecutable::level4(int *result,int *index)
{
	register char op;
    int hold;
    level5(result,index);
    if ((op = *m_tokens.at(*index).token) == '^') 
	{
        (*index)++;
        level5(&hold,index);
        arith(op,result,&hold);
    }
}


/* is a unary + or - */              
void CExecutable::level5(int *result,int *index)
{
    register char op;
    op = 0;
    if ((m_tokens.at(*index).token_type==DELIMITER) && 
		*m_tokens.at(*index).token == '+' || 
		*m_tokens.at(*index).token == '-' )  
	{
        op = *m_tokens.at(*index).token;
        (*index)++;
    }
    level6(result,index);
    if (op)  
		if(op=='-')
			*result=-(*result);
}


/* process parenthesized expression */                
void CExecutable::level6(int *result,int *index)
{
	if ((*m_tokens.at(*index).token == '(') && (m_tokens.at(*index).token_type == DELIMITER))  
	{
        (*index)++;
        level2(result,index);
        if (*m_tokens.at(*index).token!=')')
            serror(1);
        (*index)++;
    }
    else 
        primitive(result,index);
}

/* find value of number or variable */
void CExecutable::primitive(int *result,int *index)
{
	int token_type=m_tokens.at(*index).token_type;
    if(Isvar(m_tokens.at(*index).token))		
		token_type=VARIABLE;
    switch (token_type)  
	{
	case VARIABLE:
		find_var(m_tokens.at(*index).token,result);
		(*index)++;
		return;
	case NUMBER:
		*result = atoi(m_tokens.at(*index).token);
		(*index)++;
		return;
	default:
		serror(0);
    }
}

int CExecutable::find_var(char *var_name,void *value)
{
	for(int i=0;i<=m_intArray.size()-1;i++)
		if(!strcmp(var_name,m_intArray.at(i).name))
		{
			int *int_value=(int *)value;
			*int_value=m_intArray.at(i).value;
			return 1;
		}
		return 0;
}

int CExecutable::Isvar(char *name)
{
	if(m_intArray.size()==0)
		return 0;
	for(int i=0;i<=m_intArray.size()-1;i++)
		if(!strcmp(name,m_intArray.at(i).name))
			return INTEGER;
		return 0;
}

/* perform the specified arithmetic */
void CExecutable::arith(char o,int *r,int *h)
{
    /*register*/ int t,ex;
    
    switch (o)  {
	case '-':
		*r = *r-*h;
		break;
	case '+':
		*r = *r+*h;
		break;
	case '*':
		*r = *r**h;
		break;
	case '/':
		*r = (*r)/(*h);
		break;
	case '%':
		*r = (*r)%(*h);
		break;
	case '^':
		ex = *r;
		if (*h==0)  {
			*r = 1;
			break;
		}
		for (t=*h-1;t>0;--t)  *r=(*r)*ex;
		break;
    }
}


void CExecutable::serror(int error)
{
	char *e[] = {
        "syntax error",          // 0
			"unbalanced parentheses", // 1
			"no expression present", // 2
			"equal sign expected",  // 3
			"not a variable",      // 4
			"label table full",   // 5
			"duplicate label",      // 6
			"undefined label",     // 7
			"THEN expected",      // 8
			"TO expected",        // 9
			"too many nested FOR loops", // 10
			"NEXT without FOR",    // 11
			"too many nested GOSUB", // 12
			"RETURN without GOSUB",   // 13
			"While without Do",  // 14
			"Do without Loop", // 15
			"'(' is not behind the call of sub" // 16
    };
	
    printf ("%s\n",e[error]);
}

void CExecutable::Debug(int i)
{
	printf("Debug token:%s ,tok:%d ,index:%d \n",m_tokens.at(i).token,m_tokens.at(i).tok,i);
}

⌨️ 快捷键说明

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