时间:2019/11/29

首先,词法分析器由一个扫描器与状态机组成。

一. 词法分析器整体设计流程

  

二、设计细节

1. code.txt:

  我们假设读取下面文本

  

2.符号类型的设计

  我们使用 enum 数据结构,其好处有两点:

  1. 只能选取其成员中的一个。

  2. 可以直接用符号的名字命名变量。  

 enum symbol {
KW_MAIN, KW_IF, KW_ELSE, KW_WHILE, KW_INT, KW_COUT, KW_CIN, KW_ENDL, KW_RETURN, // 关键字
LBRACE, RBRACE, LPAREN, RPAREN, SEMI, COMMA, // 界符
ASSIGN, ADD, MINUS, TIMES, DIVIDE, // 运算
EQ, NE, G, GE, B, BE, IN, OUT, // 判断标志位
STR, NUM, ID, // 字符串,数字,标识符
END // 文件结尾
};

3. 扫描器

  扫描器会仅仅读取一个字符,先将旧的字符保存,再将读取的字符存储在全局变量ch中,如果读取成功,返回0,否则返回1.

 int getCh() {
oldch = ch;
if (fscanf_s(fin, "%c", &ch) == EOF) {
return ;
}
else {
return ;
}
}

4.有限状态机:

  其通过当前所读取的字符 ch 来判断其种类。

  1)数字:比如如果为 '0',则表示数字,依次"读取-计算-存储"直到不是数字时再退出,将值保存在num中,sym赋值NUM,之后返回。

     else if(ch>='' && ch<='')
{
int value = ;
do {
value = value * + ch -'';
f = getCh();
} while (ch >= '' && ch <= ''); // 判断条件一定要明确 sym = NUM;
num = value; }

  2) ‘=’ 与 ‘==’的区分:当遇到 = 时,超前读取一个字符,来判断。 如果是 == ,在继续读取一个字符(供之后判断使用),否则不用读取。

 case '=':
f = getCh();
if (ch == '=') {
sym = EQ;
// 再往前读一行
f = getCh();
}
else {
sym = ASSIGN;
}
break;

  3) 变量名 与 关键字之前的区分:我们设计了一个数组,当为 变量名或关键字时进行判断。

 /*
关键字检索器:将标识符与id区分开来,并打上标记 sym;
*/
const int arrLen = ;
const char * keyWords[arrLen] = { "main","if","else","while","int","cout","cin","endl","return" };
const enum symbol keySymbols[arrLen] = { KW_MAIN, KW_IF, KW_ELSE, KW_WHILE, KW_INT, KW_COUT, KW_CIN, KW_ENDL, KW_RETURN }; void checkKeyWord() {
// 将id来遍历 keyWords[] 数组,打上标签
int flag = ; // 标记是否是关键字
for (int i = ; i < arrLen; i++) {
if (strcmp(id, keyWords[i]) == ) {
sym = keySymbols[i]; // 完成赋值
flag = ;
break;
}
}
if (flag == )
sym = ID;
}

三、验证检查的可靠性

1. 我们先简单地写了一下测试代码:

    //
// 测试词法扫描器
// string filename = "C:\\Users\\97905\\source\\repos\\T编译器\\Debug\\abc.txt";
int ErrorCode = fopen_s(&fin, filename.c_str(), "r");
if ( == ErrorCode) {
cout << "打开文件成功" << endl;
}
else {
cout << "错误码: " << ErrorCode << endl;
return ;
}
// 循环解析符号
getCh(); // 启动时必须先读取第一个字符
while (getSym()) {
if (sym == STR) {
// 输出字符串
cout << "(string," << str << ")"<< endl;
}
else if (sym == NUM) {
// 输出数字
cout << "(NUM," << num << ")" << endl;
}
else if (sym == ID) {
cout << "(ID," << id << ")" << endl;
}
else {
cout <<"(关键字或字符," << symbolName[sym] <<")" << endl;
}
}
if (sym == END) {
cout << "文件读取结束" << endl;
} return ;

2. 将上面那个代码填入进去,最终的测试结果如下。

符合测试要求

四、下一步计划

  写一个简单的 "int i;" 与 "i = 3;"的 语法分析程序 与 语义分析程序。

  "int i;" 时建立变量记录表

  "i = 3;" 时在变量表中查询变量,并且赋值。

  这个计划用 MAP 数据结构来实现(毕竟查找比较方便)

  预计更新日期:2019/11/30

【编译系统01】编译器 - 词法分析器(lexial)的设计思路的更多相关文章

  1. (原创)通用查询实现方案(可用于DDD)[附源码] -- 设计思路

    [声明] 写作不易,转载请注明出处(http://www.cnblogs.com/wiseant/p/3988592.html).   [系列文章] 通用查询实现方案(可用于DDD)[附源码] -- ...

  2. RBAC角色权限设计思路

    1 设计思路 为了设计一套具有较强可扩展性的用户认证管理,需要建立用户.角色和权限等数据库表,并且建立之间的关系,具体实现如下. 1.1 用户 用户仅仅是纯粹的用户,用来记录用户相关信息,如用户名.密 ...

  3. FPGA Asynchronous FIFO设计思路

    FPGA Asynchronous FIFO设计思路 将一个多位宽,且在不停变化的数据从一个时钟域传递到另一个时钟域是比较困难的. 同步FIFO的指针比较好确定,当FIFO counter达到上限值时 ...

  4. selenium 关键字驱动部分设计思路

    1 说明: 1.以下的代码亲测直接可用, 2.设计思路来自博客园的 张飞_ :http://www.cnblogs.com/zhangfei/p/5330994.html   /   http://w ...

  5. Sizzle源码分析:一 设计思路

    一.前言 DOM选择器(Sizzle)是jQuery框架中非常重要的一部分,在H5还没有流行起来的时候,jQuery为我们提供了一个简洁,方便,高效的DOM操作模式,成为那个时代的经典.虽然现在Vue ...

  6. 通用查询实现方案(可用于DDD)[附源码] -- 设计思路

    原文:通用查询实现方案(可用于DDD)[附源码] -- 设计思路 [声明] 写作不易,转载请注明出处(http://www.cnblogs.com/wiseant/p/3988592.html).   ...

  7. TYPESDK手游聚合SDK服务端设计思路与架构之一:应用场景分析

    TYPESDK 服务端设计思路与架构之一:应用场景分析 作为一个渠道SDK统一接入框架,TYPESDK从一开始,所面对的需求场景就是多款游戏,通过一个统一的SDK服务端,能够同时接入几十个甚至几百个各 ...

  8. 分享一个CQRS/ES架构中基于写文件的EventStore的设计思路

    最近打算用C#实现一个基于文件的EventStore. 什么是EventStore 关于什么是EventStore,如果还不清楚的朋友可以去了解下CQRS/Event Sourcing这种架构,我博客 ...

  9. ENode框架单台机器在处理Command时的设计思路

    设计目标 尽量快的处理命令和事件,保证吞吐量: 处理完一个命令后不需要等待命令产生的事件持久化完成就能处理下一个命令,从而保证领域内的业务逻辑处理不依赖于持久化IO,实现真正的in-memory: 保 ...

随机推荐

  1. 5G技术发展迅猛,亚博电竞(yabo055)搭上科技快车

    要说当前互联网科技最为令人期待的当属yabo055点康母的5G技术了.自2018年5G标准确定以来,民众就对5G非常的期待,而亚博电竞早已意识到了5G时代的来临势不可挡,早已着手将5G运用于网站和游戏 ...

  2. Map随笔:最常用的Map——HashMap

    目录 Map随笔:最常用的Map--HashMap 前言: 1,HashMap的结构 2,HashMap的一些属性(JDK8) 3,HashMap的构造函数(JDK8) 4,HashMap的一些方法( ...

  3. mysql DDL 锁表

    mysql DDL 锁表 select trx_state, trx_started, trx_mysql_thread_id, trx_query from information_schema.i ...

  4. adb devices无法连接mumu模拟器

    解决方案: 如果你的android环境能够直接访问 adb 的相关指令.只需要把mumu模拟器打开 然后打开cmd -> 输入 adb connect 127.0.0.1:7555 就能直接连上 ...

  5. chrome 插件备份

  6. Python爬虫实战教程:爬取网易新闻

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: Amauri PS:如有需要Python学习资料的小伙伴可以加点击 ...

  7. Ajax:实现后台验证js实现get方式的异步请求,判断用户名是否重复

    <%@ page contentType="text/html;charset=UTF-8" language="java" %><html& ...

  8. SSM框架之SpringMVC(2)参数绑定及自定义类型转换

    SpringMVC(2)参数绑定及自定义类型转换 1.请求参数的绑定 1.1. 请求参数的绑定说明 1.1.1.绑定机制 表单提交的数据都是k=v格式的 username=haha&passw ...

  9. AudioRecord 录制播放PCM音频

    AudioRecord 与 MediaRecorder 区别 AudioRecord 基于字节流录制,输出的是pcm数据,未进行压缩,直接保存的pcm文件不能被播放器识别播放. 可以对音频文件进行实时 ...

  10. Flutter学习笔记(6)--Dart流程控制语句

    如需转载,请注明出处:Flutter学习笔记(5)--Dart流程控制语句 条件语句:if.if...elseif.if...elseif...else ; ) { print('优秀'); } &g ...