编译原理之基于自动机的词法分析器的设计与实现

一、实验目的

设计与实现一个词法分析器,加深对词法分析原理的理解。

二、实验内容

需要实现的功能:

1)输入:源程序字符串,源程序存储在文本文件中(编码格式ANSI),文件名作为命令行参数输入;

2)输出:输出token序列到标准输出设备。

三、实验要求

语言的词法:

1、关键字

main

if then else

while do

repeat until

for from to step

switch of case default

return

integer real char bool

and or not mod

read write

所有关键字都是小写。

2、专用符号

运算符包括:=、+、-、*、/、<、<=、>、>=、!=

分隔符包括:,、;、:,{、}、、、(、)

3、其它标记ID和NUM

通过以下正规式定义其它标记:

ID ® letter(letter | digit)*

NUM ® digit digit*

Letter ® a | ... | z | A | ... | Z

Digit ® 0|...|9

4、空白格由空格、制表符和换行符组成

空白一般用来分隔ID、NUM、专用符号和关键字,词法分析阶段通常被忽略。

四、实验设计

五、奉上代码

cpp 复制代码
#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

string code;

unordered_map<string, int> word = {
{"main",1}, {"if",2}, {"then",3}, {"while",4},{"do",5},{"static",6},{"ID",25},{"NUM",26},{"+",27},
{"-",28},{"*",29},{"/",30},{":",31},{":=",32},{"<",33},{"<>",34},{"<=",35},{">",36},{">=",37},{"=",38},
{"default",39},{"define",40},{";",41},{"(",42},{")",43},{"{",44},{"}",45},{"int",7},{"double",8},{"struct",9},{"break",10},
{"else",11},{"long",12},{"switch",13},{"case",14},{"typedef",15},{"char",16},{"return",17},{"const",18},
{"float",19},{"short",20},{"continue",21},{"for",22},{"void",23},{"sizeof",24},{"#",0}	
};

map<string,int> token; 

void wordAnalysis(){
	
	int s=0;
	
	while(s<code.length()){
		
		//去除空格、制表符、和换行符
		if(code[s]==' '||code[s]=='\n'||code[s]=='\t'){ 
			s++;	
			continue;
		}
		
		if(code[s]=='/'&&s+1<code.length()&&code[s+1]=='/'){
			//去除单行注释
			s+=2;
			
			while(s<code.length()&&code[s]!='\n'){
				s++;
			}
			
			continue;
		}
		
		if(code[s]=='/'&&s+1<code.length()&&code[s+1]=='*'){
			//去除多行注释
			s+=3;
			
			while(s<code.length()&&(code[s-1]!='*'||code[s]!='/')){
				s++;
			}
			
			continue;
		}
		
		if(isalpha(code[s])||code[s]=='_'){
			//识别标识符和关键字
			string temp;
			temp+=code[s];
			
			s++;
			
			while(s<code.length()&&(isalpha(code[s])||code[s]=='_'||isdigit(code[s]))){
				temp+=code[s];
				s++;				
			}
			
			if(word.count(temp))
			token[temp]=word[temp];
			else
			token[temp]=word["ID"];
			
			continue;
		}
		
		if(isdigit(code[s])){
			
			string temp;
			temp+=code[s];
			//识别普通数字
			s++;
			
			while(s<code.length()&&isdigit(code[s])){
				temp+=code[s];
				s++;
			}
			
			if (s < code.length() && code[s] == '.') {
                temp += code[s];  // 识别浮点数
                s++;

                while (s < code.length() && isdigit(code[s])) {
                    temp += code[s];
                    s++;
                }

                token[temp] = word["NUM"]; 
            }
			
			else if(s<code.length()&&(isalpha(code[s])||code[s]=='_')){
				//识别错误的以数字开头的标识符
				temp+=code[s];
				s++;
				
				while(s<code.length()&&(isalpha(code[s])||code[s]=='_'||isdigit(code[s]))){
					temp+=code[s];
					s++;				
				}
					
				token[temp]=-1;
			}else{
				token[temp]=word["NUM"];
			}
			
			continue;
		}
		
		string temp(1,code[s]);
        if (word.count(temp)) {
            // 检查双字符操作符
            if ((temp == ":" || temp == "<" || temp == ">") && s + 1 < code.length()) {
                string twoChar = temp + code[s + 1];
                if (word.count(twoChar)) {
                    token[twoChar] = word[twoChar];
                    s += 2; // 跳过两个字符
                    continue;
                }
            }

            token[temp] = word[temp];
            s++; // 跳过单字符
        } else {
        	token[temp]=-1;
            s++; 
        }		
			
	}
}

int main(){
	
	ifstream file("C:\\Users\\24775\\Desktop\\test.txt");
	
	if(!file){
		cout<<"file read error!"<<endl;
	}
	
	string line;
	//文件读取
	while(getline(file, line)){
		code+=line;
		code+='\n';
	}
	
	cout<<code;
	
	file.close();
	
	wordAnalysis();
	//打印词法分析后的token
	for(auto i : token){
		if(i.second!=-1)
		cout<<"token: "<<i.first<<" "<<"syn: "<<i.second<<endl;
		else
		cout<<"token: "<<i.first<<" "<<"Invalid Token !!!"<<endl;
	}

	return 0;
}

测试代码:

输出结果:

相关推荐
xunberg8 小时前
【生命科学 Agent】推理平台(三)
算法·程序员·架构
INGNIGHT8 小时前
151 · 买卖股票的最佳时机 III(序列dp)
数据结构·算法·leetcode
庖丁解牛8 小时前
十进制转二进制:凑数法(填1法)
算法
行者全栈架构师8 小时前
【共创稿事节】双引擎智能相册:HarmonyOS 7(API 26)文搜图 × 图像超分端侧 AI 联动实战
前端·算法·架构
小蒋观天下8 小时前
【无标题】红外补光近距过曝、远距欠曝:导致车牌AI识别失效调试
人工智能·深度学习·数码相机·算法·机器学习·ai大模型
会编程的小孩8 小时前
Qt学习路线大纲图
c++
洁洁!9 小时前
手搓 C++ 线程池详细讲解以及如何面试应答
java·c++·面试
坤坤子吖9 小时前
C++继承:继承的基本用法与访问规则
开发语言·c++·笔记·学习
Demon--hx9 小时前
C++ 文件流:理解 ifstream/ofstream 与 RAII 机制
开发语言·c++
纪念 2299 小时前
C++ stack和queue
开发语言·c++