词法分析实验报告

一、实验目的

  通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解,并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类,并依次输出各个单词的内部编码及单词符号自身值。

二、实验内容和要求

实验内容:用C语言对源程序进行词法分析。通过输入源程序从左到右对字符串进行扫描和分解,依次输出各个单词的内部编码及单词符号自身值;若遇到错误则显示“Error”,然后跳过错误部分继续显示;同时进行标识符登记符号表的管理。

以下是实现词法分析设计的主要工作:1)从源程序文件中读入字符(2)统计行数和列数用于错误单词的定位。(3)删除空格类字符,包括回车、制表符空格。(4)按拼写单词,并用(内码,属性)二元式表示。(属性值——token的机内表示)5)如果发现错误则报告出错(6)根据需要是否填写标识符表供以后各阶段使用。

实验要求:

1.待分析的简单的词法

1)保留字:if,else, for, while, do, int ,read, write,real,char 

2)纯单分界符:+ * (){} 

3)双分界符:> < = ! ,&&,||

2.实现功能:

1)在命令行中输入源程序文件名(包括文件名路径)

2)输入目标文件名(包括文件名路径)

3)调用所编词法分析代码将分析结果写入目标文件代码(编译完成)

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

 1.      源程序名:词法分析.zip   中源程序名:词法分析.c

可执行程序名:词法分析.exe

2.      原理分析及流程图

主要算法:算法的基本任务是从输入的字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

 存储结构:顺序存储结构

关键函数的实现:通过扫描函数对输入的字符串进行一一扫描

注:关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。如能查到匹配的单词,则该单词为关键字,否则为一般标识符。

3.      流程图:

4.主要程序段及其解释: 

 

void scaner()

{
    /*共分为三大块,分别是标示符、数字、符号,对应下面的 if else if 和 else */ 
    for(n=0;n<7;n++) 
        TOken[n]=0;//每次循环完就清零 
    ch=A[i];
    while(ch==' '||ch=='\n')//如果字符是空格或者回车,跳过 
    {
        i++;
        ch=A[i];
    }
    if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) //可能是标示符或者变量名 
    {
        m=0;
        while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))//找到一个变量名或者关键字,直到遇到空格为止 
        {
            TOken[m]=ch;m++;
            i++;ch=A[i];
        }
        TOken[m]='\0';//将识别出来的字符和已定义的标示符作比较, //因为定义的begin为1,if为2...... 
        if(strcmp(TOken,r1)==0){syn=1;}
        else if(strcmp(TOken,r2)==0){syn=2; }
        else if(strcmp(TOken,r3)==0){syn=3;} 
        else if(strcmp(TOken,r4)==0){syn=4;}
        else if(strcmp(TOken,r5)==0){syn=5;}
        else if(strcmp(TOken,r6)==0){syn=6;}
        else if(strcmp(TOken,r7)==0){syn=7;}
        else if(strcmp(r8,TOken)==0){syn=8;}
        else if(strcmp(r9,TOken)==0){syn=9;}
        else if(strcmp(r10,TOken)==0){syn=10;}
        else if(strcmp(r11,TOken)==0){syn=11;}
        else if(strcmp(r12,TOken)==0){syn=12;}
        else if(strcmp(r13,TOken)==0){syn=13;}
        else if(strcmp(r14,TOken)==0){syn=14;}
        else if(strcmp(r15,TOken)==0){syn=15;}
        else if(strcmp(r16,TOken)==0){syn=16;}
        else if(strcmp(r17,TOken)==0){syn=17;}
        else if(strcmp(r18,TOken)==0){syn=18;}
        else if(strcmp(r19,TOken)==0){syn=19;}
        else if(strcmp(r20,TOken)==0){syn=20;}
        else if(strcmp(r21,TOken)==0){syn=21;}
        else if(strcmp(r22,TOken)==0){syn=22;}
        else if(strcmp(r23,TOken)==0){syn=23;}
        else if(strcmp(r24,TOken)==0){syn=24;}
        else if(strcmp(r25,TOken)==0){syn=25;}
        else if(strcmp(r26,TOken)==0){syn=26;}
        else if(strcmp(r27,TOken)==0){syn=27;}
        else if(strcmp(r28,TOken)==0){syn=28;}
        else if(strcmp(r29,TOken)==0){syn=29;}
        else if(strcmp(r30,TOken)==0){syn=30;}
        else if(strcmp(r31,TOken)==0){syn=31;}
        else if(strcmp(r32,TOken)==0){syn=32;}
        else if(strcmp(r33,TOken)==0){syn=33;}
        else if(strcmp(r34,TOken)==0){syn=34;}
        else if(strcmp(r35,TOken)==0){syn=35;}
        else if(strcmp(r36,TOken)==0){syn=36;}
        else if(strcmp(r37,TOken)==0){syn=37;}
        else if(strcmp(r38,TOken)==0){syn=38;}
        else{syn=100;}    //变量名 
    }
    else if((ch>='0'&&ch<='9')) //数字 
    {
        sum=0;
        while((ch>='0'&&ch<='9'))
        {
            sum=sum*10+ch-'0';//显示其数字sum 
            i++;
            ch=A[i];
        }
        syn=40;
    }
    else switch(ch) //其他字符 
    {
case'<':m=0;TOken[m]=ch;m++;
    i++;ch=A[i];
    if(ch=='=')//<>为22 
    {
        syn=41;
        TOken[m]=ch;m++;i++;
    }
    else
    {
        syn=46;
    }
    break;
case'>':m=0;TOken[m]=ch;m++;
    i++;ch=A[i];
    if(ch=='=')
    {
        syn=42;
        TOken[m]=ch;m++;i++;
    }
    else
    {
        syn=47;
    }
    break;
case':':m=0;TOken[m]=ch;m++;
    i++;ch=A[i];
    if(ch=='=')
    {
        syn=44;
        TOken[m]=ch;m++;i++;
    }
    else
    {
        syn=49;
    }
    break; 
case'@':syn=0;
    TOken[0]=ch;
    i++;
    break;
case'=':syn=48;
    TOken[0]=ch;
    i++;
    break; 
case'#':syn=50;
    TOken[0]=ch;
    i++;
    break;
case'+':syn=50;
    TOken[0]=ch;
    i++;
    break;
case'-':syn=51;
    TOken[0]=ch;
    i++;
    break;
case'*':syn=52;
    TOken[0]=ch;
    i++;
    break;
case'/':syn=53;
    TOken[0]=ch;
    i++;
    break; 
case'(':syn=54;
    TOken[0]=ch;
    i++;
    break;
case')':syn=55;
    TOken[0]=ch;
    i++;
    break;
case'{':syn=56;
    TOken[0]=ch;
    i++;
    break;
case'}':syn=57;
    TOken[0]=ch;
    i++;
    break; 
case';':syn=58;
    TOken[0]=ch;
    i++;
    break;
case'.':syn=59;
    TOken[0]=ch;
    i++;
    break;
case'\'':syn=60;
    TOken[0]=ch;
    i++;
    break;
case'\n':
    syn=-2;
    break;
default: syn=-1;
    break;
    }
}

 5. 运行结果及分析

 

posted @ 2016-10-14 17:04  098-谢家豪  阅读(1522)  评论(4编辑  收藏  举报