?? 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 + -