手写一个词法分析器(0)

您所在的位置:网站首页 用getchar函数读入 手写一个词法分析器(0)

手写一个词法分析器(0)

2023-06-17 18:52| 来源: 网络整理| 查看: 265

在开始手写词法分析器之前呢,我们得先准备好一些零件,规划好将要使用哪些函数,如果函数没有现成的,那还得自己写。

输入

由于我们需要从流中读出,有时还需要放回流,词法分析器显然每次读入都是按字符读入,所以使用getchar函数一般没有问题,然后对于放回流,C中提供了一个ungetc的后悔函数,首先先来尝试一下这个函数:

int main() { char t; t = getchar(); cout {0, 0, 0, 0, 0}, {2, 3, 4, 0, 0}, {0, 0, 4, 0, 0}, {0, 0, 4, 0, 0}, {0, 0, 4, 5, 7}, {0, 0, 6, 0, 0}, {0, 0, 6, 0, 7}, {8, 9, 10, 0, 0}, {0, 0, 10, 0, 0}, {0, 0, 10, 0, 0}, {0, 0, 10, 0, 0}};

根据状态转移表完成编程:

string num() // 输入一个数字字符串 { string s; char t; int status = 1; int last_status; while(1){ t = getchar(); switch (t) { case '+': last_status = status; status = st[status][0]; break; case '-': last_status = status; status = st[status][1]; break; case '.': last_status = status; status = st[status][3]; break; case 'E': last_status = status; status = st[status][4]; break; case 'e': last_status = status; status = st[status][4]; break; default: if(isdigit(t)) { last_status = status; status = st[status][2]; } else { last_status = status; status = 0; } break; } if(!status) { ungetc(t, stdin); break; } s += t; } status = last_status; if(status != 4 && status != 6 && status != 10) return ""; return s; }

结果测试:

edf72a06d022af4280c5cf3d772eabf2.png

于是乎我们又实现了一个有限状态自动机,从而实现了数字字符串的输入。

子问题3:将输入分割为小字符串

要实现将输入分割为小字符串,且向前看的步长仅为1步。首先我们需要分析出究竟在什么时候,才应该将他们分开。

1) 以下划线、字母开头,使用Trie树搜索;

2) 以+ -开头,再看一步为数字,放回加减后使用DFA搜索;

3) 除+ -专用符号开头,使用Trie树搜索;

4) 注释符号开头,一直接收到遇到注释尾。

子问题4:处理注释

此处做一个简化,不考虑注释中的转义字符,匹配到 */ 则结束。

string comments() { string s; char last_c, c; while(last_c != '*' || c != '/') { last_c = c; c = getchar(); s += c; } return s; }

验证:

03ee73d72ecef22acc557f48927d637f.png

可以看到,它自动截取了注释的前面部分。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3