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

一、实验目的

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

二、实验内容

需要实现的功能:

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;
}

测试代码:

输出结果:

相关推荐
王老师青少年编程3 小时前
csp信奥赛C++高频考点专项训练之贪心算法 --【哈夫曼贪心】:合并果子
c++·算法·贪心·csp·信奥赛·哈夫曼贪心·合并果子
叼烟扛炮4 小时前
C++第二讲:类和对象(上)
数据结构·c++·算法·类和对象·struct·实例化
天疆说4 小时前
【哈密顿力学】深入解读航天器交会最优控制中的Hamilton函数
人工智能·算法·机器学习
wuweijianlove5 小时前
关于算法设计中的代价函数优化与约束求解的技术7
算法
leoufung5 小时前
LeetCode 149: Max Points on a Line - 解题思路详解
算法·leetcode·职场和发展
样例过了就是过了5 小时前
LeetCode热题100 最长公共子序列
c++·算法·leetcode·动态规划
HXDGCL5 小时前
矩形环形导轨:自动化循环线的核心运动单元解析
运维·算法·自动化
谭欣辰5 小时前
C++ 排列组合完整指南
开发语言·c++·算法
代码中介商6 小时前
银行管理系统的业务血肉 —— 流程、状态机、输入校验与持久化(下篇)
c语言·算法
橙子也要努力变强6 小时前
信号捕捉底层机制-机理篇2
linux·服务器·c++