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

📄 comile_to_token.cpp

📁 扫描器设计(4学时) 1.实验目的 熟悉并实现一个扫描器。 2.实验类型 设计性。 3.实验基本要求 (1) 设计扫描器的自动机; (2) 设计翻译、生成Token的算法; (3)
💻 CPP
字号:
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <vector>
using namespace std;

	int aut[10][7]={ 2, 15, 15, 15, 8, 9, 15,
                       2, 3, 5,11, 11, 11, 11,
                       4, 0, 0, 0, 0, 0, 0,
                       4, 11, 5,11, 11, 11, 11,
                       7, 0, 0, 6, 0, 0, 0,
                       7, 0, 0, 0, 0, 0, 0,
                       7, 11, 11,11, 11, 11, 11,
                       8, 12, 12, 12, 8, 12, 12,
                       14, 14, 14, 14, 14, 10, 14,
					   13, 13, 13, 13, 13, 13, 13};

	string borderwords[15]={";", ":", "(", ")", ",", ":=", "+", "-", "*", "/",
					  ">", ">=", "==", "<", "<="};
	string keywords[13] = {"program","begin","end","var","while","do",
						"repeat","until","for","to","if","then","else"};
	vector<string> ID;//标识符表
    vector<float> C;//常数表
	vector<string> KEYWORDS;//关键字表
	vector<string> BORDERWORDS;//界符表
	bool flag = false;
	struct token
            { int code;
              int value;}token;            //Token结构
    struct token tok[100];      //Token数组
    int s;              //当前状态
    int n,p,m,e,t;     //尾数值,指数值,小数位数,指数符号,类型
    float num;         //常数值
	char w[50];      //源程序缓冲区
	int i;
	int codes = 0;
	string strToken = "";

	//查找是否为界符
	int Reserve(string strToken)
	{
		int r_i = 0;
		int flag_str = 0;
		for(r_i = 0; r_i < 15; r_i++ )//查找是否是界符
		{
			if(strToken == borderwords[r_i])
			{
				flag_str = 1;
			}
			if(flag_str == 1)
			{		
				return 3;
			}		
		}
		
		for(r_i = 0; r_i < 13; r_i++ )//查找是否为关键字
		{
			if(strToken == keywords[r_i])
			{
				flag_str = 2;
			}	
			if(flag_str == 2)
			{
				return 4;
			}
		}
		if(flag_str == 1)//界符返回3
			{
				return 3;
			}
		else if(flag_str == 2)//关键字返回4
			{
				return 4;
			}
		else 
			return 0;
	}
	//查找插入常数
	int InsertConst(float number)
	{
		bool c_flag = false;
		for(int c_i = 0; c_i < C.size(); c_i++)//查找是否常数表中已经存在
		{
			if(number == C[c_i])
			{
				c_flag = true; 
				break;
			}
				
		}
		if(c_flag == true)
			return c_i+1;
		else					//不存在则插入
		{
			C.push_back(number);
			return C.size();
		}	
	}
//查找插入标识符
	int InsertID(string strToken)
	{
		bool id_flag = false;
		for(int id_i = 0; id_i < ID.size(); id_i++)//查找标识表中是否已有
		{
			if(strToken == ID[id_i])
			{
				id_flag = true;
				break;
			}
				
		}
		if(id_flag == true)
			return id_i+1;
		else					//不存在则插入
		{
			ID.push_back(strToken);
			return ID.size();
		}
		
	}
	//查找插入关键字表
	int InsertKeywords(string strToken)
	{
			bool k_flag = false;
				for(int k_i = 0; k_i < KEYWORDS.size(); k_i++)//查找关键字表中是否已有
				{
					if(strToken == KEYWORDS[k_i])
					{
						k_flag = true; 
						break;
					}
						
				}
				if(k_flag)
				{
					return k_i+1;
				}
				else					//不存在则插入
				{
					KEYWORDS.push_back(strToken);
					return KEYWORDS.size();
				}
	}
	//查找插入界符表
	int InsertBorder(string strToken)
	{
				bool b_flag = false;
				for(int b_i = 0; b_i < BORDERWORDS.size(); b_i++)//查找界符表中是否已有
				{
					if(strToken == BORDERWORDS[b_i])
					{
						b_flag = true; 
						break;
					}
						
				}
				if(b_flag)
				{
					return b_i+1;
				}
				else					//不存在则插入
				{
					BORDERWORDS.push_back(strToken);
					return BORDERWORDS.size();
				}
	}
	//语意动作,执行相应的操作
	void acts(int temp)
	{
		switch(temp)
		{
			case 1:            //其它变量初始化;
				n=m=p=t=0;
				e = 1;
				num = 0;
				break;
			case 2:
				n = 10 * n + (w[i] - '0');
				break;
			case 3:
				t = 1;
				break;
			case 4:
				n = 10 *n + (w[i] - '0');
				m++;
				break;
			case 5:
				t = 1;
				break;
			case 6:
				if(w[i] == '-')
					e = -1;
				break;
			case 7:
				p = 10 * p + (w[i] - '0');
				break;
			case 8:
				strToken += w[i];
				break;
			case 9:
				strToken += w[i];
				break;
			case 10:
				strToken += w[i];
				break;
			case 11:
				num = n * pow(10,e*p-m);//计算常数值
				tok[i].code = 2;			//生成常数Token
				tok[i].value = InsertConst(num);
				break;
			case 12:
				codes = Reserve(strToken);//查关键字表 
				if(codes == 4)
				{
					tok[i].code = codes; //生成关键字Token
					tok[i].value = InsertKeywords(strToken);
				}
				else					 //生成标识符Token
				{
					tok[i].code = 1;  
					tok[i].value = InsertID(strToken);
				}
				break;
			case 13:
				codes = Reserve(strToken);  //查界符表
				if(codes == 4)						//生成关键字Token 4
				{
					 tok[i].code = codes; 
					 tok[i].value = InsertKeywords(strToken); 
				}
				else							 //生成界符Token
				{
					tok[i].code = codes; 
					tok[i].value = InsertBorder(strToken);   //生成界符Token
				}
				break;
			case 14:
				codes = Reserve(strToken);         //查界符表
				tok[i].code = codes; 
				tok[i].value = InsertBorder(strToken);       //生成界符Token
				break;				
			default:
				break;
		}
		
		
	}
//有限自动机的执行
	int find(int s_temp, char w_temp)
	{
		
		if(w_temp >= '0' && w_temp <= '9')
			return aut[s_temp-1][0];
		else if(w_temp == '.')
			return aut[s_temp-1][1];
		else if(w_temp >= 'a' && w_temp <= 'z' || w_temp >= 'A' && w_temp <= 'Z')
			return aut[s_temp-1][4];
		else if(w_temp == ';' ||w_temp == ',' ||w_temp == ':' ||w_temp == '(' ||
				w_temp == ')' ||w_temp == ':=' ||w_temp == '+' ||w_temp == '-' ||
				w_temp == '*' ||w_temp == '/' ||w_temp == '>' ||w_temp == '>=' ||
				w_temp == '<' ||w_temp == '<=' ||w_temp == '=')
			return aut[s_temp-1][5];
		else if(w_temp == '+' || w_temp == '-')
			return aut[s_temp-1][3];
		else if(w_temp == 'E' || w_temp == 'e')
			return aut[s_temp-1][2];
		else 
			return aut[s_temp-1][6];
	}

void main()
{

            //源程序指针,当前字符为w[i]

	ifstream infile("input_file.txt");
	ofstream outfile("output_file.txt");

	if(!infile.good())
	{
		cerr << "error : can not open this file " << endl;
	}

	while(!infile.eof())
	{	
		infile.getline(w,50);
		i = 0;
		do//读取一行文件
		{
			while(true)
			{
				if(w[i] == ' ')
				{
					i++;
				}
				else
					break;
			}

			strToken = "";
			i--;
			s = 1;

			while(s != 0)
			{
				acts(s);//语意执行

				if(s >=11 && s <= 14)
					break;
				i++;

				s = find(s,w[i]);//有限自动机执行
			}

			if(s == 0)	//词法错误
			{
				cout << "词法错误" << endl;	
			}	
		}while(w[i] != '\0');

//Token序列输出
		cout << "Token 序列 : " << endl;
		outfile << "Token 序列 : " << endl;//文件输出
		for(int out = 0; out < i; out++)
		{
			if(tok[out].code != 0)
			cout << "<" << tok[out].code << "," << tok[out].value << ">"<< " ";
			outfile <<  "<" << tok[out].code << "," << tok[out].value << ">"<< " ";//文件输出

		}
		cout << endl;
		outfile << endl;//文件输出
	}

	infile.close();

	cout << "常数表:";
	for(i = 0; i < C.size(); i++)
	{
		cout << C[i] << "  ";
	}
	cout << "\n" << "标识符表: ";
	for(i = 0; i< ID.size(); i++)
	{
		cout << ID[i] << "  "  ;
	}
	cout << "\n" << "关键字表: ";
	for(i = 0; i< KEYWORDS.size(); i++)
	{
		cout << KEYWORDS[i] << "  "  ;
	}
	cout << "\n" << "界符表: ";
	for(i = 0; i< BORDERWORDS.size(); i++)
	{
		cout << BORDERWORDS[i] << "  "  ;
	}
	cout << endl;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -