编译原理实验一:词法分析工具Flex

本文介绍如何使用词法分析工具Flex完成词法分析器的搭建,重点讲解词法单元的正则表达式及动作设置,并针对注释的处理进行了详细说明。通过实验设计与测试验证,展示了词法分析器的有效性和正确性。

编译原理实验一:词法分析工具Flex

实验要求

根据cminux-f的词法补全[lexical_analyer.l](../../src/lexer/lexical_analyzer.l)文件,完成词法分析器,能够输出识别出的token,type ,line(刚出现的行数),pos_start(该行开始位置),pos_end(结束的位置,不包含)。如:

文本输入:

 int a;

则识别结果应为:

int     280     1       2       5
a       285     1       6       7
;       270     1       7       8

实验难点

1.Flex的使用

将词素转换为词法单元有两种方式:第一种是手动用代码实现(需要画状态转移图辅助),另一种是使用词法分析器生成工具(需要使用正则表达式描述出词素的模式)。而Flex就是一个词法分析器生成工具。词法分析器工具的工作过程如下:

Lex源程序----->Lex编译器----->lex.yy.c
lex.yy.c-----> C编译器 ----->a.out
 输入流  -----> a.out	----->词法单元的序列

而Lex源程序的格式如下:

声明部分:变量的定义和声明,会直接复制到lex.yy.c中。
%%
转换规则:形式为:模式{
   
   动作},模式为正则表达式,动作则是代码片段。
%%
辅助函数:各个动作需要的辅助函数。用户自定义,直接复制到lex.yy.c末尾。

Lex中还有一些变量和函数,以下只给出了实验涉及的一部分:

  • yyin:FILE*,指向正在解析的文件。

  • yyout:FILE*,指向记录lexer输出的位置,缺省时yyin和yyout都指向标准输入和输出流。

  • yytext:char*,存储匹配模式的文本。

  • yylex():这一函数开始词法分析,由Lex自动生成。

  • yywrap():这一函数在文件或输入的末尾调用,返回值是1则停止解析。可以通过改变yyin指针指向不同文件,进行多文件的解析。

本实验主要是需要完成转换规则部分,给出cminux-f中词法单元的正则表达式和动作。

2.识别到词法单元的动作

运算符,符号,关键字,ID和NUM类型的词法单元在识别后,需要确定出现的行数,开始位置,结束的位置。出现的行数可以在识别到换行符时lines++实现,开始的位置为上一个识别的词法单元结束的位置,结束的位置为开始位置加上词素长度。最后返回token值结束完成一个词素的识别。因此识别到词法单元的动作如下:

RE {
   
   pos_start=pos_end;pos_end=pos_start+strlen(yytext);return token}

对于运算符,符号和关键字,长度是确定的,可以直接加上长度,不需要调用sterlen。

3.识别到特殊词法单元的动作

对于注释,空格,换行符,只需要进行识别,不需要输出到分析结果中。这些token与程序运行无关。其中空格对接下来的词法单元无影响,与一般词法单元的动作相同;识别到换行符需要将lines++,并将开始位置置1;识别到注释时,由于注释中内容全部都与程序无关,需要判断注释中是否含有换行符,并将lines加上换行符的个数。因此在识别到这些词法单元时,处理如下:

    int len;
	while(token = yylex()){
   
   
        switch(token){
   
   
            case COMMENT:
                len = strlen(yytext);
                for(int i=0;i<len;i++){
   
   
                    if(yytext[i]=='\n') {
   
   
                        lines++;
                        pos_end = 1;	//pos_start由pos_end得到,这里就不需要置1了
                    }
                    else pos_end++;
                }
                break;
            case BLANK:
                break;
            case EOL:
                lines++;
                pos_end = 1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值