📄 syntax.cpp
字号:
{
// 变量错误
return Error;
}
// 检查赋值号右侧表达式
char Exp[MaxY];
GetMid(strLine, Pos + 2, strlen(strLine) - 1, Exp);
ClearBlankInside(Exp);
if (!ExpressionOK(Exp))
{
// 表达式错误
return ErrorExpression;
}
}
else
{
// 未知语句类型
return ErrorSyntax;
}
}
// 返回无错误
return NoError;
}
bool VarOK(const char Var[MaxY])
{
// 检查变量名
if (strchr(Var, '('))
{
// 当前字符串是数组
// 取数组名
char VarMain[MaxY];
GetPart(Var, 1, '(', VarMain);
if (!VarOK(VarMain))
{
// 数组名非法
Error = ErrorVar;
return false;
}
// 取数组下标
GetPart(Var, 2, '(', VarMain);
VarMain[strlen(VarMain) - 1] = '\0';
if (VarMain[strlen(VarMain) - 1] == ',')
{
// 有多余的逗号
Error = ErrorUnwantedComma;
return false;
}
// 存储各下标字符串
char Range[MaxY];
// 取第一个下标字符串
int i = 1;
GetPart(VarMain, i, ',', Range);
ClearBlankInside(Range);
while (Range[0] != '\0')
{
if (!ExpressionOK(Range))
{
// 下标表达式出错
Error = ErrorExpression;
return false;
}
// 取下一个下标
i++;
GetPart(VarMain, i, ',', Range);
ClearBlankInside(Range);
}
if (i == 1)
{
// 缺少下标
Error = ErrorMissingRange;
return false;
}
return true;
}
if (Var[0] == '\0')
{
// 变量为空
Error = ErrorMissingVar;
return false;
}
else if (strlen(Var) <= MaxLenOfVar)
{
// 长度小于最大允许长度
if (isalpha(Var[0]))
{
for(int i = 1; i < strlen(Var); i++)
{
if (!isdigit(Var[i]) && !isalpha(Var[i]) && Var[i] != '_')
{
// 非字母,非数字,非下划线
Error = ErrorVar;
return false;
}
}
// 正确
return true;
}
else
{
// 首字符必须是字母
Error = ErrorVar;
return false;
}
}
else
{
// 超过允许长度
Error = ErrorVar;
return false;
}
}
bool BooleanOK(const char Exp[MaxY])
{
// 检查布尔表达式是否正确,供外部调用
int Seat = 0;
bool Result = BoolOK(Exp, Seat);
return Result && Seat >= strlen(Exp);
}
bool BoolOK(const char Exp[MaxY], int &Seat)
{
// 检查布尔表达式是否正确,内部使用
// 测试OR表达式
if (!OROK(Exp, Seat))
{
// 第一个OR表达式出错,返回
return false;
}
while (Exp[Seat] == '|')
{
// 继续检查后面的
Seat++;
if (!OROK(Exp, Seat))
{
// 表达式错误,返回
return false;
}
}
// 正确,返回
return true;
}
bool OROK(const char Exp[MaxY], int &Seat)
{
// 检查OR表达式是否正确
// 检查第一个AND表达式
if (!ANDOK(Exp, Seat))
{
// 表达式错误,返回
return false;
}
while (Exp[Seat] == '&')
{
// 继续检查后面的
Seat++;
if (!ANDOK(Exp, Seat))
{
return false;
}
}
// 正确,返回
return true;
}
bool ANDOK(const char Exp[MaxY], int &Seat)
{
// 检查AND表达式是否正确
if (Exp[Seat] == '(')
{
// 一个新的布尔表达式开始
Seat++;
if (!BoolOK(Exp, Seat))
{
// 表达式错误
return false;
}
if (Exp[Seat] != ')')
{
// 缺少括号匹配
return false;
}
// 正确,返回
return true;
}
else if (Exp[Seat] == '~')
{
// 检查非表达式
Seat++;
if (!ANDOK(Exp, Seat))
{
// 表达式错误,返回
return false;
}
// 正确,返回
return true;
}
else
{
// 检查元表达式
// 取左侧表达式
char Word[MaxY] = "";
while (!strchr("<>!=&|", Exp[Seat]))
{
strcat(Word, " ");
Word[strlen(Word) - 1] = Exp[Seat];
Seat++;
}
if (!ExpressionOK(Word))
{
// 左侧表达式错误
return false;
}
// 取逻辑运算符
char Operation[3] = "";
while (Seat < strlen(Exp) && strchr("<>!=", Exp[Seat]))
{
strcat(Operation, " ");
Operation[strlen(Operation) - 1] = Exp[Seat];
Seat++;
}
if (Operation[0] == '\0')
{
// 无运算符,正确返回
return true;
}
// 取右侧表达式
Word[0] = '\0';
while (!strchr("<>!=&|", Exp[Seat]))
{
strcat(Word, " ");
Word[strlen(Word) - 1] = Exp[Seat];
Seat++;
}
if (!ExpressionOK(Word))
{
// 右侧表达式错误
return false;
}
if (strcmp(Operation, ">") != 0 &&
strcmp(Operation, "<") != 0 &&
strcmp(Operation, "=") != 0 &&
strcmp(Operation, ">=") != 0 &&
strcmp(Operation, "<=") != 0 &&
strcmp(Operation, "<>") != 0)
{
// 操作符错误
return false;
}
// 正确,返回
return true;
}
}
bool FactorOK(const char strExp[MaxY], int &Seat)
{
// 计算因式的值
if (strExp[Seat] == '(')
{
// 因式中含有括号,开始表达式处理
// 越过左括号位
Seat++;
// 返回表达式的值
if (!ExpressOK(strExp, Seat))
{
return false;
}
if (Seat >= strlen(strExp) || strExp[Seat] != ')')
{
return false;
}
// 越过右括号位
Seat++;
// 返回因式的值
return true;
}
else if (strExp[Seat] == '+' || strExp[Seat] == '-')
{
// 是负号
if (Seat > 0 && (strchr("+-", strExp[Seat - 1])))
{
return false;
}
// 越过负号位
Seat++;
// 返回因式的相反数
bool OK = FactorOK(strExp, Seat);
return OK;
}
else
{
// 处理普通因式
int i = Seat;
char Chr = strExp[i];
while (i < strlen(strExp) && (isalpha(Chr) || isdigit(Chr) || Chr == '.'))
{
// 是字母、数字或小数点
i++;
Chr = strExp[i];
}
// 取变量或数字
char strTemp[MaxY] = "";
GetMid(strExp, Seat, i - 1, strTemp);
Seat = i;
if (strTemp[0] == '\0')
{
// 表达式错误
return false;
}
double Temp;
if (strcmp(strTemp, "RND") == 0 ||
strcmp(strTemp, "INT") == 0 ||
strcmp(strTemp, "SQR") == 0)
{
// 是RND、INT或SQR
// 取参数
char strPara[MaxY];
int End;
if (!GetParaStr(strExp, Seat, strPara, End))
{
// 缺少参数
return false;
}
Seat = End;
// 检查参数表达式
ClearBlankInside(strPara);
return ExpressionOK(strPara);
}
else if (strcmp(strTemp, "PI") == 0)
{
// 正确,返回
return true;
}
else if (IsNumber(strTemp, Temp))
{
// 正确,返回
return true;
}
else if (strExp[Seat] != '(')
{
// 简单变量
return VarOK(strTemp);
}
else if (strExp[Seat] == '(')
{
// 数组变量
// 取下标字符串
char strPara[MaxY];
int New;
if (!GetParaStr(strExp, Seat, strPara, New))
{
// 下标字符串错误
return false;
}
Seat = New;
if (strPara[strlen(strPara) - 1] == ',')
{
// 多余逗号
return false;
}
// 末尾添加逗号,方便分离各下标
strcat(strPara, ",");
// 存储各下标表达式
char strExp[MaxY];
// 取第一个下标
int i = 1;
GetPart(strPara, 1, ',', strExp);
ClearBlankInside(strExp);
while (strExp[0] != '\0')
{
if (!ExpressionOK(strExp))
{
// 下标表达式错误
return false;
}
// 取下一个下标
i++;
GetPart(strPara, i, ',', strExp);
ClearBlankInside(strExp);
}
// 正确,返回
return true;
}
}
return true;
}
bool TermOK(const char strExp[MaxY], int &Seat)
{
// 计算项的值
if (!FactorOK(strExp, Seat))
{
// 有错误,返回
return false;
}
bool OK;
while (Seat < strlen(strExp) &&
(strExp[Seat] == '*' || strExp[Seat] == '/' || strExp[Seat] == '%'))
{
// 还有因式需要计算
Seat++;
switch (strExp[Seat - 1])
{
case '*':
case '/':
case '%':
// 符号正确
OK = FactorOK(strExp, Seat);
break;
default:
return false;
}
if (!OK)
{
return false;
}
}
// 返回项的值
return true;
}
bool ExpressOK(const char strExp[MaxY], int &Seat)
{
// 计算表达式的值
if (!TermOK(strExp, Seat))
{
// 有错误,返回
return false;
}
bool OK;
while (Seat < strlen(strExp) &&
(strExp[Seat] == '+' || strExp[Seat] == '-'))
{
// 还有项需要计算
Seat++;
switch (strExp[Seat - 1])
{
case '+':
case '-':
// 减号
OK = TermOK(strExp, Seat);
break;
default:
return false;
}
if (!OK)
{
return false;
}
}
// 返回表达式的值
return true;
}
bool ExpressionOK(const char strExp[MaxY])
{
// 检查表达式是否正确,外部调用
int SeatOut = 0;
bool OK = ExpressOK(strExp, SeatOut);
return OK && SeatOut >= strlen(strExp);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -