• 实验一词法分析实验报告


    实验一、算法分析实验

    专业:商业软件工程   姓名:李智濠  学号:201506110117

    一、        实验目的

     

    编制一个词法分析程序。

    二、        实验内容和要求

    输入:源程序字符串

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

    待分析语言的词法规则。

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

     

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

    可执行程序名:kenk.exe

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

    对字符串表示的源程序 

    从左到右进行扫描和分解

    根据词法规则

    识别出一个一个具有独立意义的单词符号

    以供语法分析之用

    发现词法错误,则返回出错信息

    1. 3.      主要程序段及其解释:
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #define _KEY_WOED_END "waiting for your expanding" //关键字结束标志
    
    typedef struct
    {
    int typenum;
    char * word;
    }WORD;
    
    char input[255];
    
    char token[255]=""; 
    
    int p_input; 
    
    int p_token;
    
    char ch; //当前所读的字符
    
    char *rwtab[]={"begin","if","then","while","do","end",_KEY_WOED_END}; //C语言关键字
    
    WORD * scaner(); //词法扫描函数,获得关键字
    
    main()
    {
    int over=1;
    WORD *oneword;
    oneword=(WORD *)malloc(sizeof(WORD));
    printf("请输入您的单词(以#作为结束标志):");
    scanf("%[^#]s",input); //读入源程序字符串到缓冲区,以#结束,允许多行输入
    p_input=0;
    printf("您输入的单词是:%s\n\n",input);
    while(over<1000&&over!=-1)
    {
    oneword=scaner();
    printf("(%d,%s)",oneword->typenum,oneword->word);
    over=oneword->typenum;
    }
    printf("\n按#可推出程序");
    scanf("%[^#]s",input);
    }
    
    
    //需要用到的自编函数参考实现
    //从输入缓冲区读取一个字符到ch中
    
    char m_getch(){
    ch=input[p_input];
    p_input=p_input+1;
    return (ch);
    }
    
    //去掉空白字符
    void getbc()
    {
    while(ch==' '||ch==10){
    ch=input[p_input];
    p_input=p_input+1;
    }
    }
    
    //拼接单词
    void concat()
    {
    token[p_token]=ch;
    p_token=p_token+1;
    token[p_token]='\0';
    }
    
    //判断是否字母
    int letter()
    {
    if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z')return 1;
    else return 0;
    }
    
    
    //判断是否数字
    int digit()
    {
    if(ch>='0'&&ch<='9')
    return 1;
    else
    return 0;
    }
    
    
    //检索关键字表格
    int reserve()
    {
    int i=0;
    for(i=0;i<7;i++)
    {
    if(!strcmp(rwtab[i],token))
    {
    return i+1;
    }
    i=i+1;
    }
    return 10;
    }
    
     
    
    //回退一个字符
    void retract()
    {
    p_input=p_input-1;
    }
    
    
    /*数字转换成二进制
    char *dtb()
    {
    return NULL;
    }
    */
    
    WORD *scaner()
    {
    WORD *myword;
    myword=(WORD *)malloc(sizeof(WORD));
    myword->typenum=10;
    myword->word="";
    p_token=0;
    m_getch();
    getbc();
    if(letter())
    {
    while(letter()||digit())
    {
    concat();
    m_getch();
    
    }
    retract();
    myword->typenum=reserve();
    myword->word=token;
    return(myword);
    }
    else if(digit())
    {
    while(digit())
    {
    concat();
    m_getch();
    }
    retract();
    myword->typenum=20;
    myword->word=token;
    return(myword);
    }
    else
    {
    switch(ch)
    {
    case '=':m_getch();
    if(ch=='=')
    {
    myword->typenum=39;
    myword->word="==";
    return(myword);
    }
    retract();
    myword->typenum=21;
    myword->word="=";
    return(myword);
    break;
    case '+':
    myword->typenum=22;
    myword->word="+";
    return(myword);
    break;
    case '-':
    myword->typenum=23;
    myword->word="-";
    return(myword);
    break;
    case '*':
    myword->typenum=24;
    myword->word="*";
    return(myword);
    break;
    case '/':
    myword->typenum=25;
    myword->word="/";
    return(myword);
    break;
    case '(':
    myword->typenum=26;
    myword->word="(";
    return(myword);
    break;
    case ')':
    myword->typenum=27;
    myword->word=")";
    return(myword);
    break;
    case '[':
    myword->typenum=28;
    myword->word="[";
    return(myword);
    break;
    case ']':
    myword->typenum=29;
    myword->word="]";
    return(myword);
    break;
    case '{':
    myword->typenum=30;
    myword->word="{";
    return(myword);
    break;
    case '}':
    myword->typenum=31;
    myword->word="}";
    return(myword);
    break;
    case ',':
    myword->typenum=32;
    myword->word=",";
    return(myword);
    break;
    case ':':
    myword->typenum=33;
    myword->word=":";
    return(myword);
    break;
    case ';':
    myword->typenum=34;
    myword->word=";";
    return(myword);
    break;
    case '>':
    myword->typenum=35;
    myword->word=">";
    return(myword);
    break;
    case '<':
    myword->typenum=36;
    myword->word="<";
    return(myword);
    break;
    case '!':
    m_getch();
    if(ch=='=')
    {
    myword->typenum=40;
    myword->word="!=";
    return(myword);
    }
    retract();
    myword->typenum=-1;
    myword->word="ERROR";
    return(myword);
    break;
    case '\0':
    myword->typenum=1000;
    myword->word="OVER";
    return(myword);
    break;
    default:
    myword->typenum=-1;
    myword->word="ERROR";
    return(myword);
    }
    }
    }
    
    
    1. 4.      运行结果及分析

    一般必须配运行结果截图,结果是否符合预期及其分析。

       (截图需根据实际,截取有代表性的测试例子)

     

     

     

     

     

    四、        实验总结

    对要输出的字符串和字符组不是很熟悉,虽然网上有代码参考,但还是不懂。

  • 相关阅读:
    浅谈数据结构之KMP(串中的模式匹配算法)
    electron 使用serialport串口库
    electron-builder 打包时下载 winCodeSign和nsis缓慢解决方法
    【SQL / MySQL】Hierarchical Queries (层级结构查询)
    delphi MSSQL表类型传参
    DevExpress ComboboxEdit绑定key value值
    devexpress gridControl1导出为pdf文件时出现 中文乱码的解决方案
    DevExpress的GridControl控件设置自定义显示方法
    Reactive Spring实战 -- 响应式MySql交互
    Reactive Spring实战 -- 响应式Kafka交互
  • 原文地址:https://www.cnblogs.com/lzhshuai/p/5961388.html
Copyright © 2020-2023  润新知