词法分析器 (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;
}

  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
词法分析器是编译器的第一个阶段,用于将源代码分解成单个的词语(Token)。以下是一个简单C++实现: ```cpp #include <iostream> #include <string> #include <vector> using namespace std; // 定义Token类 class Token { public: string type; // 类型 string value; // 值 Token(string type, string value) { this->type = type; this->value = value; } }; // 定义词法分析器类 class Lexer { private: string input; // 输入代码 int position; // 当前位置 char current; // 当前字符 public: Lexer(string input) { this->input = input; position = 0; current = input[position]; } // 获取下一个字符 void advance() { position++; if (position < input.size()) { current = input[position]; } else { current = '\0'; } } // 获取数字 Token get_number() { string number = ""; while (current >= '0' && current <= '9') { number += current; advance(); } return Token("NUMBER", number); } // 获取符号 Token get_symbol() { string symbol = ""; while (current == '+' || current == '-') { symbol += current; advance(); } return Token("SYMBOL", symbol); } // 分析输入代码 vector<Token> analyze() { vector<Token> tokens; while (current != '\0') { if (current >= '0' && current <= '9') { tokens.push_back(get_number()); } else if (current == '+' || current == '-') { tokens.push_back(get_symbol()); } else { advance(); } } return tokens; } }; int main() { string input = "12+34-56"; Lexer lexer(input); vector<Token> tokens = lexer.analyze(); for (int i = 0; i < tokens.size(); i++) { cout << "Token: " << tokens[i].type << ", Value: " << tokens[i].value << endl; } return 0; } ``` 以上代码实现了一个简单词法分析器,可以将输入的代码分解成数字和符号两种类型的Token,并输出它们的类型和值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值