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

📄 syntax.cpp

📁 c语言写的VB编译器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
////////////////////////////////////////////////
//                                            //
//    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 + -