• 实验一 词法分析程序实验


    实验一、词法分析程序实验

    商业软件工程   蓝海鹏  201506110171

    一、        实验目的

     

         编制一个词法分析程序。

    二、        实验内容和要求

    实验内容:

    1. 对字符串表示的源程序
    2. 从左到右进行扫描和分解
    3. 根据词法规则:

    单词符号

    种别码

    单词符号

    种别码

    begin

    1

    :

    17

    if

    2

    :=

    18

    then

    3

    20

    while

    4

    <=

    21

    do

    5

    <> 

    22

    end

    6

    23

    l(l|d)*(标识符)

    10

    >=

    24

    dd*(整数)

    11

    =

    25

    +

    13

    ;

    26

    -

    14

    (

    27

    *

    15

    )

    28

    /

    16

    #

    0

    1. 识别出一个一个具有独立意义的单词符号
    2. 以供语法分析之用
    3. 发现词法错误,则返回出错信息。

    实验要求:

    输入:源程序字符串

    输出:二元组(种别,单词符号本身)

    三、        实验方法、步骤及结果测试

    1. 1.      源程序名:压缩包文件(rarzip)中

    源程序名: 171蓝海鹏.c

    可执行程序名:171蓝海鹏.exe

    1. 2.      原理分析及流程图

    1)        存储结构:一维顺序数组存储。

    2)        算法关键定义:

    01. 定义全局变量syn存放单词种别码

    02. 定义数组prog存放整个字符串,数组token存放临时字符串

    03. 定义数组keyword存放关键字

    3)        流程图:

    4)        关键函数的实现:

    //获取字符串比较返回种别码

    void scaner()

        for(n=0;n<8;n++)//初始化token数组

        {token[n]='';}

        n=0;

        ch=prog[p++];

        while(ch==' ')

        {ch=prog[p++];}

        if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))//判断输入的是否为关键字

        {

               do{

                      token[n++]=ch;

                      ch=prog[p++];

               }while((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||(ch>='0'&&ch<='9'));

               syn=10;       

               for(n=0;n<6;n++)     //在六个关键字中对比

               {

                      if(strcmp(token,keyword[n])==0)

                             syn=n+1;

               }

               p--;

        }

        else if(ch>='0'&&ch<='9')//判断输入的是否为整数常数

        {

               p--;

               do

               {

                      token[n++]=prog[p++];

                      ch=prog[p];

               }while(ch>='0'&&ch<='9');

               syn=11;

               return;

        }

        else

        {

               switch(ch)

               {

               case '+':syn=13;token[0]=ch;break;

               case '-':syn=14;token[0]=ch;break;

               case '*':syn=15;token[0]=ch;break;

               case '/':syn=16;token[0]=ch;break;

               case ':':syn=17;token[0]=ch;

                      ch=prog[p++];

                      if(ch=='='){token[1]=ch;syn++;}

                      else p--;

                      break;

               case '<':syn=20;token[0]=ch;

                      ch=prog[p++];

                      if(ch=='>'){token[1]=ch;syn++;}

                      else if(ch=='='){token[1]=ch;syn=syn+2;}

                      else p--;

                      break;

               case '>':syn=23;token[0]=ch;

                      ch=prog[p++];

                      if(ch=='='){token[1]=ch;syn++;}

                      else p--;

                      break;

               case '=':syn=25;token[0]=ch;break;

               case ';':syn=26;token[0]=ch;break;

               case '(':syn=27;token[0]=ch;break;

               case ')':syn=28;token[0]=ch;break;

               case '#':syn=0;token[0]=ch;break;                

               default: printf("词法分析出错! 请检查是否输入非法字符 ");syn=-1;break;              

               }

        }

    }

    1. 3.      主要程序段及其解释:

    源代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define SIZE 100
    int p=0,syn,n,i;            //syn用于记录种别码,其为全局变量
    char prog[SIZE],ch,token[8];
    char *keyword[6]={"begin","then","if","while","do","end"};//定义关键字数组
    void scaner();      //将prog数组中的数移到token数组进行比较,更新种别码 
    main()
    {
        p=0;
        printf("请输入源程序字符串(以'#'结束):
    ");
        do
        {
            ch=getchar();
            prog[p++]=ch;
        }while(ch!='#');//将键盘输入的字符串录入数组prog
        p=0;    
        do
        {
            scaner();
            switch(syn)
            {
            case -1:printf("词法分析 出错
    ");break;
            default :printf("<%d,%s>
    ",syn,token);break;
            }    
        }while(syn!=0);//输入#号,种别码syn为0,循环结束
        printf("词法分析 成功
    ");    
        getchar();    
    }
    void scaner()
    {    
        for(n=0;n<8;n++)//初始化token数组
        {token[n]='';}
        n=0;
        ch=prog[p++];
        while(ch==' ')
        {ch=prog[p++];}    
        if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))//判断输入的是否为关键字
        {
            do{
                token[n++]=ch;
                ch=prog[p++];
            }while((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||(ch>='0'&&ch<='9'));
            syn=10;        
            for(n=0;n<6;n++)     //在六个关键字中对比
            {
                if(strcmp(token,keyword[n])==0)
                    syn=n+1;
            }
            p--;
        }
        else if(ch>='0'&&ch<='9')//判断输入的是否为整数常数
        {
            p--;
            do
            {
                token[n++]=prog[p++];
                ch=prog[p];
            }while(ch>='0'&&ch<='9');
            syn=11;    
            return;
        }
        else
        {
            switch(ch)
            {
            case '+':syn=13;token[0]=ch;break;
            case '-':syn=14;token[0]=ch;break;
            case '*':syn=15;token[0]=ch;break;
            case '/':syn=16;token[0]=ch;break;
            case ':':syn=17;token[0]=ch;
                ch=prog[p++];
                if(ch=='='){token[1]=ch;syn++;}
                else p--;
                break;
            case '<':syn=20;token[0]=ch;
                ch=prog[p++];
                if(ch=='>'){token[1]=ch;syn++;}
                else if(ch=='='){token[1]=ch;syn=syn+2;}
                else p--;
                break;
            case '>':syn=23;token[0]=ch;
                ch=prog[p++];
                if(ch=='='){token[1]=ch;syn++;}
                else p--;
                break;
            case '=':syn=25;token[0]=ch;break;
            case ';':syn=26;token[0]=ch;break;
            case '(':syn=27;token[0]=ch;break;
            case ')':syn=28;token[0]=ch;break;
            case '#':syn=0;token[0]=ch;break;            
            default: printf("词法分析出错! 请检查是否输入非法字符
    ");syn=-1;break;            
            }
        }
    }
    1. 4.      运行结果及分析

     

    分析:

    第1个字符串是关键字,顺序第1输出二元组(1,begin);

    第2个字符串是标识符,因为关键字为小写,其不为关键字,输出二元组(10,BEGIN);

    第3个字符串是由字母和数字组成的标识符,输出二元组(10,lan171);

    第4个字符串是整数,输出二元组(11,10);

    第5个字符串是符号,输出二元组(13,+);

    第6个字符串是结束,输出二元组(0,#);

    四、        实验总结

    刚刚接触编译原理这门课,其实很多概念不懂,课上也没有认真听课,这就做了一个实验,其实已经有了充足的时间准备。

    1. 通过本次实验,对词法分析程序的开发有了一定的认识;
    2. 在这次实验中,我对以前学习的C语言知识有了更深刻的认识。

    问题:在“读下一个字符“的时候遇到少读或多读一个字符的情况。

    (解决:通过多次调试将读字符的每种情况都考虑)

     

     

     

  • 相关阅读:
    Oracle函数应用与查询聚合统计
    Oracle子查询与分页查询
    DB2端口(转自百度文库http://wenku.baidu.com/view/47809b26aaea998fcc220e65.html)
    职场生涯
    git 管理多个私钥
    ubuntu 解压 windows 生成的 zip 文件乱码问题
    js实现类似于add(1)(2)(3)调用方式的方法
    webkit内核浏览器的CSS写法
    python 单例模式
    Javascript模块化编程:AMD规范及require.js用法【转】
  • 原文地址:https://www.cnblogs.com/171-LAN/p/5961804.html
Copyright © 2020-2023  润新知