词法分析器 (c++实现) 简单实现

参考种别码

勿抄,请不要限制你的想象力。

改进之处:遇到不能识别的应该继续往后识别,功能未完善。
思路:看代码就懂了;
Talk is cheap. Show me the code.

 

#include <bits/stdc++.h>//万用头文件
using namespace std;
//——————————全局变量——————————
struct Keyword
{
	string token;
	int syn;
}Key[13];

int syn,tag=1;//种别码,标记
string token;
int i = 0;//全局变量作为下标
//————————————————————————————

bool judletter(char ch)//判断字符
{
	if (ch>='A'&& ch<='Z'|| ch >= 'a'&& ch <= 'z')
		return 1;
	else
		return 0;
}

bool judnum(char num)//判断数字
{
	if (num>='0'&&num<='9')
		return 1;
	else
		return 0;
}

int scan(string input)//对单个字符块进行扫描
{
	if (input[i]==' ')//空格
	{
		syn = -2;
		i++;
		return syn;
	}
	token = "";//NULL默认为0,不为空

	if (judnum(input[i]))//数字开头
	{
		int sum = 0;
		while (judnum(input[i]))
		{
			sum = 10 * sum + (input[i] - '0');
			i++;
			syn = 20;
		}
		token += to_string(sum);
		return syn;
	}
	if (judletter(input[i]))//字母开头可能为1、标识符 2、关键字
	{
		while (judletter(input[i])||judnum( input[i]))
		{
			token += input[i];
			i++;
		}
		syn = 10;//标识符(e.g.变量、常量)
		for (int j = 1; j <= 12; j++)//
		{
			if (token == Key[j].token)
			{
				syn = Key[j].syn;
				return syn;
			}
		}
		return syn;
	}
	else //符号
	{
		token = "";
		switch (input[i]) {
		case'=':
			syn = 21;
			i++;
			token = "=";
			if (input[i]=='=')
			{
				syn = 39;
				i++;
				token = "==";
			}
			return syn;
			break;//多余,习惯case+break
		case '+':
			syn = 22;
			i++;
			token = "+";
			return syn;
		case'-':
			syn = 23;
			i++;
			token = "-";
			return syn;
		case'*':
			syn = 24;
			i++;
			token = "*";
			return syn;
		case'/':
			syn = 25;
			i++;
			token = "/";
			return syn;
		case'(':
			syn = 26;
			i++;
			token = "(";
			return syn;
		case')':
			syn = 27;
			i++;
			token = ")";
			return syn;
		case'[':
			syn = 28;
			i++;
			token = "[";
			return syn;
		case']':
			syn = 29;
			i++;
			token = "]";
			return syn;
		case'{':
			syn = 30;
			i++;
			token = "{";
			return syn;
		case'}':
			syn = 31;
			i++;
			token = "}";
			return syn;
		case',':
			syn = 32;
			i++;
			token = ",";
			return syn;
		case':':
			syn = 33;
			i++;
			token = ":";
			return syn;
		case';':
			syn = 34;
			i++;
			token = ";";
			return syn;
		case'>':
			syn = 35;
			i++;
			token = ">";
			if (input[i] == '=')
			{
				syn = 37;
				i++;
				token = ">=";
			}
			return syn;
		case'<':
			syn = 36;
			i++;
			token = "<";
			if (input[i] == '=')
			{
				syn = 38;
				i++;
				token = "<=";
			}
			return syn;
		case'!':
			syn = -1;//若只有一个!则报错
			i++;
			if (input[i] == '=')
			{
				syn = 40;
				i++;
				token = "!=";
			}
			return syn;

		case'"'://此处仍需改进 ,"也应该作为一个单独单词符号,拥有种别码
			syn = -1;
			token += input[i];
			i++;
			while (input[i] != '"')
			{
				if (input[i] == '#')
				{
					tag = 0;
					break;
				}
				else
				{
					token += input[i];
					i++;
				}
			}
			//————————————
			if (tag)
			{
				token += input[i];
				i++;
				syn = 50;
				return syn;
			}
			else
			{
				syn = -3;
				return syn;
			}
		case '#':
			syn = 0;
			return syn;
			break;

		default:
			syn = -1;
			return syn;
			break;
		}
	}

}

void initial()//初始化保留字
{
	Key[1] = { "main",1 };
	Key[2] = { "int",2 };
	Key[3] = { "char",3 };
	Key[4] = { "if",4 };
	Key[5] = { "else",5 };
	Key[6] = { "for",6 };
	Key[7] = { "while",7 };
	Key[8] = { "return",8 };
	Key[9] = { "void",9 };
	Key[10] = { "STRING",50 };
	Key[11] = { "ID",10 };
	Key[12] = { "INT",20 };
}

string input()//读取本地文件,code.txt位于本项目cpp存放地,若更改位置则需输入相应地址,
//注:window的地址和代码地址\两个地址符相反/
{
	//把全部文件读取放入string a中
	ifstream in("code.txt", ios::in);
	istreambuf_iterator<char> beg(in), end;
	string a(beg, end);//或者string a;a.assign(beg,end);
	in.close();
	return a;
}

void output(string a)//输出,循环在此实现
{
	cout << "(种别码,token/sum)" << endl;
	int syn;
	do
	{
		syn = scan(a);
		switch (syn)
		{
		case -1:
			cout << "error 非法字符" << endl;
			syn = 0;
			break;
		case -2:
			break;
		case -3:
			cout << "语法错误(引号不全)" << endl;
			syn = 0;
		default:
			cout << "(" << syn << "," << token << ")" << endl;
		}
	} while (syn!=0);
}

int main()
{
	initial();//初始化
	string a = input();//读取文件置入字符串a中,样例把换行读成/n
	//cout << "请输入以#结尾的字符串" << endl;
	/*若想cmd内输入,则把input()那一行换成下面这些;
	string a;
	//getline(cin,a);
	*/
	cout << "读取到的字符串为:" << a << endl;
	output(a);
	return 0;
}

 

 

 


posted @ 2020-12-06 00:32  gidear  阅读(587)  评论(0编辑  收藏  举报