使用 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); 中,printfscore 都是和词法单元 id 的模式匹配的词素,而 'Total = %d\n' 则是一个和 literal 匹配的词素。

常见词法单元分类

在很多程序设计语言中,下面的类别覆盖了大部分或所有的词法单元:

  1. 关键字: 一个关键字的类型就是该关键字本身。
  2. 运算符: 它可以表示单个运算符,也可以表示一类运算符。
  3. 标识符: 一个表示所有标识符的词法单元。
  4. 常量: 一个或多个表示常量的词法单元,比如数字和字面值字符串。
  5. 界符: 每一个标点符号有一个词法单元,比如左右括号、逗号和分号。

样例

样例 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-- 语言源代码中的词法错误。通过分析示例代码,读者可以理解词法单元的分类和识别方法,并根据实验要求编写自己的词法分析器。

C-- 语言词法分析器:使用 GNU Flex 和 C 语言实现

原文地址: https://www.cveoy.top/t/topic/zCl 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录