Geekerstar

编译原理实验(一)词法分析器的设计
1 概述通过某种高级语言(如C/C++,Java)实现词法分析器的功能。1.1 实验目标1.理解并掌握词法分析的原...
扫描右侧二维码阅读全文
18
2018/02

编译原理实验(一)词法分析器的设计

1 概述

通过某种高级语言(如C/C++,Java)实现词法分析器的功能。

1.1 实验目标

1.理解并掌握词法分析的原理与方法

2.能够使用某种语言实现词法分析程序。

3.对编译的基本概念,原理和方法有完整和清楚的理解,并能正确而熟练的运用。

1.2 实验描述

1.2.1 实验要求

选用某种语言(如C/C++)实现词法分析程序。词法分析程序的主要任务如下:

  1. 识别出输入的源程序中的单词,输出二元组形式的单词序列。
  2. 删除无用的空白字符、回车符等没有实质意义的字符。
  3. 删除注释。

1.2.2 实验步骤

  • PL/0语言文法的EBNF表示如下:

<程序>::=begin<语句串>end

<语句串>::=<语句>{;<语句>}

<语句>::=<赋值语句>

<赋值语句>::=ID:=<表达式>

<表达式>::=<项>{+<项> | -<项>}

<项>::=<因子>{*<因子> | /<因子>

<因子>::=ID | NUM | (<表达式>)

  • 设计单词种别表
单词符号种别编码
Begin1
If2
Then3
While4
Do5
End6
标识符10
数字20
+13
-14
*15
/16
:17
:=18
<20
<>21
<=22
>23
>=24
=25
;26
(27
)28
#0

2.状态图

状态图

图1 状态图

试验流程图

图2 实验流程图

2 技术分析

2.1 词法分析

词法分析器根据词法规则识别出源程序中的各个记号,每个记号代表一类单词。源程序中常见的记号可以归为几大类:关键字、标识符、字面量和特殊符号。词法分析器的输入是源程序,输出是识别的记号流。词法分析器的任务是把源文件的字符流转换成记号流。它是编译过程的第一个阶段。其主要任务是从左到右依次描描字符串形式的源程序的各个字符,逐个识别出其中的单词,并将其转换成为内部编码形式的单词符号串输出,用于进行语法分析。

概括的说,语法器在其工作过程中,一般应完成下列的任务:

(1)识别出源程序中的各个单词符号,并将其转换成内部编码形式;

(2)删除无用的空白字符、回车字符以及其他非实质性字符;

(3)删除注释;

(4)进行词法检查,报告所发现的错误。

此外,视编译工作流程的组织,一些编译程序在进行词法分析时,还要完成将所识别出的标志符登录到符号表的工作。

3 设计与实现

3.1 设计思路

程序的关键点在于对给出一段程序中的各种单词的分离。在每段程序中,单词种类可以分为:关键字,分界符,算术运算符,关系运算符,标识符和常数。关键字的判断则是通过与已知数组中列出的元素进行对比,得出该单词是否为关键字;分解符,算术运算符,关系运算符的判断与接受到的字符进行比较,得出该字符是否为分解符,算术运算符或者为关系运算符。

3.2 实现方法

本次实验是设计词法分析器,其中核心函数是cifa(),分析的语言是PL/0,首先,采用循环遍历的方法读取用户输入的一段代码,跳过源程序中的空格字符,然后if语句配合switch语句对读入的代码挨个判断,最后以二元组的形式输出结果。

5f6c4bd0adbcfe0a243b94286ace797c.png

图3 词法分析核心代码

3.3 测试用例

项目/软件词法分析器程序版本V1.0
功能模块名词法分析模块编制人XX
用例编号T1.0编制时间207.10.27
功能特性词法定义分析判断
测试目的判断词法是否正确
测试数据1:begin a:=4;b:=2*3;c:=a+b;end 2:a:=2;b:=2*3;c:=a+b;end: 3:begin a:=4;b:=2*3;c:=a+b;
测试用例操作描述代码期望结果实际结果测试状态
1输入第一段代码begin a:=4;b:=2*3;c:=a+b; end(begin,1) (a,10) (:=,18) (4,20) (;,26) (b,10) (:=,18) (2,20) (*,15) (3,20) (;,26) (c,10) (:=,18) (a,10) (+,13) (b,10) (;,26) (end,6)(begin,1) (a,10) (:=,18) (4,20) (;,26) (b,10) (:=,18) (2,20) (*,15) (3,20) (;,26) (c,10) (:=,18) (a,10) (+,13) (b,10) (;,26) (end,6)良好
2输入第二段代码a:=2;b:=2*3;c:=a+b;end缺少Begin缺少begin良好
3输入第三段代码begin a:=4;b:=2*3;c:=a+b;缺少结束符缺少结束符良好

3.4 实验结果及分析

当我们输入PL/0代码:begin a:=4;b:=2*3;c:=a+b;
end,词法分析以二元组的形式输出以下结果:

试验结果图

图3 实验结果图

根据以上实验结果,基本判断词法分析程序正确运行,成功将输入的代码以二元组的形式输出。

4 总结

经过本次实验,我对词法分析器有了更近一步的理解,让我了解到如何设计、编制并调试词法分析程序,对编译的基本概念,原理和方法有完整和清楚的理解,并能正确的运用。实验目前还不够完善,存在不少问题,有待改善。

5 参考文献

1.互联网:百度,CSDN博客。

2.教材:《编译技术》张莉 高等教育出版社。

3.教材:C++ primer plus(第六版)

6 代码展示

#include "cstdio"
#include "string"
#include "iostream"
#include "algorithm"
#include "cstring"
using namespace std;

char str[1000];            //从键盘输入
char bzf[8];      //判断是否是关键字
char ch;
char *keyword[6]={"begin","if","then","while","do","end"};
int num,p,m,n,sum;
int x;
void cifa()   //词法分析
{
    sum=0;
    for(m=0;m<8;m++)
        bzf[m++]=NULL;
    m=0;
    ch=str[p++];
    while(ch==' ')       //去掉空格
        ch=str[p++];
    if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A')))  //标识符
    {
        while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9')))
        {
            bzf[m++]=ch;
            ch=str[p++];
        }
        p--;
        num=10;
        bzf[m++]='\0';
        for(n=0;n<6;n++)
        if(strcmp(bzf,keyword[n])==0)
        {
            num=n+1;
            break;
        }
    }
    else if((ch>='0')&&(ch<='9'))  //数字
    {
        while((ch>='0')&&(ch<='9'))
        {
            sum=sum*10+ch-'0';
            ch=str[p++];
        }
        p--;
        num=11;
    }
    else
    switch(ch)     //符号
    {
        case '<':
            m=0;
            ch=str[p++];
            if(ch=='>')
            {
                num=21;
            }
            else if(ch=='=')
            {
                num=22;
            }
            else
            {
                num=20;
                p--;
            }
        break;

        case '>':
            m=0;
            ch=str[p++];
            if(ch=='=')
            {
                num=24;
            }
            else
            {
                num=23;
                p--;
            }
        break;

        case ':':
            m=0;
            ch=str[p++];
            if(ch=='=')
            {
                num=18;
            }
            else
            {
                num=17;
                p--;
            }
            break;

        case '+':
            num=13;
        break;

        case '-':
            num=14;
        break;

        case '*':
            num=15;
        break;

        case '/':
            num=16;
        break;

        case '(':
            num=27;
        break;

        case ')':
            num=28;
        break;

        case '=':
            num=25;
        break;

        case ';':
            num=26;
        break;

        case '#':
            num=0;
        break;

        default:
            num=-1;
        break;
    }
}
int main()
{
    p=x=0;
    printf("词法分析结果\n");
    do
    {
        scanf("%c",&ch);
        str[p++]=ch;
    }while(ch!='#');
    p=0;
    cifa();
    return 0;
}

版权声明:本文为原创文章,版权归 Geekerstar 所有。

本文链接:http://www.geekerstar.com/technology/92.html

除了有特殊标注文章外欢迎转载,但请务必标明出处,格式如上,谢谢合作。

最后修改:2018 年 02 月 25 日 11 : 50 AM
如果觉得我的文章对你有用,请随意赞赏

发表评论