c语言实现词法分析器+文法分析器(全代码)

学习记录,可能有很多不足,请谅解。

基本按照教材方法

在这里插入图片描述
在这里插入图片描述
注意本次词法分析只分析上图中拥有的

#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;

string reservewords[] = { "while","if","else","int","print"};//保留字
char character;//单个字符
string token;//一串字符
string yuyan;//语法分析结果
int numbers[9];//常量储存
int numberid = 0;
int wordsid = 0;
int boolflag;//储存id。转换。
int boolflag1;
int boolflag2;
bool elseflag=false;//判断else是否可执行
int whileflag=0;//判断while是否可执行
struct word
{
	string name;
	int value;
}words[9];//变量储存

bool digit() {//是否为数字
	return character >= '0' && character <= '9' ? 1 : 0;
}

void getbe() {//去除空格
	while (1) {
		if (character == ' ') {
			character = getchar();
		}
		else {
			break;
		}
	}
}

bool letter() {//是否为字符
	return (character >= 'a' && character <= 'z') || (character >= 'A' && character <= 'Z') ? 1 : 0;
}

void concatenation() {//连接字符串
	token = token + character;
}

int reserve() {//判断是否为保留字
	int id = 0;
	for (auto s : reservewords) {
		id++;
		if (s==token) {
			return id;
		}
	}
	return 0;
}

int word() {//判断变量是否存在
	int id = 0;
	for (int i = 0; i < 10;i++) {
		id++;
		string s = words[i].name;
		if (s==token) {
			return id;
		}
	}
	return 0;
}

int number() {//判断常量是否存在
	for (int i = 0; i <= numberid;i++) {
		if (numbers[i]== atoi(token.c_str())) {
			return i+1;
		}
	}
	return 0;
}

int main()
{
	freopen("chenxu.txt", "r", stdin);//读取土木
	character = getchar();
	while (character!=EOF) {//词法分析
		getbe();
		if (letter()) {
			while (letter() || digit()) {
				concatenation();
				character = getchar();
			}
			boolflag = reserve();
			if (boolflag!= 0) {
				yuyan += '_';
				yuyan += (boolflag + '0');
				token = "";
			}
			else {
				boolflag = word();
				if (boolflag != 0) {
					yuyan += '@';
					yuyan += (boolflag + '0');
				}
				else {
					words[wordsid].name= token;
					words[wordsid].value = 0;
					yuyan += '@';
					yuyan += ((wordsid+1) + '0');
					wordsid++;
				}
				token = "";
			}
		}
		else if (digit()) {
			while (digit()) {
				concatenation();
				character = getchar();
			}
			boolflag = number();
			if (boolflag != 0) {
				yuyan += '$';
				yuyan += (boolflag + '0');
			}
			else {
				int n = atoi(token.c_str());
				numbers[numberid] = n;
				yuyan += '$';
				yuyan += ((numberid + 1) + '0');
				numberid++;
			}
			token = "";
		}
		else if (character == '+') {
			yuyan += character;
			character = getchar();
		}
		else if (character == '-') {
			yuyan += character;
			character = getchar();
		}
		else if (character == '=') {
			yuyan += character;
			character = getchar();
		}
		else if (character == '>') {
			int flag = 0;
			character = getchar();
			if (character == '=') {
				flag = 1;
				yuyan += '>';
				yuyan += character;
				character = getchar();
			}
			if (flag == 0) {
				yuyan += '>';
			}
		}
		else if (character == '<') {
			yuyan += character;
			character = getchar();
		}
		else if (character == '(') {
			yuyan += character;
			character = getchar();
		}
		else if (character == ')') {
			yuyan += character;
			character = getchar();
		}
		else if (character == '{') {
			yuyan += character;
			character = getchar();
		}
		else if (character == '}') {
			yuyan += character;
			character = getchar();
		}
		else if (character == ';') {
			yuyan += character;
			character = getchar();
		}
		else {
			character = getchar();
			continue;
		}
	}
	cout << yuyan;
	cout << endl;
}

上面是词法分析,下为文法分析,因为文法分析当时只做到了能分析老师给的特定序列并输出结果,所以文法分析存在很多问题,1. if和else依然一对一匹配,但是if和else中间可以穿插其他语句。可以在程序中写判断大小的句子,作为中断判定,如果判断失败,则作为断点中断程序,如果判断成功,就继续程序。while中只能再出现while或一个计算式等

在代码中添加函数


int bds(int i) {//单个式子文法
	if (yuyan[i] == '@') {
		i++;
		character = yuyan[i];
		if (digit()) {
			boolflag = character - '0';
			i++;
			character = yuyan[i];
			if (character == '=')
			{
				i++;
				character = yuyan[i];
				if (yuyan[i] == '@') {
					i++;
					character = yuyan[i];
					if (digit()) {
						boolflag1 = character - '0';
						i++;
						character = yuyan[i];
						if (character == '+')
						{
							i++;
							character = yuyan[i];
							if (yuyan[i] == '$') {
								i++;
								character = yuyan[i];
								if (digit()) {
									boolflag2 = character - '0';
									i++;
									character = yuyan[i];
									if (character == ';')
									{
										words[boolflag - 1].value = words[boolflag1 - 1].value + numbers[boolflag2 - 1];
										i++;
										return i;
									}
									else {
										return 0;
									}
								}
								else {
									return 0;
								}
							}
							else {
								return 0;
							}
						}
						else if (character == '-') {
							i++;
							character = yuyan[i];
							if (yuyan[i] == '$') {
								i++;
								character = yuyan[i];
								if (digit()) {
									boolflag2 = character - '0';
									i++;
									character = yuyan[i];
									if (character == ';')
									{
										words[boolflag - 1].value = words[boolflag1 - 1].value - numbers[boolflag2 - 1];
										i++;
										return i;
									}
									else {
										return 0;
									}
								}
								else {
									return 0;
								}
							}
							else {
								return 0;
							}
						}
						else {
							return 0;
						}
					}
					else {
						return 0;
					}
				}
			}
			else if (character == '>') {
				i++;
				character = yuyan[i];
				if (yuyan[i] == '$') {
					i++;
					character = yuyan[i];
					if (digit()) {
						boolflag1 = character - '0';
						if (words[boolflag - 1].value > numbers[boolflag1-1]) {
							i++;
							return i;
						}
						else {
							return -1;
						}
					}
					else {
						return 0;
					}
				}
				else if (character == '=') {
					i++;
					character = yuyan[i];
					if (yuyan[i] == '$') {
						i++;
						character = yuyan[i];
						if (digit()) {
							boolflag1 = character - '0';
							if (words[boolflag - 1].value >= numbers[boolflag1-1]) {
								i++;
								return i;
							}
							else {
								return -1;
							}
						}
						else {
							return 0;
						}
					}
					else {
						return 0;
					}
				}
				else {
					return 0;
				}
			}
			else if (character == '<') {
				i++;
				character = yuyan[i];
				if (yuyan[i] == '$') {
					i++;
					character = yuyan[i];
					if (digit()) {
						boolflag1 = character - '0';
						if (words[boolflag - 1].value < numbers[boolflag1-1]) {
							i++;
							return i;
						}
						else {
							return -1;
						}
					}
					else {
						return 0;
					}
				}
				else {
					return 0;
				}
			}
			else {
				return 0;
			}
		}
		else {
			return 0;
		}
	}
    else {
         return 0;
    }
}

int whilesx(int i) {//循环分析
	int j = i;
	i++;
	int aa = bds(i);
	if (aa > 0) {
		i = aa;
		character = yuyan[i];
		if (character == ')') {
			i++;
			character = yuyan[i];
			if (character == '{') {
				i++;
				character = yuyan[i];
				aa = bds(i);
				if (aa != 0) {
					i = aa;
					if (yuyan[i] == '}') {
						i++;
						whileflag = i;
						i = j;
						whileflag=whilesx(i);
					}
					else {
						return 0;
					}
				}
				else {
					if (character == '_') {
						i++;
						character = yuyan[i];
						if (yuyan[i] == '1') {
							i++;
							character = yuyan[i];
							if (yuyan[i] == '(') {
								whileflag=whilesx(i);
								i = j;
								whileflag=whilesx(i);
							}
							else {
								return 0;
							}
						}
						else {
							return 0;
						}
					}
					else {
						return 0;
					}
				}
			}
			else {
				return 0;
			}
		}
		else {
			return 0;
		}
	}
	else if (aa == -1) {
		if (whileflag == 0) {
			while (yuyan[i] != '}') {
				i++;
			}
			whileflag = i;
			return whileflag;
		}
		else {
			return whileflag;
		}
	}
	else {
		return 0;
	}
}

在main方法中添加

for (int i = 0; i < yuyan.length();) {//文法分析,输出结果
		character = yuyan[i];
		if (character == '_') {
			i++;
			character = yuyan[i];
			if (character == '1') {
				i++;
				character = yuyan[i];
				if (yuyan[i] == '(') {
					int aa = whilesx(i);
					if (aa == 0) {
						cout << "出错了"; break;
					}
					else {
						while (yuyan[aa] == '}') {
							aa++;
						}
						i = aa;
					}
				}
				else {
					cout << "出错了"; break;
				}
			}
			else if (character == '2') {
				elseflag = false;
				i++;
				character = yuyan[i];
				if (yuyan[i] == '(') {
					i++;
					int aa = bds(i);
					if (aa > 0) {
						elseflag = false;
						i = aa;
						character = yuyan[i];
						if (character == ')') {
							i++;
							character = yuyan[i];
							if (character == '{') {
								i++;
								character = yuyan[i];
								aa = bds(i);
								if (aa != 0) {
									i = aa;
									if (yuyan[i] == '}') {
										i++;
										continue;
									}
									else {
										cout << "出错了"; break;
									}
								}
								else {
									cout << "出错了"; break;
								}
							}
							else {
								cout << "出错了"; break;
							}
						}
						else {
							cout << "出错了"; break;
						}
					}
					else if (aa == -1) {
						elseflag = true;
						while (yuyan[i] != '}') {
							i++;
						}
						i++;
					}
					else {
						cout << "出错了"; break;
					}
				}
				else {
					cout << "出错了"; break;
				}
			}
			else if (character == '3') {
				if (elseflag == false) {
					while (yuyan[i] != '}') {
						i++;
					}
					i++;
				}
				else {
					i++;
					character = yuyan[i];
					if (yuyan[i] == '{') {
						i++;
						character = yuyan[i];
						int aa = bds(i);
						if (aa != 0) {
							i = aa;
							if (yuyan[i] == '}') {
								i++;
								continue;
							}
							else {
								cout << "出错了"; break;
							}
						}
						else {
							cout << "出错了"; break;
						}
					}
					else {
						cout << "出错了"; break;
					}
				}
			}
			else if (character == '4') {
				i++;
				character = yuyan[i];
				if (yuyan[i] == '@') {
					i++;
					character = yuyan[i];
					if (digit()) {
						boolflag = character - '0';
						i++;
						character = yuyan[i];
						if (character == '=')
						{
							i++;
							character = yuyan[i];
							if (yuyan[i] == '$') {
								i++;
								character = yuyan[i];
								if (digit()) {
									boolflag1 = character - '0';
									i++;
									character = yuyan[i];
									if (character == ';')
									{
										words[boolflag - 1].value = numbers[boolflag1 - 1];
										i++;
									}
									else {
										cout << "出错了";
										break;
									}
								}
								else {
									cout << "出错了";
									break;
								}
							}
							else {
								cout << "出错了";
								break;
							}
						}
						else {
							cout << "出错了";
							break;
						}
					}
					else {
						cout << "出错了";
						break;
					}
				}
				else {
					cout << "出错了";
					break;
				}
			}
			else if (character == '5') {
				i++;
				character = yuyan[i];
				if (yuyan[i] == '@') {
					i++;
					character = yuyan[i];
					if (digit()) {
						boolflag = character - '0';
						i++;
						character = yuyan[i];
						if (character == ';')
						{
							cout << words[boolflag - 1].value;
							i++;
						}
						else {
							cout << "出错了";
							break;
						}
					}
					else {
						cout << "出错了";
						break;
					}
				}
				else {
					cout << "出错了";
					break;
				}
			}
			else { cout << "出错了"; break; }
		}
		else if (character == '@') {
			i = bds(i);
			if (i == 0) {
			cout << "出错了"; break;
			}
			if(i==-1){
				cout << "程序中断退出"; break;
			}
        }
        else {
            cout << "出错了"; break;
	    }
	}

结果展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

感谢观看

  • 6
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值