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

📄 词法分析.cpp

📁 CMM语言解释器的词法分析(C++编写)
💻 CPP
字号:
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

//用于保存记号的二元式的结构体
struct code_val{
	string code; //记号的类型
	string val; //记号的值
};

//判断是否基本字
string reserve (string token)
{
	//基本字表
	const string reserveword[] = {"if","else","while","read","write","int","real"}; //保留字表
	
	for (int j = 0; j < 7; j ++) 
		if (token == reserveword[j]) 
			return "reserved word"; //返回"基本字"
	
		return "ID"; //返回"标识符"
}

//扫描函数,返回一个单词的二元式
struct code_val scanner(string line, int i) {
	   
	   struct code_val t; //用于存放单词的二元式
	   t.code = "NUL";  //识别前初始化 
	   
	   string token = ""; //拼接单词的字符串
	   
	   while (line[i] == ' ') i++; //去除前导空格
       
	   //识别标识符或基本字
	   if (line[i] >= 'a' && line[i] <= 'z') {
	       while (line[i] >= 'a' && line[i] <= 'z' || line[i] >= '0' && line[i] <= '9' || line[i] == '_')
		   {
			   //拼接
		       token = token + line[i];
		       i ++;
		   }
		   t.code = reserve(token); //判断是否基本字
		   t.val = token;
           
		   //判断标识符是否以下划线结束
		   if (token[token.size() - 1] == '_') 
		   {
			   cout << "error" << endl;
			   exit(0);
		   }//输出错误信息并中断程序

		   return t; //返回标识符或基本字的二元式
	   }
       
       //识别整常数或实常数
	   if (line[i] >= '0' && line[i] <= '9') {
		   while (line[i] >= '0' && line[i] <= '9') {
			   token = token + line[i]; //拼接
		       i ++;
		   }
	       if (line[i] == '.') {
			   token = token + line[i];
		       i ++;
		       while (line[i] >= '0' && line[i] <= '9') {
				   token = token + line[i]; //拼接
			       i ++;
			   }
		       t.code = "REAL"; //实常数
		   }
	       else 
		       t.code = "INT"; //整常数
	       t.val = token;
	       return t; //返回整常数或实常数的二元式
	   }

	   //识别实常数(以小数点起始)
	   if (line[i] == '.') {
		   token = token + line[i]; //拼接
		   i++;
		   if (line[i] >= '0' && line[i] <= '9') {
			   while (line[i] >= '0' && line[i] <= '9') {
				   token = token + line[i]; //拼接
				   i++;
			   }
			   t.code = "REAL";
			   t.val = token;
			   return t; //返回实常数的二元式
		   }
		   else {
			   cout << "Error word" << token << endl; //输出错误信息
			   exit(0);
		   }
	   }

       //识别其余单词
	   switch (line[i]) {
	   case',':
		   t.val = ",";break;
	   case';':
		   t.val = ";";break;
	   case'(':
		   t.val = "(";break;
	   case')':
		   t.val = ")";break;
	   case'[':
		   t.val = "[";break;
	   case']':
		   t.val = "]";break;
	   case'+':
		   t.val = "+";break;
       case'-':
		   t.val = "-";break;
       case'*':
		   t.val = "*";break;
       case'/':
		   t.val = "/";break;
	   case'{':
		   t.val = "{";break;
       case'}':
		   t.val = "}";break;
       case'>':
		   t.val = ">";break;
	   case'=':
		   if(line[i+1] == '=') {
			   t.val = "==";
			   i ++;
		   }
		   else t.val = "=";
		   break;
       case'<':
		   if(line[i+1] == '>') {
			   t.val = "<>";
			   i ++;
		   }
		   else t.val = "<";
		   break;
	   default:
		   cout<<"Error char"<<line[i]<<endl; //错误字符
		   exit(0);
	   }
	   
	   i++; //指向下个单词

	   return t; //返回运算符合和界符的二元式
}

void main() 
{

   string inputfile;//输入文件名
   
   //inputfile = "input.txt";
   cout << "请输入源文件名:  " ;
   cin >> inputfile;
   cout << endl;

   ifstream infile(inputfile.c_str());

   int line_number = 0;//统计行号

   bool incomment = false;//是否处于注释中的标志
   bool written = false;//该行是否已输出的标志
   
   string readline,source;//从文件读入行
   code_val returnvalue;
   
   while(getline(infile, readline))   
   { 
     written = false; //该行初始状态为未输出
	 
	 if (readline != "") {
  	  
       int i = 0;//指示一行的指针
	 
       while (readline[i] == ' ') i++; //去除前导空格
	 
	   if (readline[i] == '/' && readline[i + 1] == '*')
			   incomment = true; //进入注释
	   else 
	   {
		   if (! incomment) {
		       line_number++;
		       cout << line_number << " " << readline << endl;
			   written = true;
		   }
		   if (incomment)  
		   {
			   while (readline[i] == ' ') i++; //去除前导空格
			   
			   if (readline[i] == '*' && readline[i + 1] == '/')
			   {
				 i = i + 2;
	             incomment = false; //结束注释
			   }
		   }
	   }
	   source = readline;
       readline = readline + '#'; //在行尾巴加上结束识别符'#'

	   if (readline[i] != '#') {
	   do{
		   if (incomment) 
		   {
			   i ++;
			   if (readline[i] == '*' && readline[i + 1] == '/')
			   {
				   i = i + 2;
				   incomment = false; //结束注释
			   }
		   }
		   else {
           if (readline[i] == '/' && readline[i + 1] == '*')
			   incomment = true; //进入注释
		   else {

		   returnvalue = scanner(readline,i);
	   
		   if (! written) 
		   {
			   cout << line_number << ": " << source << endl;
			   written = true;
		   }
	       
		   cout << "  " << line_number << ": ";
   
           //输出单词的二元式
    	   if (returnvalue.code == "reserved word")
	    	   cout << returnvalue.code << ": " << returnvalue.val << endl;
	       if (returnvalue.code == "ID")
    		   cout << returnvalue.code << ", name = " << returnvalue.val << endl;
    	   if (returnvalue.code == "REAL" || returnvalue.code == "INT")
   	    	   cout<< returnvalue.code << ", val = " << returnvalue.val << endl;
    	   if (returnvalue.code == "NUL")
    		   cout<< returnvalue.val << endl;

           while (readline[i] == ' ') i++;
 
		   for (int j = 1; j < returnvalue.val.size(); j++) 
			   i++;
		   i++;
		   }
		   }
	   }while(readline[i] != '#');
	   }
	 }
   }
   
   system("pause"); 

}

⌨️ 快捷键说明

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