实验报告:词法分析器

实验报告:词法分析器

一些基本概念:

  1. lex:词法分析器的自动产生系统
    lex.exe将lex源程序转换成lex.yy.c文件(由命令flex xxx.lex执行)
    编译lex.yy.c生成可执行文件,该可执行文件即可将源语言程序切割为单词符号串
  2. lex源程序的识别规则:由正规式和相应的动作组成
    格式:在一行中以“正规式 动作”形式书写,动作用大括号括起
  3. 关于yylex()函数
    作用:调用yylex()启动或者重新开始扫描
    用户段代码:段中的所有代码都被拷贝到yylex()。以空白开始的行被假定是用户代码。"%%"后的代码直接放置在接近扫描程序的开始处,在第一条执行的语句之前。
  4. 输出的单词符号分类:
    K(关键字)I(标识符)C(常量,此处常量指整型)
    O(算符) D(界符) T(其他)
    F(浮点数)S(字符串)R(字符)
    A (整型数组)

实验思路:

  1. 设立一个结构体cell用于存储识别出的每一个单词及其属性,cell含有单词类,单词名,长度,行列数据。其实最后发现此处设置一个结构体并没有太大的用处,或者说在词法分析这一步完全不需要结构体,只有可能方便后续的操作
  2. 每次识别成功执行add_cell()函数,改函数根据传入参数(一个int类型的值)的不同为单词分类并确定该单词的行列数据,同时打印出相关的数据到“result.txt”

关于识别规则:

  1. 错误字符(即T类字符)的判定:
    ①含有非法字符的标识符,非法字符指 “?!$&#@`” 这些字符
    ②以数字开头的标识符
    ③含有一个以上浮点符号的浮点数
  2. 整型的判定:
    为方便表示,只保有interger和longint两个关键字,均为以 “+” 或 “-” 开头的0-9数字组成,或者是没有表示正负的符号

语言扩展:

  1. 支持字符、字符串类型及相关运算
    pascal对应的声明规则为 var a:string ,冒号后接变量的类型
    添加关键字 string char ;添加识别条件识别 ‘xxx’ 和 “xxx” 样式的语句,将字符串归为 S 类,字符归为 A 类
  2. 支持for循环语句:
    添加关键字 for to downto do
  3. 支持repeat语句:
    添加关键字 repeat until
  4. 支持浮点类型及相关运算:
    为方便表示,只保有单精度和双精度两类浮点数,因此添加关键字 single double;添加识别浮点数的语句并将其归为 F 类
  5. 支持整形数组(一维):
    pascal对应的声明规则为 var a:array[1…n] of interger 即 var 数组名:array[下标1…下标2] of 元素数据类型
    因此需要添加关键字 array of 以及数值类型(前文中已经添加)
    同时添加一个新的类型 A类 表示数组
    以上述数组声明为例,词法分析器最后的结果为
    var(K) a(I) :(D) array(K) 1…n of(K) interger(K)

遇到的问题:

  1. 文件指针(FILE*)在第一部分声明,在主函数中定义(在第一部分定义会报错我也不知道为什么。。。)
  2. 结构体中保存单词名的指针char* name只是粗略地将yytext的值传入并没有为该指针分配相应的空间(如果分配空间大小应为yyleng),后续如果用到了该指针需要注意其停止输出的部分
  3. 错误字符只能识别很有限的一部分(毕竟如果写代码的人乱写代码就会有很多句式识别不出来)
  4. 由于包含关系,为避免错误识别,非法的标识符以及关键字需要在标识符之前识别;char和string类需要在最开始识别,否则可能将字符串识别成标识符或者非法标识符
  5. 在用 . 表示除换行外字符时使用圆括号(),若使用方括号[]意思是 . 不表示任何字符而表示特定字符

Summary:

词法分析器的设计其实不需要过多的考虑语法和单词的属性,只需要将不同类单词的特点用正规式准确表示并将其分类同时记录单词的名字即可。对于不同的数据类型,无论数据类型如何,变量名一定是属于关键字一类,不同的数据本身再进行数据类型的分类,这样可以大大减少分词过程中的工作量,添加关键字也是如此。

发布了3 篇原创文章 · 获赞 0 · 访问量 66

猜你喜欢

转载自blog.csdn.net/AnthonyD7/article/details/105091201
今日推荐