有了前文中的积木,继续实现一个词法分析器就不再困难。
先回顾一下各个模块:
然后我们试图将他们组装起来,因为一开始实现的都是零件(子函数)部分,本文主要介绍在main函数中运行的自动机。
还记得-1篇中的DFA吗?
经过第0篇,以及满足题目要求,我们最终的DFA应该是这样:
流程大致为:
按照以上思路,经过不断地调试完善,主函数设计为:
int main()
{
initialize();
string tmp;
char c;
while((c = getchar()) != EOF)
{
if(isspace(c)) // 忽略空白
continue;
if(isdigit(c)) // 如果是数字开头
{
ungetc(c, stdin);
cout << "DIGIT : " << num() << endl;
continue;
}
char peek;
peek = getchar(); // 一步提前量
if((c == '+' || c == '-') && isdigit(peek)) //输入带符号数
{
ungetc(peek, stdin);
ungetc(c, stdin);
cout << "DIGIT : " << num() << endl;
continue;
}
if(c == '/' && peek == '*') //输入注释
{
cout << "COMMENTS : /*" << comments() << endl;
continue;
}
int tkn = 0;
string s;
if(!isalnum(c)) // 输入c为专用符号
{
s += c;
if(peek == '=') // 所定义的双目运算符中第二个只有 = 可以偷懒;
s += peek;
else ungetc(peek, stdin);
tkn = query(s);
}
if(!tkn){ // 若不是专用符号开头,即为字母开头
ungetc(peek, stdin);
s += c;
while((c = getchar()) != EOF) // 读入这一串字母
{
if(isspace(c)) break;
if(isalnum(c) || c == '_')
s += c;
else{
ungetc(c, stdin);
break;
}
}
tkn = query(s); // 查询token
}
switch (tkn) // 依据token打印
{
case 1:
cout << "KEYWORD : " << s << endl;
break;
case 2:
cout << "BASIC : " << s << endl;
break;
case 3:
cout << "IDENTITY : " << s << endl;
break;
case 5:
cout << "SYMBOL : " << s << endl;
break;
default:
break;
}
}
return 0;
}
测试
使用测试样例1:
{ /* An example */
int i,j; float x; float[100] a;
while ( true) {
do i = i + 1; while ( a[i] < x);
if ( i >= j ) break;
x = a[i];
}
}
输出结果:
// line 1 { /* An example */
SYMBOL : {
COMMENTS : /* An example */
// line 2 int i,j; float x; float[100] a;
BASIC : int
IDENTITY : i
SYMBOL : ,
IDENTITY : j
SYMBOL : ;
BASIC : float
IDENTITY : x
SYMBOL : ;
BASIC : float
SYMBOL : [
DIGIT : 100
SYMBOL : ]
IDENTITY : a
SYMBOL : ;
// line 3 while ( true) {
KEYWORD : while
SYMBOL : (
KEYWORD : true
SYMBOL : )
SYMBOL : {
// line 4 do i = i + 1; while ( a[i] < x);
KEYWORD : do
IDENTITY : i
SYMBOL : =
IDENTITY : i
SYMBOL : +
DIGIT : 1
SYMBOL : ;
KEYWORD : while
SYMBOL : (
IDENTITY : a
SYMBOL : [
IDENTITY : i
SYMBOL : ]
SYMBOL : <
IDENTITY : x
SYMBOL : )
SYMBOL : ;
// line 5 if ( i >= j ) break;
KEYWORD : if
SYMBOL : (
IDENTITY : i
SYMBOL : >=
IDENTITY : j
SYMBOL : )
KEYWORD : break
SYMBOL : ;
// line 6 x = a[i];
IDENTITY : x
SYMBOL : =
IDENTITY : a
SYMBOL : [
IDENTITY : i
SYMBOL : ]
SYMBOL : ;
// line 7 }
SYMBOL : }
// line 8 }
SYMBOL : }
可以发现输出结果是完全正确的。
测试样例2:测试数字
+1212.551e1589
输出:
DIGIT : +1212.551e1589
好,到此,我们就完成了本次实验任务,一个简单的词法分析器的设计,在设计过程中,我们使用到了Trie树这一数据结构,使得代码变得美观了许多,同时,针对较为复杂的数字读取行为,我们设计了一个DFA确定的有限状态自动机完成,最终,我们在main函数中,将他们拼接起来,就形成了最后的词法分析器,整个实验用时半天,整体思想并不难理解,相信大家如果从头看到此处应该逻辑会相当清晰。
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。
举报投诉
-
分析器
+关注
关注
0文章
92浏览量
12478 -
有限状态自动机
+关注
关注
0文章
2浏览量
886
发布评论请先 登录
相关推荐
LabVIEW 生命小游戏 元胞自动机
生命小游戏,又叫元胞自动机,一个令人着迷的图灵完备系统参考资料:https://zhuanlan.zhihu.com/p/347305597https://www.zhihu.com
发表于 02-12 18:33
NFA→FA→GFA自动机转换算法
研究了不确定有穷自动机NFA、确定有穷自动机FA、规范有穷自动机GFA的基本关系与等价转换;给出了“NFA→FA”等价转换算法与“FA→GFA”等价转换算法,构造性证明了从FA到GFA的存
发表于 12-10 17:25
•14次下载
加性细胞自动机的同构性分析
根据矩阵方程理论和细胞自动机原理,提出了加性细胞自动机状态转移结构的同构性方法,该方法利用状态转移矩阵方程及其特征多项式分析规则90和150加性细胞自动机,证明了特
发表于 02-28 17:03
•35次下载
[自动机与自动线].李绍炎.扫描版
本书结合目前国内自动机械行业的现状,从应用的角度系统介绍了自动机械的模块化结构及工作原理、设计选型方法、装配调试及维护要领等。主要内容包括:自动机械的结构组成、输
发表于 09-17 16:02
•0次下载
异步多进程时间自动机的可覆盖性问题
已有的实时系统模型无法动态创建新进程.为此,基于时间自动机模型,提出了异步多进程时间自动机模型,将每个进程抽象为进程时间自动机,其部分状态能够触发新进程,考虑到队列会导致模型图灵完备,进程都被缓存
发表于 12-29 14:10
•0次下载
基于统计的AC自动机空间优化
基于访问频率、访问层次以及结合上述2种特征对AC自动机的部分节点实现完全化的算法。在Snort、ClamAV、URL等真实数据集上的实验结果表明,HybridFA算法的存储空间低于高级AC自动机的5%。此外,结合访问频率和访问层
发表于 03-13 16:47
•0次下载
自动机器学习简述
自动机器学习(AutoML)的目标就是使用自动化的数据驱动方式来做出上述的决策。用户只要提供数据,自动机器学习系统自动的决定最佳的方案。领域专家不再需要苦恼于学习各种机器学习的算法。
自动机终结字查找算法实现优化综述
自动机的秩与工业自动化中的部件定向器设计问题和理论计算机科学中的 Cerny-pin猜想密切相关。计算自动机的秩可以归结于查找
发表于 04-28 15:49
•3次下载
评论