热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【编译原理】手工构造词法分析器

【问题描述】通过设计c语言常见单词的正规文法或正规式,而后得到NFA,再确定化得到DFA,根据DFA的转换矩阵或转换图,用c

【问题描述】通过设计c语言常见单词的正规文法或正规式,而后得到NFA,再确定化得到DFA,根据DFA的转换矩阵或转换图,用c++语言实现词法分析器。
【输入形式】输入一段完整的c语言程序
【输出形式】各类单词的token字
【样例输入】

int main(){int a &#61; 10;double b &#61; -20.9;if(a<&#61;b)a&#43;&#61;b;return a;
}

【样例输出】

line1:(type, int)line1:(keyword, main)line1:(bracket, ()line1:(bracket, ))line1:(bracket, {)line2:(type, int)line2:(identify, a)line2:(OPT, &#61;)line2:(integer, 10)line2:(bracket, ;)line3:(type, double)line3:(identify, b)line3:(OPT, &#61;)line3:(decimal, -20.9)line3:(bracket, ;)line4:(keyword, if)line4:(bracket, ()line4:(identify, a)line4:(OPT, <&#61;)line4:(identify, b)line4:(bracket, ))line5:(identify, a)line5:(OPT, &#43;&#61;)line5:(identify, b)line5:(bracket, ;)line6:(identify, a)line6:(OPT, &#61;)line6:(integer, 0)line6:(bracket, ;)line7:(keyword, return)line7:(identify, a)line7:(bracket, ;)line8:(bracket, })

【样例说明】需要识别的关键字包括main, return, if, else, do, while, for, scanf, printf, sqrt, abs&#xff1b;type类型包括void, int, double, float, char&#xff1b;运算符(算术、关系、逻辑、位)&#xff1b;需要识别的其他单词有标识符, 整数&#xff08;十进制形式、指数形式&#xff09;&#xff0c;实数&#xff08;十进制形式、指数形式&#xff09;&#xff0c;字符串&#xff08;输出类型名为string&#xff09;&#xff1b;过滤注释及空格。
【评分标准】根据设计文档的质量、lex文件的正确性&#xff0c;代码的正确性、代码的时间空间复杂度、识别单词的种类等综合评分
在这里插入图片描述

实现代码&#xff1a;

#include
#include
#include
#include using namespace std;vector<string> keyword &#61; {"scanf", "printf", "if", "else", "for", "while", "return", "do", "main", "abs", "sqrt"};
vector<string> type &#61; {"int", "void", "char", "double", "short", "float"};
vector<char> bracket &#61; {&#39;,&#39;, &#39;\\&#39;, &#39;;&#39;, &#39;:&#39;, &#39;(&#39;, &#39;)&#39;, &#39;[&#39;, &#39;]&#39;, &#39;{&#39;, &#39;}&#39;, &#39;"&#39;, &#39;\&#39;&#39;};struct Node
{int line &#61; 0;string type;string word;
};vector<Node> stack;
int line &#61; 1;
char text[int(1e5)] &#61; "";
char ch &#61; &#39; &#39;;
int len &#61; 0;
int i &#61; 0;
string word;
Node temp;void makeword(string s)
{temp.line &#61; line;temp.type &#61; s;temp.word &#61; word;stack.push_back(temp);word.clear();
}void JudgeE()
{word &#43;&#61; ch;ch &#61; text[&#43;&#43;i];if (ch &#61;&#61; &#39;&#43;&#39; || ch &#61;&#61; &#39;-&#39;){word &#43;&#61; ch;ch &#61; text[&#43;&#43;i];}if (ch >&#61; &#39;1&#39; && ch <&#61; &#39;9&#39;){word &#43;&#61; ch;while ((ch &#61; text[&#43;&#43;i]) && (ch >&#61; &#39;0&#39; && ch <&#61; &#39;9&#39;))word &#43;&#61; ch;makeword("float");}else{cout << "Error at Line " << line << ": Illegal floating point number \"" << word << "\".\n";exit(-1);}
}void jump()
{while (ch &#61;&#61; &#39; &#39; || ch &#61;&#61; &#39;\n&#39;){if (ch &#61;&#61; &#39;\n&#39;)line&#43;&#43;;ch &#61; text[&#43;&#43;i];}
}void makenumber()
{while (ch >&#61; &#39;0&#39; && ch <&#61; &#39;9&#39;){word &#43;&#61; ch;ch &#61; text[&#43;&#43;i];}if (ch &#61;&#61; &#39;.&#39;){word &#43;&#61; ch;ch &#61; text[&#43;&#43;i];while (ch >&#61; &#39;0&#39; && ch <&#61; &#39;9&#39;){word &#43;&#61; ch;ch &#61; text[&#43;&#43;i];}if (ch &#61;&#61; &#39;e&#39;)JudgeE();elsemakeword("decimal");}else if (ch &#61;&#61; &#39;e&#39;)JudgeE();elsemakeword("integer");
}void fun()
{ch &#61; text[i];jump();while (ch !&#61; &#39;\0&#39; && ch !&#61; EOF){jump();if (ch &#61;&#61; &#39;&#43;&#39; || ch &#61;&#61; &#39;-&#39;){word &#43;&#61; ch;ch &#61; text[&#43;&#43;i];if (ch &#61;&#61; &#39;&#61;&#39;){word &#43;&#61; ch;makeword("OPT");ch &#61; text[&#43;&#43;i];}elsemakenumber();}if (ch >&#61; &#39;0&#39; && ch <&#61; &#39;9&#39;){word &#43;&#61; ch;ch &#61; text[&#43;&#43;i];makenumber();}if (isalnum(ch) || ch &#61;&#61; &#39;_&#39;){while (isalnum(ch) || ch &#61;&#61; &#39;_&#39;){word &#43;&#61; ch;ch &#61; text[&#43;&#43;i];}if (find(keyword.begin(), keyword.end(), word) !&#61; keyword.end())makeword("keyword");else if (find(type.begin(), type.end(), word) !&#61; type.end())makeword("type");elsemakeword("identify");}if (ch &#61;&#61; &#39;/&#39;){char temp &#61; text[&#43;&#43;i];if (temp &#61;&#61; &#39;/&#39;)do{ch &#61; text[&#43;&#43;i];} while (ch !&#61; &#39;\n&#39;);else if (temp &#61;&#61; &#39;*&#39;){do{ch &#61; text[&#43;&#43;i];} while (ch !&#61; &#39;/&#39;);ch &#61; text[&#43;&#43;i];}else if (temp &#61;&#61; &#39;&#61;&#39;){word &#43;&#61; "/&#61;";makeword("OPT");ch &#61; text[&#43;&#43;i];}else{word &#43;&#61; &#39;/&#39;;makeword("OPT");ch &#61; text[&#43;&#43;i];}}if (ch &#61;&#61; &#39;0&#39;){word &#43;&#61; ch;ch &#61; text[&#43;&#43;i];makeword("integer");}if (ch &#61;&#61; &#39;%&#39; || ch &#61;&#61; &#39;&&#39;){if (isalnum(text[i&#43;1])){word &#43;&#61; ch;word &#43;&#61; text[&#43;&#43;i];ch &#61; text[&#43;&#43;i];makeword("typeidentify");}}if (find(bracket.begin(), bracket.end(), ch) !&#61; bracket.end()){word &#43;&#61; ch;ch &#61; text[&#43;&#43;i];makeword("bracket");}if (ch &#61;&#61; &#39;*&#39; || ch &#61;&#61; &#39;&#61;&#39; || ch &#61;&#61; &#39;<&#39; || ch &#61;&#61; &#39;>&#39; || ch &#61;&#61; &#39;!&#39;){word &#43;&#61; ch;if (text[i &#43; 1] &#61;&#61; &#39;&#61;&#39;)word &#43;&#61; text[&#43;&#43;i];ch &#61; text[&#43;&#43;i];makeword("OPT");}}
}int main()
{text[len] &#61; getchar();while (text[len] !&#61; &#39;\0&#39; && text[len] !&#61; EOF){text[&#43;&#43;len] &#61; getchar();}fun();for (vector<Node>::iterator iter &#61; stack.begin(); iter !&#61; stack.end(); iter&#43;&#43;)cout << "line" << (*iter).line << ":(" << (*iter).type << ", " << (*iter).word << &#39;)&#39; << endl;
}


推荐阅读
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • 如何查询zone下的表的信息
    本文介绍了如何通过TcaplusDB知识库查询zone下的表的信息。包括请求地址、GET请求参数说明、返回参数说明等内容。通过curl方法发起请求,并提供了请求示例。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • 本文介绍了GTK+中的GObject对象系统,该系统是基于GLib和C语言完成的面向对象的框架,提供了灵活、可扩展且易于映射到其他语言的特性。其中最重要的是GType,它是GLib运行时类型认证和管理系统的基础,通过注册和管理基本数据类型、用户定义对象和界面类型来实现对象的继承。文章详细解释了GObject系统中对象的三个部分:唯一的ID标识、类结构和实例结构。 ... [详细]
  • linux进阶50——无锁CAS
    1.概念比较并交换(compareandswap,CAS),是原⼦操作的⼀种,可⽤于在多线程编程中实现不被打断的数据交换操作࿰ ... [详细]
  • C语言自带的快排和二分查找
    Author🚹:CofCaiEmail✉️:cai.dongjunnexuslink.cnQQ😙:1664866311personalPage&#x ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 电话号码的字母组合解题思路和代码示例
    本文介绍了力扣题目《电话号码的字母组合》的解题思路和代码示例。通过使用哈希表和递归求解的方法,可以将给定的电话号码转换为对应的字母组合。详细的解题思路和代码示例可以帮助读者更好地理解和实现该题目。 ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了Windows Vista操作系统中的用户账户保护功能,该功能是为了增强系统的安全性而设计的。通过对Vista测试版的体验,可以看到系统在安全性方面的进步。该功能的引入,为用户的账户安全提供了更好的保障。 ... [详细]
  • 简述在某个项目中需要分析PHP代码,分离出对应的函数调用(以及源代码对应的位置)。虽然这使用正则也可以实现,但无论从效率还是代码复杂度方面考虑ÿ ... [详细]
author-avatar
fover黄瓜小妞1
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有