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

📄 express.cpp

📁 c语言写的VB编译器
💻 CPP
字号:
//////////////////////////////////////////////
//                                          //
//    Express.cpp                           //
//    表达式计算模块                        //
//    处理数值表达式计算和布尔表达式计算    //
//    最后更新时间:2004年4月23日11:33      //
//                                          //
//////////////////////////////////////////////



#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>

#include "Express.h"

double Expression(const char strExp[MaxY], int &Seat)
{
	// 计算表达式的值

	double Expr;

	// 计算项的值
	Expr = Term(strExp, Seat);

	if (Error)
	{
		// 有错误,返回
		return 0;
	}

	while (Seat < strlen(strExp) && 
			(strExp[Seat] == '+' || strExp[Seat] == '-'))
	{
		// 还有项需要计算

		Seat++;
		switch (strExp[Seat - 1])
		{
		case '+':
			// 加号

			Expr += Term(strExp, Seat);
			break;
		case '-':
			// 减号

			Expr -= Term(strExp, Seat);
			break;
		}

		if (Error)
		{
			return 0;
		}
	}

	// 返回表达式的值
	return Expr;
}

double Term(const char strExp[MaxY], int &Seat)
{
	// 计算项的值

	double Tem;

	// 计算因式的值
	Tem = Factor(strExp, Seat);

	if (Error)
	{
		// 有错误,返回

		return 0;
	}

	while (Seat < strlen(strExp) && 
			(strExp[Seat] == '*' || strExp[Seat] == '/' || strExp[Seat] == '%'))
	{
		// 还有因式需要计算

		Seat++;
		switch (strExp[Seat - 1])
		{
		case '*':
			// 乘号

			Tem *= Factor(strExp, Seat);
			break;
		case '/':
			// 除号

			double Div = Factor(strExp, Seat);
			if (fabs(Div) < 0.000001 )
			{
				// 除数为0,错误

				Error = ErrorZeroDivision;
			}
			else
			{
				// 除数不为0

				Tem /= Div;
			}
			break;
		case '%':
			// 取余数

			int Num2 = Factor(strExp, Seat);
			if (Num2 < 0.000001)
			{
				// 除数为0,错误

				Error = ErrorZeroDivision;
			}
			else
			{
				Tem = (int) Tem %  Num2;
			}
			break;

		}

		if (Error)
		{
			return 0;
		}
	}

	// 返回项的值
	return Tem;
}

double Factor(const char strExp[MaxY], int &Seat)
{
	// 计算因式的值

	if (strExp[Seat] == '(')
	{
		// 因式中含有括号,开始表达式处理

		// 越过左括号位
		Seat++;

		// 返回表达式的值
		double Exp = Expression(strExp, Seat);

		if (Error)
		{
			return 0;
		}

		// 越过右括号位
		Seat++;

		// 返回因式的值
		return Exp;
	}
	else if (strExp[Seat] == '+')
	{
		// 是正号

		// 越过正好位
		Seat++;

		// 返回因式的值
		double Result = Factor(strExp, Seat);

		return Result;
	}
	else if (strExp[Seat]=='-')
	{
		// 是负号

		// 越过负号位
		Seat++;

		// 返回因式的相反数
		double Result = -Factor(strExp, Seat);

		return Result;
	}
	else
	{
		// 处理普通因式

		// 存储因式的表达式
		char strTemp[MaxY];
		strTemp[0] = '\0';

		char Chr = strExp[Seat];

		while (isalpha(Chr) || isdigit(Chr) || Chr == '_' || Chr == '.')
		{
			// 是字母、数字或小数点

			// 添加如表达式
			strcat(strTemp, " ");
			strTemp[strlen(strTemp) - 1] = Chr;

			// 位置后移
			Seat++;

			Chr = strExp[Seat];
		}

		double Value;
		if (IsNumber(strTemp, Value))
		{
			return Value;
		}

		switch (GetType(strTemp))
		{
			// 查看因式的类型

		case NoType:
			// 有未定义的变量错误

			// 输出错误
			Error = ErrorUndefined;

			return 0;
		case Integer:
			// 是整形变量

			return VarValue_Int(strTemp);
		case Real:
			// 是实型变量

			return VarValue_Real(strTemp);
		case Array:
			// 是数组

			// 存储数组变量名
			char strVar[MaxLenOfVar];

			// 得到变量名
			strcpy(strVar,strTemp);

			// 得到其数组指针
			VarArrayHeadType *pThis = GetArrayDim(strVar);

			char strPara[MaxY];

			int SeatNew;
			if (!GetParaStr(strExp, Seat, strPara, SeatNew))
			{
				// 缺少对应括号

				Error = ErrorMissingBracketInArray;

				return 0;
			}

			Seat = SeatNew;

			// 取各下标
			int Dim[MaxDim];
			int TotDim;
			Para(strPara, Dim, TotDim);
			if (pThis->TotDim != TotDim)
			{
				// 维数不正确

				Error = ErrorDim;

				return 0;
			}

			// 计算数组元素位置
			int Position = CalcPosition(pThis, Dim);
			if (Error)
			{
				return 0;
			}

			// 取数组元素值
			int Result = GetValue(pThis, Position);
			if (Error)
			{
				return 0;
			}

			return Result;

		case SystemFunc:
			// 是系统函数

			if (strcmp(strTemp,"RND") == 0)
			{
				// 随机函数

				// 取参数
				GetParaStr(strExp, Seat, strPara, SeatNew);
				Seat = SeatNew;

				// 计算参数值
				int SeatPara = 0;
				int Temp = Expression(strPara, SeatPara);

				if (Error)
				{
					return 0;
				}

				if (Temp < 1)
				{
					// 随机参数小于零

					Error = ErrorRND;
					return 0;
				}
				else
				{
					return random(Temp);
				}
			}
			else if (strcmp(strTemp,"INT")==0)
			{
				// 取整函数

				// 取参数
				GetParaStr(strExp, Seat, strPara, SeatNew);
				Seat = SeatNew;

				// 计算参数值
				int SeatPara = 0;
				int Result = Expression(strPara, SeatPara);

				if (Error)
				{
					return 0;
				}
				else
				{
                    return Result;
				}
			}
			else if (strcmp(strTemp,"SQR")==0)
			{
				// 求平方根函数

				// 取参数
				GetParaStr(strExp, Seat, strPara, SeatNew);
				Seat = SeatNew;

				// 计算参数值
				int SeatPara = 0;
				double Result = Expression(strPara, SeatPara);

				if (Error)
				{
					return 0;
				}
				else
				{
                    return sqrt(Result);
				}
			}
			else if (strcmp(strTemp,"PI")==0)
			{
				// 圆周率

				return Pi;
			}
			break;
		}
	}

	return 0;
}

void BoolChange
	(
	const char ExpIn[MaxY],	// 源布尔表达式
	char *Return			// 返回字符串
	)
{
	// 变换布尔表达式
	// NOT	->	!
	// AND	->	&
	// OR	->	|
	// 清除中间所有空格

	char Exp[MaxY];
	strcpy(Exp, ExpIn);

	// 在变换连接时使用
	char strLeft[MaxY];
	char strRight[MaxY];

	// 存储单词
	char Word[MaxY];

	// 源表达式字符指针
	int i = 0;

	while (i < strlen(Exp))
	{
		if (!strchr("<>=(), ", Exp[i]))
		{
			// 加入单词

			strcat(Word, " ");
			Word[strlen(Word) - 1] = Exp[i];

			// 指针后移
			i++;
		}
		else if (Word[0] != '\0')
		{
			if (strcmp(Word, "NOT") == 0)
			{
				// 替换NOT

				// 取关键字左边的部分
				GetMid(Exp, 0, i - 4, strLeft);

				// 取关键字右边的部分
				GetMid(Exp, i, strlen(Exp), strRight);

				// 依次连接表达式
				strcat(strLeft, " ! ");
				strcat(strLeft, strRight);

				// 覆盖源表达式
				strcpy(Exp, strLeft);
			}
			else if (strcmp(Word, "AND") == 0)
			{
				// 替换AND

				// 取关键字左边的部分
				GetMid(Exp, 0, i - 4, strLeft);

				// 取关键字右边的部分
				GetMid(Exp, i, strlen(Exp), strRight);

				// 依次连接表达式
				strcat(strLeft, " & ");
				strcat(strLeft, strRight);

				// 覆盖源表达式
				strcpy(Exp, strLeft);
			}
			else if (strcmp(Word, "OR") == 0)
			{
				// 替换OR

				// 取关键字左边的部分
				GetMid(Exp, 0, i - 4, strLeft);

				// 取关键字右边的部分
				GetMid(Exp, i, strlen(Exp), strRight);

				// 依次连接表达式
				strcat(strLeft, " | ");
				strcat(strLeft, strRight);

				// 覆盖源表达式
				strcpy(Exp, strLeft);

				// 因为替换后源表达式变长一位,所以指针后移
				i++;
			}
			else
			{
				// 标识符

				i++;
			}

			// 清空单词
			Word[0] = '\0';
		}
		else
		{
			// 连续的分隔符

			i++;
		}
	}

	// 清除中间的空格
	ClearBlankInside(Exp);

	// 复制给返回字符串
	strcpy(Return, Exp);
}

bool Boolean(const char Exp[MaxY], int &SeatStart)
{
	// 计算布尔表达式

	// 计算AND表达式的值
	int Seat = SeatStart;
	bool Result = AND(Exp, Seat);

	if (Error)
	{
		return false;
	}

	if (Result)
	{
		// 当前为真,则直接返回真

		SeatStart = Seat;
		return true;
	}

	while (Exp[Seat] == '|')
	{
		// 计算下一个AND表达式
		Seat++;
		Result = AND(Exp, Seat);

		if (Error)
		{
			return false;
		}

		if (Result)
		{
			// 结果为真,直接返回真

			SeatStart = Seat;
			return true;
		}
	}

	// 返回假
	SeatStart = Seat;
	return false;
}

bool AND(const char Exp[MaxY], int &SeatStart)
{
	// 计算AND表达式的值

	// 计算OR表达式的值
	int Seat = SeatStart;
	bool Result = OR(Exp, Seat);

	if (Error)
	{
		return false;
	}

	if (!Result)
	{
		// 当前为假,则直接返回假

		SeatStart = Seat;
		return false;
	}

	while (Exp[Seat] == '&')
	{
		// 计算下一个OR表达式的值

		Seat++;
		Result = OR(Exp, Seat);

		if (Error)
		{
			return false;
		}

		if (!Result)
		{
			// 当前为假,则直接返回假

			SeatStart = Seat;
			return false;
		}
	}

	SeatStart = Seat;

	return true;
}

bool OR(const char Exp[MaxY], int &SeatStart)
{
	// 计算OR表达式的值

	int Seat = SeatStart;

	if (Exp[Seat] == '(')
	{
		// 计算新的布尔表达式的值

		Seat++;
		bool Result = Boolean(Exp, Seat);

		if (Error)
		{
			return false;
		}

		SeatStart = Seat;
		return Result;
	}
	else if (Exp[Seat] == '!')
	{
		// 计算NOT

		Seat++;
		bool Result = OR(Exp, Seat);

		SeatStart = Seat;
		return !Result;
	}
	else
	{
		// 取左侧表达式
		char Word[MaxY] = "";
		while (!strchr("<>=&|", Exp[Seat]))
		{
			strcat(Word, " ");
			Word[strlen(Word) - 1] = Exp[Seat];
			Seat++;
		}

		// 计算左侧表达式
		int SeatTemp = 0;
		double Exp1 = Expression(Word, SeatTemp);
		if (Error)
		{
			return false;
		}

		// 取逻辑运算符
		char Operation[3] = "";
		while (strchr("<>=", Exp[Seat]))
		{
			strcat(Operation, " ");
			Operation[strlen(Operation) - 1] = Exp[Seat];
			Seat++;
		}

		if (Operation[0] == '\0')
		{
			// 逻辑运算符为空,直接返回左侧表达式
			// 非零为真,反之为假

			return Exp1 != 0;
		}

		// 取右侧表达式
		Word[0] = '\0';
		while (!strchr("<>!=&|", Exp[Seat]))
		{
			strcat(Word, " ");
			Word[strlen(Word) - 1] = Exp[Seat];
			Seat++;
		}

		// 计算右侧表达式
		SeatTemp = 0;
		double Exp2 = Expression(Word, SeatTemp);
		if (Error)
		{
			return false;
		}

		SeatStart = Seat;

		// 根据运算符,分别判断返回
		if (strcmp(Operation, ">") == 0)
		{
			return Exp1 > Exp2;
		}
		else if (strcmp(Operation, "<") == 0)
		{
			return Exp1 < Exp2;
		}
		else if (strcmp(Operation, "=") == 0)
		{
			return Exp1 == Exp2;
		}
		else if (strcmp(Operation, ">=") == 0)
		{
			return Exp1 >= Exp2;
		}
		else if (strcmp(Operation, "<=") == 0)
		{
			return Exp1 <= Exp2;
		}
		else if (strcmp(Operation, "<>") == 0)
		{
			return Exp1 != Exp2;
		}
	}
}

⌨️ 快捷键说明

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