SNL文法的递归下降语法分析器

得到token序列后,我们就可以采用递归下降法对其进行语法分析。如果没有语法错误,打印token序列,提示没有语法错误,否则,打印已经匹配的token,提示语法错误。(下面程序使用vs2013编译)


#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

//token结构体
struct Token
{
	Token(string str, int pos)
	{
		this->type = str;
		this->pos = pos;
	}
	string type;
	int pos;
};

vector<string> IdTable;//全局变量,标示符表
vector<int> NbTable;//全局变量,INTC值表
FILE *g_pf;//全局变量,打开*.token的文件指针
FILE *g_pf_log;//全局变量,日志文件*.log的文件指针

vector<string> result;//记录匹配成功的token
int max_read_num = 0;//最大匹配token数量

//从文件中读入一个token,需要先打开*.token文件
Token *ReadToken(FILE *pf)
{
	if (pf == NULL)
		exit(-1);
	char buf1[256] = { 0 };
	char buf2[256] = { 0 };
	int num = 0;
	if (!pf)
		return NULL;
	while (!feof(pf))
	{
		memset(buf1, 0, sizeof(buf1));
		memset(buf2, 0, sizeof(buf2));

		fgets(buf1, sizeof(buf1), pf);
		result.push_back(buf1);

		if (result.size() > max_read_num)//记录读入token数量最大值
			max_read_num = result.size();

		if (g_pf_log)
			fprintf(g_pf_log,"读入%s\n", buf1);
		sscanf(buf1, "(%[^,],%[^)]", buf1, buf2);

		if (buf2[0] == '"')
		{
			return new Token(buf1, -1);
		}
		else if (buf2[0] == '[')
		{
			sscanf(buf2, "[%[0-9]", buf2);
			num = atoi(buf2);
			return new Token(buf1, num);
		}
		else
		{
			return NULL;
		}
	}
	return NULL;
}
//从文件流中回退一个token,需要先打开*.token文件
void BackToken(FILE*pf)
{
	if (pf == NULL)
		exit(-1);
	string tmp = result[result.size() - 1];
	int i = tmp.size();
	while (i)
	{
		 ungetc(tmp[--i], pf);
	}
	if (g_pf_log)
		fprintf(g_pf_log, "返回%s\n", result[result.size() - 1].c_str());
	result.erase(result.end() - 1);
}

//总程序
bool MatchProgramHead();
bool MatchDeclarePart();
bool MatchProgramBody();
bool MatchProgramName();
bool MatchTypeDecpart();
bool MatchVarDecpart();
bool MatchProcDecpart();
bool MatchTypeDec();
bool MatchTypeDecList();
bool MatchTypeDecMore();
bool MatchTypeId();
bool MatchTypeName();
bool MatchBaseName();
bool MatchStructureType();
bool MatchArrayType();
bool MatchLow();
bool MatchTop();
bool MatchRecType();
bool MatchFieldDecList();
bool MatchFieldDecMore();
bool MatchIdList();
bool MatchIdMore();
//变量声明
bool MatchVarDecpart();
bool MatchVarDec();
bool MatchVarDecList();
bool MatchVarDecMore();
bool MatchVarIdList();
bool MatchVarIdMore();
//过程声明
bool MatchProcDecpart();
bool MatchProcDec();
bool MatchProcDecMore();
bool MatchProcName();
//参数声明
bool MatchParamList();
bool MatchParamDecList();
bool MatchParamMore();
bool MatchParam();
bool MatchFormList();
bool MatchFidMore();
//过程中的声明
bool MatchProcDecPart();
//过程体
bool MatchProcBody();
bool MatchProgramBody();
//语句序列
bool MatchStmList();
bool MatchStmMore();
//语句
bool MatchStm();
bool MatchAssCall();
bool MatchAssignmentRest();
bool MatchConditionalStm();
bool MatchLoopStm();
bool MatchInputStm();
bool MatchInvar();
bool MatchOutputStm();
bool MatchReturnStm();
bool MatchCallStmRest();
bool MatchActParamList();
bool MatchActParamMore();
bool MatchRelExp();
bool MatchOtherRelE();
bool MatchExp();
bool MatchOtherTerm();
bool MatchTerm();
bool MatchOtherFactor();
bool MatchFactor();
bool MatchVariable();
bool MatchVariMore();
bool MatchFieldVar();
bool MatchFieldVarMore();
bool MatchCmpOp();
bool MatchAddOp();
bool MatchMultOp();


bool MatchProgram()
{
	if (!MatchProgramHead())
		return false;
	if (!MatchDeclarePart())
		return false;
	if (!MatchProgramBody())
		return false;
	if (ReadToken(g_pf)->type != "$.")
	{
		BackToken(g_pf);
		return false;
	}
	return true;
}
bool MatchProgramHead()
{
	if (ReadToken(g_pf)->type == "$program")
		return MatchProgramName();
	return false;
}
bool MatchProgramName()
{
	if (ReadToken(g_pf)->type == "$id")
		return true;
	return false;
}
bool MatchDeclarePart()
{
	if (!MatchTypeDecpart())
		return false;
	if (!MatchVarDecpart())
		return false;
	if (!MatchProcDecpart())
		return false;
	return true;
}

bool MatchTypeDecpart()
{
	MatchTypeDec();
	return true;
}
bool MatchTypeDec()
{
	if (ReadToken(g_pf)->type != "$type")
	{
		BackToken(g_pf);
		return false;
	}
	else
	{
		if (!MatchTypeDecList())
		{
			BackToken(g_pf);
			return false;
		}
		else
		{
			return true;
		}
	}
}
bool MatchTypeDecList()
{
	if (!MatchTypeId())
		return false;
	if (ReadToken(g_pf)->type != "$=")
	{
		BackToken(g_pf);
		return false;
	}
	if (!MatchTypeName())
	{
		BackToken(g_pf);
		return false;
	}
	if (ReadToken(g_pf)->type != "$;")
	{
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	return MatchTypeDecMore();
}
bool MatchTypeDecMore()
{
	MatchTypeDecList();
	return true;
}
bool MatchTypeId()
{
	if (ReadToken(g_pf)->type == "$id")
		return true;
	else
	{
		BackToken(g_pf);
		return false;
	}
}
bool MatchTypeName()
{
	if (MatchBaseName())
		return true;
	if (MatchStructureType())
		return true;
	if (ReadToken(g_pf)->type == "$id")
		return true;
	else
	{
		BackToken(g_pf);
		return false;
	}
	return false;
}
bool MatchBaseName()
{
	if (ReadToken(g_pf)->type == "$integer")
		return true;
	else
	{	
		BackToken(g_pf);
	}
	if (ReadToken(g_pf)->type == "$char")
		return true;
	else
	{
		BackToken(g_pf);
	}
	return false;
}
bool MatchStructureType()
{
	if (MatchArrayType())
		return true;
	if (MatchRecType())
		return true;
	return false;
}
bool MatchArrayType()
{
	if (ReadToken(g_pf)->type != "$array")
	{
		BackToken(g_pf);
		return false;
	}
	if (ReadToken(g_pf)->type != "$[")
	{
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	if (!MatchLow())
	{
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	if (ReadToken(g_pf)->type != "$.")
	{
		BackToken(g_pf);
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	if (ReadToken(g_pf)->type != "$.")
	{
		BackToken(g_pf);
		BackToken(g_pf);
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	if (!MatchTop())
	{
		BackToken(g_pf);
		BackToken(g_pf);
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	if (ReadToken(g_pf)->type != "$]")
	{
		BackToken(g_pf);
		BackToken(g_pf);
		BackToken(g_pf);
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	if (ReadToken(g_pf)->type != "$of")
	{
		BackToken(g_pf);
		BackToken(g_pf);
		BackToken(g_pf);
		BackToken(g_pf);
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	return MatchBaseName();
}
bool MatchLow()
{
	if (ReadToken(g_pf)->type != "$INTC")
	{
		BackToken(g_pf);
		return false;
	}
	return true;
}
bool MatchTop()
{
	if (ReadToken(g_pf)->type != "$INTC")
	{
		BackToken(g_pf);
		return false;
	}
	return true;
}
bool MatchRecType()
{
	if (ReadToken(g_pf)->type != "$record")
	{
		BackToken(g_pf);
		return false;
	}
	if (!MatchFieldDecList())
	{
		BackToken(g_pf);
		return false;
	}
	if (ReadToken(g_pf)->type != "$end")
	{
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	return true;
}
bool MatchFieldDecList()
{
	if (MatchBaseName())
		if (MatchIdList())
			if (ReadToken(g_pf)->type == "$;")
			{
				if (MatchFieldDecMore())
					return true;
			}
			else
			{
				BackToken(g_pf);
			}
	if (MatchArrayType())
		if (MatchIdList())
			if (ReadToken(g_pf)->type == "$;")
			{
				if (MatchFieldDecMore())
					return true;
			}
			else
			{
				BackToken(g_pf);
			}
	return false;
}
bool MatchFieldDecMore()
{
	MatchFieldDecList();
	return true;
}
bool MatchIdList()
{
	if (ReadToken(g_pf)->type != "$id")
	{
		BackToken(g_pf);
		return false;
	}		
	return MatchIdMore();
}
bool MatchIdMore()
{
	if (ReadToken(g_pf)->type == "$comma")
		if (MatchIdList())
		{
			return true;
		}
		else
		{
			BackToken(g_pf);
		}
	return true;
}

bool MatchVarDecpart()
{
	MatchVarDec();
	return true;
}
bool MatchVarDec()
{
	if (ReadToken(g_pf)->type != "$var")
	{
		BackToken(g_pf);
		return false;
	}
	if (MatchVarDecList())
		return true;
	else
	{
		BackToken(g_pf);
		return false;
	}
}
bool MatchVarDecList()
{
	if (!MatchTypeName())
		return false;
	if (!MatchVarIdList())
		return false;
	if (ReadToken(g_pf)->type != "$;")
	{
		BackToken(g_pf);
		return false;
	}
	if (!MatchVarDecMore())
		return false;
	return true;
}
bool MatchVarDecMore()
{
	MatchVarDecList();
	return true;
}
bool MatchVarIdList()
{
	if (ReadToken(g_pf)->type != "$id")
	{
		BackToken(g_pf);
		return false;
	}
	if (!MatchVarIdMore())
		return false;
	return true;
}
bool MatchVarIdMore()
{
	if (ReadToken(g_pf)->type == "$comma")
	{
		if (MatchVarIdList())
		{
			return true;
		}
		else
		{
			BackToken(g_pf);
		}
	}
	else
	{
		BackToken(g_pf);
	}
	
	return true;
}

//过程声明
bool MatchProcDecpart()
{
	MatchProcDec();
	return true;
}
bool MatchProcDec()
{
	if (ReadToken(g_pf)->type != "$procedure")
	{
		BackToken(g_pf);
		return false;
	}
	if (!MatchProcName())
	{
		BackToken(g_pf);
		return false;
	}
	if (ReadToken(g_pf)->type != "$(")
	{
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	if (!MatchParamList())
	{
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	if (ReadToken(g_pf)->type != "$)")
	{
		BackToken(g_pf);
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	if (ReadToken(g_pf)->type != "$;")
	{
		BackToken(g_pf);
		BackToken(g_pf);
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	if (!MatchProcDecPart())
	{
		BackToken(g_pf);
		return false;
	}
	if (!MatchProcBody())
	{
		BackToken(g_pf);
		return false;
	}
	if (!MatchProcDecMore())
	{
		BackToken(g_pf);
		return false;
	}
	return true;
}
bool MatchProcDecMore()
{
	MatchProcDec();
	return true;
}
bool MatchProcName()
{
	if (ReadToken(g_pf)->type != "$id")
	{
		BackToken(g_pf);
		return false;
	}
	return true;
}
//参数声明
bool MatchParamList()
{
	MatchParamDecList();
	return true;
}
bool MatchParamDecList()
{
	if (!MatchParam())
		return false;
	if (!MatchParamMore())
		return false;
	return true;
}
bool MatchParamMore()
{
	if (ReadToken(g_pf)->type == "$;")
	{
		if (MatchParamDecList())
			return true;
		else
			BackToken(g_pf);
	}
	else
	{
		BackToken(g_pf);
	}
	return true;
}
bool MatchParam()
{
	if (MatchTypeName())
		return MatchFormList();
	if (ReadToken(g_pf)->type == "$var")
	{
		if (MatchTypeName())
		{
			if (MatchFormList())
				return true;
			else
				BackToken(g_pf);
		}
		else
		{
			BackToken(g_pf);
		}
	}
	else
	{
		BackToken(g_pf);
	}
	return false;
}
bool MatchFormList()
{
	if (ReadToken(g_pf)->type != "$id")
	{
		BackToken(g_pf);
		return false;
	}
	if(!MatchFidMore())
	{
		BackToken(g_pf);
		return false;
	}
	else
		return true;
}
bool MatchFidMore()
{
	if (ReadToken(g_pf)->type == "$comma")
	{
		if (MatchFormList())
			return true;
		else
			BackToken(g_pf);
	}
	else
	{
		BackToken(g_pf);
	}
	return true;
}
//过程中的声明
bool MatchProcDecPart()
{
	return MatchDeclarePart();
}
//过程体
bool MatchProcBody()
{
	return MatchProgramBody();
}
bool MatchProgramBody()
{
	if (ReadToken(g_pf)->type != "$begin")
	{
		BackToken(g_pf);
		return false;
	}
	if (!MatchStmList())
	{
		BackToken(g_pf);
		return false;
	}
	if (ReadToken(g_pf)->type != "$end")
	{
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	return true;
}
//语句序列
bool MatchStmList()
{
	if (!MatchStm())
		return false;
	if (!MatchStmMore())
		return false;
	return true;
}
bool MatchStmMore()
{
	if (ReadToken(g_pf)->type == "$;")
	{
		if (MatchStmList())
			return true;
		else
		{
			BackToken(g_pf);
			return false;
		}
	}
	else
		BackToken(g_pf);
	return true;
}
//语句
bool MatchStm()
{
	if (MatchConditionalStm())
		return true;
	if (MatchLoopStm())
		return true;
	if (MatchInputStm())
		return true;
	if (MatchOutputStm())
		return true;
	if (MatchReturnStm())
		return true;
	if (ReadToken(g_pf)->type == "$id")
		if (MatchAssCall())
			return true;
		else
			BackToken(g_pf);
	else
		BackToken(g_pf);
	return false;
}
bool MatchAssCall()
{
	if (MatchAssignmentRest())
		return true;
	if (MatchCallStmRest())
		return true;
	return false;
}
bool MatchAssignmentRest()
{
	if (!MatchVariMore())
		return false;
	if (ReadToken(g_pf)->type == "$:=")
	{
		if (!MatchExp())
		{
			BackToken(g_pf);
			return false;
		}
		else
		{
			return true;
		}
	}
	else
	{
		BackToken(g_pf);
		return false;
	}	
}
bool MatchConditionalStm()
{
	if (ReadToken(g_pf)->type != "$if")
	{
		BackToken(g_pf);
		return false;
	}
	if (!MatchRelExp())
	{
		BackToken(g_pf);
		return false;
	}
	if (ReadToken(g_pf)->type != "$then")
	{
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	if (!MatchStmList())
	{
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	if (ReadToken(g_pf)->type != "$else")
	{
		BackToken(g_pf);
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	if (!MatchStmList())
	{
		BackToken(g_pf);
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	if (ReadToken(g_pf)->type != "$fi")
	{
		BackToken(g_pf);
		BackToken(g_pf);
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	return true;
}
bool MatchLoopStm()
{
	if (ReadToken(g_pf)->type != "$while")
	{
		BackToken(g_pf);
		return false;
	}
	if (!MatchRelExp())
	{
		BackToken(g_pf);
		return false;
	}
	if (ReadToken(g_pf)->type != "$do")
	{
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	if (!MatchStmList())
	{
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	if (ReadToken(g_pf)->type != "$endwh")
	{
		BackToken(g_pf);
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	return true;
}
bool MatchInputStm()
{
	if (ReadToken(g_pf)->type != "$read")
	{
		BackToken(g_pf);
		return false;
	}
	if (ReadToken(g_pf)->type != "$(")
	{
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	if (!MatchInvar())
	{
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	if (ReadToken(g_pf)->type != "$)")
	{
		BackToken(g_pf);
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	return true;
}
bool MatchInvar()
{
	if (ReadToken(g_pf)->type != "$id")
	{
		BackToken(g_pf);
		return false;
	}
	return true;
}
bool MatchOutputStm()
{
	if (ReadToken(g_pf)->type != "$write")
	{
		BackToken(g_pf);
		return false;
	}
	if (ReadToken(g_pf)->type != "$(")
	{
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	if (!MatchExp())
	{
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	if (ReadToken(g_pf)->type != "$)")
	{
		BackToken(g_pf);
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	return true;
}
bool MatchReturnStm()
{
	if (ReadToken(g_pf)->type != "$return")
	{
		BackToken(g_pf);
		return false;
	}
	if (ReadToken(g_pf)->type != "$(")
	{
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	if (!MatchExp())
	{
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	if (ReadToken(g_pf)->type != "$)")
	{
		BackToken(g_pf);
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	return true;
}
bool MatchCallStmRest()
{
	if (ReadToken(g_pf)->type != "$(")
	{
		BackToken(g_pf);
		return false;
	}
	if (!MatchActParamList())
	{
		BackToken(g_pf);
		return false;
	}
	if (ReadToken(g_pf)->type != "$)")
	{
		BackToken(g_pf);
		BackToken(g_pf);
		return false;
	}
	return true;
}
bool MatchActParamList()
{
	if (!MatchExp())
		return MatchActParamMore();
	return true;
}
bool MatchActParamMore()
{
	if (ReadToken(g_pf)->type == "$;")
	{
		if (MatchActParamList())
			return true;
		else
		{
			BackToken(g_pf);
			return false;
		}
	}
	else
		BackToken(g_pf);
	return true;
}
bool MatchRelExp()
{
	if (!MatchExp())
		return false;
	if (!MatchOtherRelE())
		return false;
	return true;
}
bool MatchOtherRelE()
{
	if (!MatchCmpOp())
		return false;
	if (!MatchExp())
		return false;
	return true;
}
bool MatchExp()
{
	if (!MatchTerm())
		return false;
	if (!MatchOtherTerm())
		return false;
	return true;
}
bool MatchOtherTerm()
{
	if (MatchAddOp())
		return MatchExp();
	return true;
}
bool MatchTerm()
{
	if (!MatchFactor())
		return false;
	if (!MatchOtherFactor())
		return false;
	return true;
}
bool MatchOtherFactor()
{
	if (MatchMultOp())
		return MatchTerm();
	return true;
}
bool MatchFactor()
{
	if (ReadToken(g_pf)->type == "$(")
	{
		if (MatchExp())
		{
			if(ReadToken(g_pf)->type == "$)")
				return true;
			else
			{
				BackToken(g_pf);
				BackToken(g_pf);
				return false;
			}
		}
		else
		{
			BackToken(g_pf);
			return false;
		}
	}
	else
	{
		BackToken(g_pf);
	}
		

	if (ReadToken(g_pf)->type == "$INTC")
		return true;
	else
	{
		BackToken(g_pf);
	}
	if (MatchVariable())
		return true;
	return false;

}
bool MatchVariable()
{
	if (ReadToken(g_pf)->type != "$id")
	{
		BackToken(g_pf);
		return false;
	}
	return MatchVariMore();
}
bool MatchVariMore()
{
	bool flag = true;
	if (ReadToken(g_pf)->type == "$[")
	{
		if (MatchExp())
		{
			if (ReadToken(g_pf)->type == "$]")
			{
				return true;
			}
			else
			{
				BackToken(g_pf);
				BackToken(g_pf);
				return false;
			}
		}
		else
		{
			BackToken(g_pf);
			return false;
		}
	}
	else
	{
		BackToken(g_pf);
	}
	if (ReadToken(g_pf)->type == "$.")
		if (MatchFieldVar())
			return true;
		else
		{
			BackToken(g_pf);
			return false;
		}
	else
	{
		BackToken(g_pf);
	}
	return true;
}
bool MatchFieldVar()
{
	if (ReadToken(g_pf)->type == "$id")
	{
		if (MatchFieldVarMore())
			return true;
		else
		{
			BackToken(g_pf);
			return false;
		}
	}
	else
	{
		BackToken(g_pf);
		return false;
	}
}
bool MatchFieldVarMore()
{
	if (ReadToken(g_pf)->type == "$[")
	{
		if (!MatchExp())
		{
			BackToken(g_pf);
			return false;
		}
		if (ReadToken(g_pf)->type != "$]")
		{
			BackToken(g_pf);
			return false;
		}
	}
	else
	{
		BackToken(g_pf);
	}
	return true;
}
bool MatchCmpOp()
{
	if (ReadToken(g_pf)->type == "$<")
		return true;
	else
		BackToken(g_pf);
	if (ReadToken(g_pf)->type == "$=")
		return true;
	else
		BackToken(g_pf);
	return false;
}
bool MatchAddOp()
{
	if (ReadToken(g_pf)->type == "$+")
		return true;
	else
		BackToken(g_pf);
	if (ReadToken(g_pf)->type == "$-")
		return true;
	else
		BackToken(g_pf);
	return false;
}
bool MatchMultOp()
{
	if (ReadToken(g_pf)->type == "$*")
		return true;
	else
		BackToken(g_pf);
	if (ReadToken(g_pf)->type == "$/")
		return true;
	else
		BackToken(g_pf);
	return false;
}


int main(int argc, char **argv)
{
	//设置源文件名
	string filename;
	if (argc >= 2)
		filename = argv[1];
	else
		filename = "snl.txt";

	//打开*.token
	g_pf = fopen((filename+".token").c_str(), "r");	

	//判断文件是否存在
	if (g_pf == NULL)
	{
		printf("请先进行词法分析!\n");
		return -1;
	}

	//打开语法分析日志文件,语法分析程序调用过程中记录分析信息
	g_pf_log = fopen((filename + ".log").c_str(), "w+");

	//进行语法分析,没有语法错误返回true,否则返回false
	bool re = MatchProgram();
	
	//最多匹配结果
	while (result.size() < max_read_num)
	{
		ReadToken(g_pf);//读入一个token
	}
	//关闭文件*.token
	fclose(g_pf);

	//打开文件*.result
	FILE * pfile = fopen((filename+".result").c_str(), "w+");	

	//打印result中除最后一个token之外的所有token
	for (auto iter = result.begin(); iter != result.end() - 1; ++iter)
	{
		printf(" 已匹配%s", iter->c_str());
		fprintf(pfile, "已匹配%s", iter->c_str());
	}

	
	if (re)//没有语法错误
	{
		//打印最后一个单词
		printf(" 已匹配%s", (result.end()-1)->c_str());
		fprintf(pfile, "已匹配%s", (result.end()-1)->c_str());

		//打印提示成功信息
		printf("语法分析完成,没有语法错误!\n");
		fprintf(pfile, "语法分析完成,没有语法错误!\n");
	}
	else//存在语法错误
	{
		//打印错误信息
		printf(" 语法错误:单词不匹配%s", (result.end()-1)->c_str());
		fprintf(pfile, "语法错误:单词不匹配%s", (result.end()-1)->c_str());
	}

	//关闭文件*.result
	fclose(pfile);
	
	//暂停
	system("pause");
}

程序运行结果打印到屏幕,并写入到*.result文件



语法分析阶段完成,如果要写编译器,后面还需要有语义分析,中间代码生成等等。


  • 2
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值