本文是编译原理C语言词法分析器的简单实现项目。

一、需求

词法分析程序的设计和实现。

设计并实现C语言的词法分析程序,要求如下:

  1. 可以识别出用C语言编写的源程序中的每个单词符号,并以记号的形式输出每个单词符号。
  2. 可以识别并读取源程序中的注释。
  3. 可以统计源程序汇总的语句行数、各类单词的个数、以及字符个数,并输出统计结果。
  4. 检查源程序中存在的词法错误,并报告错误所在的位置。
  5. 对源程序中存在的错误进行适当的恢复,使词法分析可以继续进行,对源程序进行一次扫描即可检查并报告源程序中存在的所有词法错误。

二、运行环境

电脑硬件配置:

  • 处理器:Intel i7 7700HQ

  • 显卡:NVIDIA GeForce GTX 1050 Ti

  • 内存:16GB

软件:

  • 编程语言:C++

  • IDE:Microsoft Visual Studio 2019

  • Windows SDK版本:10.0

  • 平台工具集:Visual Studio 2019(v142)

三、核心算法

读入源程序,将源程序拆分为单词,同时去除空格和空行并存入vector中,一个字符一个字符的读入自动机,文件输出单词和类型,并在最后输出统计结果,在屏幕输出错误。

PS:不支持中文字符

源程序的记号和表达式:

  1. 标识符:字母或“_”开头,后跟字母或数字或“_”组成的符号串

  2. 关键字:标识符集合的子集。C语言有32个关键字,分别为:

    1
    2
    3
    "do","double","auto","break","case","char","const","continue","default","else","enum","extern",
    "float","for","goto","if","int","long","register","return","struct","switch","typedef","short",
    "signed","sizeof","static","union","unsigned","void","volatile","while"
  3. 数字:由整数部分、可选小数部分和可选整数部分构成

  4. 运算符:

    1
    . ( ) ~ & ^ % <= << < >= >> > = == / != ! && & || | -> - : ?
  5. 分隔符:

    1
    ; # ’ ” [ ] { } , 
  6. 转义符:\

状态转换图:

1 22

输入形式:

文件输入。

输出形式:

分两部分:文件输出和屏幕输出。文件输出分析内容,分四部分:按文件顺序输出类型和表达式,每种表达式数量统计,每种类型数量统计,行数、单词数、字符数统计;屏幕输出错误。详见输出样例部分。

四、变量和函数

点击查看代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
int start = 0, over = 0, first = 0;//指针
int letters = 0, lines = 0, words = 0;//统计单词数,行数和字符数的变量
int state;//状态变量

class str//单词类
{
public:
int linenum;//行号
string Str;//单词
};

//输出文件名
string file_name;

//返回单词或符号,从位置i开始查找,引用参数j返回这个单词最后一个字符在str的位置。
string GetWord(string str, int i, int& j);

//除去字符串中连续的空格和换行。第一个参数为目标字符串,第二个参数为开始位置。返回值为第一个有效字符在字符串的位置
int get_nbc(string str, int i);

//文件输出函数,成功输出返回true,失败返回false
bool Output(vector<pair<string, string> > v);

//词法分析主要算法函数,返回一个pair型数组
vector<pair<string, string> > analyse(vector<str>& vec);

//此函数判断str是否为关键字,是的话,返回真,反之返回假
bool IsKey(string str);

//此函数判断C是否为字母,是的话,返回真,反之返回假
bool letter(char C);

//此函数判断C是否为数字,是的话,返回真,反之返回假
bool digit(char C);

详细代码见文末github项目。

五、测试样例:

六、项目地址

本项目的源码、可执行程序均已经存放于我的Github,欢迎下载查看:

评论




博客内容遵循 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议

载入天数...载入时分秒...