• 编译原理实验体会 > 编译原理实验
  • 编译原理实验

    免费下载 下载该文档 文档格式:DOC   更新时间:2005-05-01   下载次数:0   点击次数:1
    文档基本属性
    文档语言:English
    文档格式:doc
    文档作者:lanye
    关键词:
    主题:
    备注:
    点击这里显示更多文档属性
    编译原理实验
    --写一个简单的词法分析器
    姓名:邓乐 班级:CS0209 学号:012002014107
    一.实验目的:
    设计,编制并调试一个词法分析程序,加深对词法分析原理的理解.
    实验要求:
    1.待分析的C语言子集的词法
    关键字
    If then while do
    专用符号
    = + - * / < >= == != ; { } ( )
    其他标记ID和NUM
    通过以下的正规式定义其他标记:
    ID-->字母{字母|数字}
    NUM-->数字{数字}
    字母-->A|B|C|.....a|b|c
    数字-->1|2|3...8|9|0
    各种单词符号对应的种别码
    词法分析程序的功能
    输入:所给文法源程序字符串.
    输出:二元组(syn,word)构成的序列.要求有一定的查错功能.
    具体实现的时候单词是用结构进行处理的.
    例如,对源程序
    {x=9;
    if x> 0 then x=x+1
    while(a=0) do
    b=2*x/3}
    其运行结果如下:
    当有错误字母会有判断出错的能力,例如对程序:
    {x=9;
    if x> 0 then x=x+1
    while(a=0) do #$
    b=2*x/3}
    运行结果如下:
    词法分析程序主要算法思想
    算法的主要任务是从字符的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号.
    参考教材首先定义了一些数据结构和宏,主要是单词对应的单词码.
    变量的定义:定义了一个关键字表,定义了一个联合来存放单词的内容,该联合有三个变量,分别用来存放不同的字符,T1用来存放标识符,T2用来存放数字,T3用来存放单个的符号. 然后定义了WORD的结构,用来存放单词二元组.然后定义全局变量:一个指向含文件内容的缓冲区的指针,行列号,和下一个字符脚标及下一个单词开始位置. 主程序中定义了一个缓冲区BUF用来存放要分析的程序的内容.
    主要的函数:void DO_Start(char *strSource) 用来分析字符串的主要程序,首先对空格进行处理,然后遇到不同的字符,分别转向不同的字符处理函数.
    void DO_Tag(char *strSource)用来分析标识符的中间状态.读入下一个字符,如是数字或是字母则递归调用本函数,直到遇到非数字和非字母然后转向其它字符处理函数.
    void DO_EndOfTag(char *strSource)用来分析标识符的结束状态.首先看是否关键字,设置正确的SYN.
    void PrintWord(WORD uWord)打印二元组函数.
    四.源程序如下
    #ifndef _GLOBALS_H
    #define _GLOBALS_h
    #include
    #include
    #include
    /*单词种别码*/
    #define _SYN_IF 1
    #define _SYN_THEN 2
    #define _SYN_WHILE 3
    #define _SYN_DO 4
    /*以上为关键字的单词种别码*/
    #define _SYN_ID 10 /*标识符的单词种别码*/
    #define _SYN_NUM 20 /*整数的单词种别码*/
    #define _SYN_ASSIGN 21/*=*/
    #define _SYN_PLUS 22/*+*/
    #define _SYN_MINUS 23/*-*/
    #define _SYN_TIMES 24/***/
    #define _SYN_DIVID 25/*/*/
    #define _SYN_LPAREN 26/*(*/
    #define _SYN_RPAREN 27/*)*/
    #define _SYN_LEFTBRACKET 28/*{*/
    #define _SYN_RIGHTBRACKET 29/*}*/
    #define _SYN_SEMICOLON 30/*;*/
    #define _SYN_LG 31/*>*/
    #define _SYN_LT 32/*=*/
    #define _SYN_LE 34/*,>=*/
    void DO_EndOfLess(char *strSource);/*<,<=*/
    void DO_EndOfPrintError(char *strSource);/*词法分析错误输出*/
    void Scaner(char *strSource);/*词法扫描函数*/
    void PrintError(int nColumn,int nRow,char chInput);
    char *strSource;/*待分析的源程序*/
    char buf[length];
    int gnColumn,
    gnRow,/*行列号*/
    gnLocate,/*下一个字符的位置*/
    gnLocateStart;/*下一个单词开始位置*/
    WORD uWord;
    /*关键字表*/
    char *KEY_WORDS[20]={"if","then","while","do","end"};
    int IsDigit(char chInput)/*判断扫描的字符是否数字*/
    {if(chInput='0')
    return 1;
    else return 0;}
    int IsChar(char chInput)/*判断扫描的字符是否字母*/
    {if((chInput='a')||(chInput='A'))
    return 1;
    else return 0;
    }
    void DO_Start(char *strSource)
    {gnLocateStart=gnLocate;
    switch(strSource[gnLocate]){/*根据第一个字符判断*/
    case'+':DO_EndOfPlus(strSource); break;
    case'-':DO_EndOfSubtraction(strSource);break;
    case'*':DO_EndOfMultiply(strSource);break;
    case'/':DO_EndOfDivide(strSource);break;
    case'(':DO_EndOfLParen(strSource);break;
    case')':DO_EndOfRParen(strSource);break;
    case'{':DO_EndOfLeftBracket(strSource);break;
    case'}':DO_EndOfRightBracket(strSource);break;
    case';':DO_EndOfSemicolon(strSource);break;
    case'>':DO_EndOfMore(strSource);break;
    case',>=*/
    {if(strSource[gnLocate+1]!='='){
    uWord.syn=_SYN_LG;
    uWord.value.T3=strSource[gnLocate];
    }
    else {
    gnLocate++;
    gnRow++;
    uWord.syn=_SYN_ME;
    strcpy(uWord.value.T1,">=");
    }
    gnLocate++;
    gnRow++;
    return;
    }
    void DO_EndOfLess(char *strSource)/*<,<=*/
    {if(strSource[gnLocate+1]!='='){/*<*/
    uWord.syn=_SYN_LT;
    uWord.value.T3=strSource[gnLocate];
    }
    else {/*<=*/
    gnLocate++;
    gnRow++;
    uWord.syn=_SYN_LE;
    strcpy(uWord.value.T1,"<=");
    }
    gnLocate++;
    gnRow++;
    return;
    }
    void DO_EndOfLeftBracket(char *strSource)/*{*/
    {uWord.syn=_SYN_LEFTBRACKET;
    uWord.value.T3=strSource[gnLocate];
    gnLocate++;
    gnRow++;
    return;
    }
    void DO_EndOfRightBracket(char *strSource)/*读到'}',源程序结束*/
    {uWord.syn=_SYN_RIGHTBRACKET;
    uWord.value.T3=strSource[gnLocate];
    gnLocate++;
    gnRow++;
    return;
    }
    void PrintWord(WORD uWord)
    {if(uWord.syn=*/
    ||uWord.syn==_SYN_LE/*Col:%d\tRow:%d\tChar:%c\n" ,nColumn,nRow,chInput);
    return;
    }
    int main()
    {FILE *fp;
    int cread,i=0;
    gnColumn=gnRow=1;
    gnLocate=gnLocateStart=0;
    if((fp=fopen("file1.c","r"))==NULL)
    {printf("Error");
    return -1;}
    cread=fread(buf,1,1000,fp);
    printf ( "源文件为:\n%s\n",buf );
    strSource=buf;
    printf ( "输出的二元组是:\n" );
    while(strSource[gnLocate]){
    DO_Start(strSource);
    i++;
    If(i%5==0) printf("\n");
    PrintWord(uWord);
    }
    return;
    }
    五.实验体会
    通过这次实验,使我对词法分析有了更深刻的了解,并且对C语言的运用有了更进一步的认识.

  • 下载地址 (推荐使用迅雷下载地址,速度快,支持断点续传)
  • 免费下载 DOC格式下载
  • 您可能感兴趣的
  • 编译原理实验  编译原理课后答案  编译原理  编译原理视频教程  编译原理第二版  编译原理课后习题答案  编译原理第三版答案  编译原理视频  编译原理龙书答案