C-- 语言词法分析器:使用 GNU Flex 和 C 语言实现
使用 GNU Flex 和 C 语言实现 C-- 语言词法分析器
本文将介绍如何使用 GNU Flex 词法分析工具编写一个词法分析器,用于识别 C-- 语言源代码中的词法错误。
实验要求
你的程序需要能够查出源代码中可能包含的词法错误:
- 词法错误(错误类型 A): 出现 C-- 词法中未定义的字符,以及任何不符合 C-- 词法单元定义的字符。
输入格式
程序的输入是一个包含 C-- 源代码的文本文件,程序需要能够接收一个输入文件名作为参数。例如,假设你的程序名为 cc、输入文件名为 test1,程序和输入文件都位于当前目录下,那么在 Linux 命令行下运行 ./cc test1 即可获得以 test1 作为输入文件的输出结果。
输出格式
-
对于包含词法错误的输入文件: 只需要输出相关的词法有误的信息,不要输出任何与语法树有关的内容。
- 输出信息包括:错误类型、出错的行号以及说明文字,格式为:
Error type [错误类型] at Line [行号]: [说明文字]。 - 错误类型和出错的行号必须正确,因为这是判断输出错误提示信息是否正确的唯一标准。
- 严格遵守实验要求中给定的错误分类,词法错误为错误类型 A。
- 输入文件中可能会包含一个或多个词法错误,但输入文件的同一行中保证不出现多个错误。程序需要将这些错误全部报告出来,每一条错误提示信息在输出中单独占一行。
- 输出信息包括:错误类型、出错的行号以及说明文字,格式为:
-
对于没有任何词法错误的输入文件: 程序需要打印每一个词法单元的名称以及与其对应的词素,无需打印行号。词法单元名与相应词素之间以一个冒号和一个空格隔开。每一条词法单元的信息单独占一行。
词法单元示例
| 词法单元 | 非正式描述 | 词素示例 |
|---|---|---|
| if | 字符 'i', 'f' | if |
| else | 字符 'e', 'l', 's', 'e' | else |
| comparison | '<' 或 '>' 或 '<=' 或 '>=' 或 '==' 或 '!=' | <=, != |
| id | 字母开头的字母 / 数字串 | Pi, score, D2 |
| number | 任何数字常量 | 3.14159, 0, 6.02e23 |
| literal | 在两个'之间,除'以外的任何字符 | 'core dumped' |
示例
- 在 C 语句
printf('Total = %d\n',score);中,printf和score都是和词法单元id的模式匹配的词素,而'Total = %d\n'则是一个和literal匹配的词素。
常见词法单元分类
在很多程序设计语言中,下面的类别覆盖了大部分或所有的词法单元:
- 关键字: 一个关键字的类型就是该关键字本身。
- 运算符: 它可以表示单个运算符,也可以表示一类运算符。
- 标识符: 一个表示所有标识符的词法单元。
- 常量: 一个或多个表示常量的词法单元,比如数字和字面值字符串。
- 界符: 每一个标点符号有一个词法单元,比如左右括号、逗号和分号。
样例
样例 1:
- 输入:
1 int main()
2 {
3 int i = 1;
4 int j = ~i;
5 }
- 输出:
程序存在词法错误,第 4 行中的字符'~' 没有在 C-- 词法中被定义过。因此你的程序可以输出如下的错误提示信息:
Error type A at Line 4: Mysterious character '~'.
样例 2:
- 输入:
1 int inc()
2 {
3 int i;
4 i =100;
5 }
- 输出:
程序没有词法错误,你的程序需要输出每一个词法单元信息:
TYPE: int
ID: inc
LP: (
RP: )
LC: {
TYPE: int
ID: i
SEMI: ;
ID: i
RELOP: =
INT: 100
SEMI: ;
RC: }
总结
本文介绍了如何使用 GNU Flex 编写一个词法分析器,用于识别 C-- 语言源代码中的词法错误。通过分析示例代码,读者可以理解词法单元的分类和识别方法,并根据实验要求编写自己的词法分析器。
原文地址: https://www.cveoy.top/t/topic/zCl 著作权归作者所有。请勿转载和采集!