📄 syntax.cpp
字号:
////////////////////////////////////////////////
// //
// Syntax.cpp //
// 语法检查模块 //
// 处理整个程序或单个语句语法检查的请求 //
// 最后更新时间:2004年4月23日11:35 //
// //
////////////////////////////////////////////////
#include <string.h>
#include <ctype.h>
#include "Syntax.h"
void CheckSyntax()
{
// 检查程序的语法
// 当前行语句的副本
char Line[MaxY];
for (int i = 0; i <= EndLine; i++)
{
// 得到语句行的副本
strcpy(Line, Text[i]->Line);
// 清除前后空格
ClearHeadBlank(Line);
ClearTailBlank(Line);
// 检查该行
Error = CheckLine(Line);
if (Error != NoError)
{
// 发现语法错误
// 显示语法错误
ShowError(Error, i, "");
return;
}
}
}
ErrorType CheckLine(const char strLineIn[MaxY])
{
char strLine[MaxY];
strcpy(strLine, strLineIn);
ClearHeadBlank(strLine);
ClearTailBlank(strLine);
if (strLine[0] == '\0')
{
// 空行
// 返回无错误
return NoError;
}
// 存储首字符串
char Cmd[MaxY];
// 得到首字符串
GetPart(strLine, 1, ' ', Cmd);
if (strcmp(Cmd, "REM") == 0)
{
// 注释行,跳过语法检查
}
else if (strcmp(Cmd, "CLS") == 0
|| strcmp(Cmd, "CONTINUE") == 0
|| strcmp(Cmd, "BREAK") == 0
|| strcmp(Cmd, "EXIT") == 0
|| strcmp(Cmd, "ELSE") == 0)
{
// 单命令语句
// 得到其尾字符串
char Tail[MaxY];
GetPart(strLine,2,' ', Tail);
if (Tail[0] != '\0')
{
// 有尾巴
// 有多余部分
return ErrorUnwantedPart;
}
}
else if (strcmp(Cmd, "DIM") == 0)
{
// DIM语句
// 得到变量名
char Var[MaxY];
GetPart(strLine, 2, ' ', Var);
if (Var[0] == '\0')
{
return ErrorMissingVar;
}
if (!VarOK(Var))
{
// 变量名错误
return Error;
}
// 检查AS关键字
char Part[MaxY];
GetPart(strLine, 3, ' ', Part);
if (strcmp(Part, "AS") != 0)
{
// 缺少AS
return ErrorMissingAS;
}
// 检查类型描述
char Type[MaxY];
GetPart(strLine, 4, ' ', Type);
if (strcmp(Type, "INTEGER") != 0
&& strcmp(Type, "REAL") != 0
&& strcmp(Type, "STRING") != 0
&& strcmp(Type, "ARRAY") != 0)
{
// 未知类型
return ErrorMissingVarType;
}
// 得到尾部
char Tail[MaxY];
GetBack(strLine, 4, ' ', Tail);
if (Tail[strlen(Tail) - 1] == ',')
{
// 尾部有多余逗号
return ErrorUnwantedComma;
}
if (strcmp(Type, "ARRAY") == 0)
{
// 是数组类型
if (Tail[0] != '\0')
{
// 检查每一维是否合法
char Range[MaxY];
strcat(Tail, ",");
GetPart(Tail, 1, ',', Range);
ClearHeadBlank(Range);
int i = 1;
while (Range[0] != '\0')
{
if (!ExpressionOK(Range))
{
// 关于维数的表达式错误
return ErrorExpression;
}
i++;
GetPart(Tail, i, ',', Range);
ClearHeadBlank(Range);
}
}
else
{
// 缺少数组的具体大小
return ErrorMissingArraySize;
}
}
else if ( Tail[0] != '\0')
{
// 有尾巴
return ErrorUnwantedPart;
}
}
else if (strcmp(Cmd, "INPUT") == 0)
{
// 检查INPUT语句
// 存储变量
char Var[MaxY];
GetBack(strLine, 1, ' ', Var);
ClearBlankInside(Var);
if (!VarOK(Var))
{
return Error;
}
}
else if (strcmp(Cmd, "PRINT") == 0)
{
// 检查PRINT语句
// 存储打印序列
char PrintList[MaxY];
GetBack(strLine, 1, ' ', PrintList);
char Part[MaxY] = "";
for (int i = 0; i <= strlen(PrintList); i++)
{
// 扫描打印序列
if (PrintList[i] == ';' || i == strlen(PrintList))
{
// 一个打印元素扫描完成
if (Part[0] != '\0')
{
if (!ExpressionOK(Part))
{
return ErrorExpression;
}
Part[0] = '\0';
}
}
else if (PrintList[i] == '"')
{
// 字符串的开始
// 找字符串的末尾
do
{
i++;
} while (i < strlen(PrintList) && PrintList[i] != '"');
if (i == strlen(PrintList))
{
// 字符串缺少结束引号
return ErrorQuotation;
}
do
{
i++;
if (i < strlen(PrintList) &&
PrintList[i] != ' ' && PrintList[i] != ';')
{
return ErrorPrintSeparate;
}
} while (i < strlen(PrintList) && PrintList[i] != ';');
i++;
}
else if (PrintList[i] != ' ')
{
// 当前字符非空,加如打印元素
strcat(Part, " ");
Part[strlen(Part) - 1] = PrintList[i];
}
}
}
else if (strcmp(Cmd, "GOSUB") == 0 || strcmp(Cmd, "SUB") == 0)
{
// 检查GOSUB和SUB语句
// 存储过程名
char Var[MaxY];
GetPart(strLine, 2, ' ', Var);
if (!VarOK(Var))
{
// 过程名非法
return ErrorSubName;
}
// 检查尾部部分
char Tail[MaxY];
GetPart(strLine, 3, ' ', Tail);
if (Tail [0] != '\0')
{
// 有多余部分
return ErrorUnwantedPart;
}
}
else if (strcmp(Cmd, "FOR") == 0)
{
// 检查FOR语句
// 当前行的长度
int Len = strlen(strLine);
// 分段部分的参数
char *ptr1;
if ((ptr1 = strstr(strLine, " = ")) == NULL)
{
// FOR语句缺少变量赋值
return ErrorMissingForVarGiveValue;
}
char *ptr2;
if ((ptr2 = strstr(strLine, " TO ")) == NULL)
{
// FOR语句缺少TO
return ErrorMissingTO;
}
char *ptr3;
ptr3 = strstr(strLine, " STEP ");
char strTemp[MaxY];
// 检查循环变量
GetMid(strLine, 4, Len - strlen(ptr1) - 1, strTemp);
ClearBlankInside(strTemp);
if (!VarOK(strTemp))
{
// 循环变量错误
return Error;
}
// 检查初值部分表达式
GetMid(strLine, Len - strlen(ptr1) + 3, Len - strlen(ptr2) - 1, strTemp);
ClearBlankInside(strTemp);
if (!ExpressionOK(strTemp))
{
// 表达式错误
return ErrorExpression;
}
// 检查终值部分表达式
if (ptr3 == NULL)
{
GetMid(strLine, Len - strlen(ptr2) + 4, Len, strTemp);
}
else
{
GetMid(strLine, Len - strlen(ptr2) + 4, Len - strlen(ptr3) - 1, strTemp);
}
ClearBlankInside(strTemp);
if (!ExpressionOK(strTemp))
{
// 表达式错误
return ErrorExpression;
}
// 检查步长值部分表达式
if (ptr3 != NULL)
{
GetMid(strLine, Len - strlen(ptr3) + 6, Len, strTemp);
ClearBlankInside(strTemp);
if (!ExpressionOK(strTemp))
{
// 表达式错误
return ErrorExpression;
}
}
}
else if (strcmp(Cmd, "NEXT") == 0)
{
// 检查NEXT语句
// 存储变量名
char Var[MaxY];
GetPart(strLine, 2, ' ', Var);
if (Var[0] != '\0')
{
if (!VarOK(Var))
{
// 变量错误
return Error;
}
}
}
else if (strcmp(Cmd, "IF") == 0)
{
// 检查IF语句
// 检查末尾关键字THEN
char Part[MaxY];
GetMid(strLine, strlen(strLine) - 4, strlen(strLine) - 1, Part);
if (strcmp(Part, "THEN") != 0)
{
// 缺少THEN
return ErrorUnwantedPart;
}
// 检查布尔表达式
GetMid(strLine, 3, strlen(strLine) - 6, Part);
char Exp[MaxY];
BoolChange(Part, Exp);
if (!BooleanOK(Exp))
{
// 布尔表达式错误
return ErrorBool;
}
}
else if (strcmp(Cmd, "DELAY") == 0)
{
// 检查DELAY语句
// 检查表达式
char Part[MaxY];
GetPart(strLine, 2, ' ', Part);
ClearBlankInside(Part);
if (!ExpressionOK(Part))
{
// 表达式错误
return ErrorExpression;
}
}
else if (strcmp(Cmd, "LOCATE") == 0)
{
// 检查LOCATE语句
// 存储参数部分
char Temp[MaxY] = "";
GetBack(strLine, 1, ' ', Temp);
char Part[MaxY];
// 检查2个参数
for (int i = 1; i <= 2; i++)
{
GetPart(Temp, i, ',', Part);
ClearBlankInside(Part);
if (Part[0] == '\0')
{
return ErrorMissingExpression;
}
if (!ExpressionOK(Part))
{
// 表达式错误
return ErrorExpression;
}
}
}
else if (strcmp(Cmd, "END") == 0)
{
// 检查END语句
// 检查后面的关键字
char Part[MaxY];
GetPart(strLine, 2, ' ', Part);
if (Part[0] != '\0' && strcmp(Part, "IF") != 0 && strcmp(Part, "SUB") != 0)
{
// 不为空,且不是IF和SUB,错误
return ErrorUnwantedPart;
}
}
else if (strcmp(Cmd, "DELETE") == 0)
{
// 检查DELETE语句
// 存储变量列表
char VarList[MaxY];
GetBack(strLine, 1, ' ', VarList);
ClearBlankInside(VarList);
if (VarList[strlen(VarList) - 1] == ',')
{
// 列表后有多余的逗号
return ErrorUnwantedComma;
}
int i = 1;
// 存储变量名
char Var[MaxY];
GetPart(VarList, 1, ',', Var);
while (Var[0] != '\0')
{
if (strchr(Var, '('))
{
return ErrorCannotDelArray;
}
else if (!VarOK(Var))
{
// 变量名错误
return ErrorVar;
}
// 得到下一个变量名
i++;
GetPart(VarList, i, ',', Var);
}
if (i == 1)
{
// 需要变量名
return ErrorMissingVar;
}
}
else
{
// 检查赋值语句
char *ptr = strstr(strLine, " = ");
if (ptr != NULL)
{
// 有赋值号
// 存储赋值号的开始位置
int Pos = strlen(strLine) - strlen(ptr);
// 存储变量
char Var[MaxY];
GetMid(strLine, 0, Pos - 1, Var);
if (strchr(Var, '('))
{
// 是数组变量
// 存储下标部分
char Para[MaxY];
GetPart(Var, 2, '(', Para);
Para[strlen(Para) - 1] = '\0';
ClearTailBlank(Para);
if (Para[strlen(Para) - 1] == ',')
{
// 有多余的逗号
return ErrorUnwantedComma;
}
// 检查数组的每一个下标
char Range[MaxY];
strcat(Para, ",");
GetPart(Para, 1, ',', Range);
ClearBlankInside(Range);
int i = 1;
while (Range[0] != '\0')
{
if (!ExpressionOK(Range))
{
// 表达式错误
return ErrorExpression;
}
// 得到下一个下标
i++;
GetPart(Para, i, ',', Range);
ClearBlankInside(Range);
}
if (i == 1)
{
// 缺少下标
return ErrorMissingSubscript;
}
}
else if (!VarOK(Var))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -