📄 express.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 + -