ROOT
ROOT
文章目录
  1. 词法分析器底层部分
    1. 匹配 关键字 或标记符 自动机
    2. 匹配 无符号数 自动机
    3. 匹配 行间注释 自动机
    4. 匹配 运算符 、 分界符 自动机
    5. 匹配 字符 、 字符串 自动机
  2. 词法分析器前端部分

编译原理之词法分析器设计

这两天把编译原理词法分析实验提前给做了,作品地址:http://115.159.147.250:666/Lexical/,源码:https://github.com/netcan/compilingTheory,效果图: https://raw.githubusercontent.com/netcan/compilingTheory/master/lexical.gif

现在来记录下编写心得,这是编译原理的第一个实验,算是热身实验吧,确实很简单,花了一晚上就把词法分析器底层部分写完了,老师比较喜欢图形界面,后来又加了前端,也就是现在看到的效果。实验要求能够匹配出 关键字 、 标记符 、 运算符 、 分界符 、 无符号数 ,后来我又添加了一部分,现在能匹配出 字符 / 字符串 、 行间注释。

词法分析器底层部分

底层部分是用 C++ 写的,大体思路就是,每次从 stdin 读取出一行,然后从这行的第一个字符开始匹配。匹配完了,读取下一行,行号 +1。

匹配 关键字 或标记符 自动机

若当前匹配到的字符 是字母 ,就继续匹配下一个字符,直到下个字符 不是 字母 或者 数字 或者’_'为止,则截取字符串 ,判断这个字符串是不是 关键字 或者 标记符 ,否则 错误 处理。如果是 标记符 ,将其存入 标记符 表中,其在 标记符 表的位置即为其Pointer。最后输出相关信息。

匹配 无符号数 自动机

若当前匹配到的字符 是数字 ,就继续匹配下一个字符,直到下个字符 不是 字母 或者 数字 或者’_'为止,则截取字符串 ,判断这个字符串是不是 无符号数 。如果是 无符号数 ,将其存入 常数 表中,其在 常数 表的位置即为其 Pointer,若不是 无符号数 则当 错误 处理。最后输出相关信息。

匹配 行间注释 自动机

若当前匹配到的字符 是’/‘并且下一个字符也是’/’,就继续匹配下一个字符,直到下个字符 不是 空白(空格或 tab)为止,则截取字符串,作为注释处理。

匹配 运算符 、 分界符 自动机

我将 运算符 和分界符 放到一个 optrs 表中,若当前匹配到的字符 是optrs的元素,就继续匹配下一个字符,直到下个字符 不是 optrs 的元素或者运算符类型与字符 不一样或者就是分界符为止,则截取字符串 ,判断这个字符串是不是optrs 的元素,并确定其类型,其 Pointer 为该 运算符 或分界符 在optrs的位置,输出相关信息,否则当 错误 处理。最后输出相关信息。

匹配 字符 、 字符串 自动机

若当前匹配到的字符 是"或者 ',就继续匹配下一个字符,直到下个字符 是字符 为止,则截取字符串 ,判断这个字符串是 字符 还是 字符串 。如果是的话,将其存入 字符 或字符串 表中,其在相应表的位置即为其 Pointer,若不符合则 错误 处理。最后输出相关信息。

词法分析器前端部分

前端部分我比较认真,我用 html+js+php 来实现图形界面,之所以写成网页,是因为我不想写 native app,我也没GUI 开发环境。在互联网时代,webapp是趋势,谁还写本地客户端啊,况且带个几十 M 的 GUI 库实在是麻烦。

于是我的分析器底层部分设计成输出 json 格式,然后利用管道将 C++ 程序与 php 程序进行数据传送。前端只要用 js 输数据取数据渲染页面即可。

在这之中发现一个问题,如果 输入文本 一长,渲染效率大大降低,因为我用 append 方法一个个加元素的。解决方案是最后转换为字符串一次性输出渲染,效率提高了不少。具体可看这个优化片段:优化 js 运行效率。

支持一下
扫一扫,支持Netcan
  • 微信扫一扫
  • 支付宝扫一扫