编译原理实验报告

时间:2024.4.27

        

学生姓名:     号:   指导教师:

实验地点:  计算机软件实验室          实验时间:

一、实验室名称:计算机学院软件工程实验室

二、实验项目名称:词法分析器的设计与实现

三、实验学时:4学时

四、实验原理

 1.编译程序要求对高级语言编写的源程序进行分析和合成,生成目标程序。词法分析是对源程序进行的首次分析,实现词法分析的程序为词法分析程序。

2.词法分析的功能是从左到右逐个地扫描源程序字符串,按照词法规则识别出单词符号作为输出,对识别过程中发现的词法错误,输出相关信息。

3.状态转换图是有限有向图,是设计词法分析器的有效工具。

五、实验目的

    通过设计词法分析器的实验,使同学们了解和掌握词法分析程序设计的原理及相应的程序设计方法,同时提高编程能力。

六、实验内容

    实现求n!的极小语言的词法分析程序,返回二元式作为输出。

七、实验器材(设备、元器件)

1.    操作系统:Windows 7

2.    开发工具:visual studio 2008

八、实验步骤

 (1)启动VC6.0,创建空白工程项目。选择菜单中的“文件”->“新建”->“项目”,在弹出的对话框中,左边的“项目类型”框中,选择“Visual C++ 项目”,在右边框中,选择“空项目(.Net)”,在对话框下边,选择工程文件存放目录及输入名称,如Example1,单击“确定”。

(2)建立相应的单词符号与种别对照表;

(3)根据状态转换图编写相应的处理函数;

(4)完成词法分析器;

(5)编译与调试以上程序;

(6)生成相应的*.dyd文件,作为后面语法分析的输入文件。

九、实验数据及结果分析

   将源文件与.exe放在同一目录下

打开.exe,输入源文件名称,输出文件名称,错误输出名称

Out.dyd里部分内容

   可以对源程序进行词法分析,如果有错给出出错信息和所在行数,如果无错则生成二元式文件。

十、实验结论

    本实验程序较好地完成了词法分析程序的设计与实现,能够对所给文法的程序进行词法分析,在没有词法错误的时候生成相应的二元式文件。该实验程序可一次性给出源程序中的词法错误。

十一、总结及心得体会

    通过该实验,对词法分析程序的设计,以及运用C语言进行编程有了更深刻的理解,同时加深了自己对词法分析程序的原理的理解与掌握,提高了自己的动手能力。

十二、对本实验过程及方法、手段的改进建议

程序设计合理,代码可进一步优化。

                                                     报告评分:

指导教师签字:

本实验参考源代码如下:

Val.h:

#include <cstring>

#include <cstdio>

#include <stdio.h>

#include <string.h>

int type=0;

char val[15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

char errval[15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

void to_outfile();

void to_errfile();

Function.h

using namespace std;

bool isletter(char c) //判别是否字母

{

if(c>64&&c<91||c>96&&c<123)

return true;

return false;

}

bool isdigital(char c) //判别是否数字

{ if(c>47&&c<58)

return true;

return false;

}

int match_reserve(char *p)//匹配保留字

{

    if(!(strcmp(p,"begin")))

    {

        type=1;

        strcpy(val,"begin");

          to_outfile();

          return 1;

    }

    else if(!(strcmp(p,"end")))

    {

        type=2;

          strcpy(val,"end");

          to_outfile();

          return 1;

    }

    else if(!(strcmp(p,"integer")))

    {

        type=3;

          strcpy(val,"integer");

          to_outfile();

          return 1;

    }

    else if(!(strcmp(p,"if")))

    {

        type=4;

          strcpy(val,"if");

          to_outfile();

          return 1;

    }

    else if(!(strcmp(p,"then")))

    {

        type=5;

          strcpy(val,"then");

          to_outfile();

          return 1;

    }

    else if(!(strcmp(p,"else")))

    {

        type=6;

          strcpy(val,"else");

          to_outfile();

          return 1;

    }

    else if(!(strcmp(p,"function")))

    {

        type=7;

          strcpy(val,"function");

          to_outfile();

          return 1;

    }

    else if(!(strcmp(p,"read")))

    {

        type=8;

          strcpy(val,"read");

          to_outfile();

          return 1;

    }

    else if(!(strcmp(p,"write")))

    {

        type=9;

          strcpy(val,"write");

          to_outfile();

          return 1;

    }

    else

          return 0;

}//match

void  match_small(char *p,int tempc)//非保留字、非运算符匹配

{

    char t[15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

    strcpy(t,p);

    int k=0;

    int state=0;

   

    for(k;k<tempc;k++)

    {

          if(isletter(t[k]))

          {

               state=1;

               break;

          }

    }

    if(state==0)

    {

       type=11;

       strcpy(val,p);

       to_outfile();

    }

    else

    {

        type=10;

        strcpy(val,p);

          to_outfile();

    }

}

///////////////////////////////////////////////匹配双运算符

void match_double_operator(char *p)

{

    if(!(strcmp(p,":=")))

    {

        type=20;

          strcpy(val,":=");

          to_outfile();

    }

    else if(!(strcmp(p,"<>")))

    {

        type=13;

          strcpy(val,"<>");

          to_outfile();

    }

    else if(!(strcmp(p,"<=")))

    {

        type=14;

          strcpy(val,"<=");

          to_outfile();

    }

   else if(!(strcmp(p,">=")))

    {

        type=16;

          strcpy(val,">=");

          to_outfile();

    }

 

}

//////////////////////////////////////////////////匹配单个运算符

void match_single_operator(char *p)

{

    if(!(strcmp(p,"<")))

    {

        type=15;

          strcpy(val,"<");

          to_outfile();

    }

    else if(!(strcmp(p,">")))

    {

        type=17;

          strcpy(val,">");

          to_outfile();

    }

    else if(!(strcmp(p,"-")))

    {

        type=18;

          strcpy(val,"-");

          to_outfile();

    }

    else if(!(strcmp(p,"*")))

    {

        type=19;

          strcpy(val,"*");

          to_outfile();

    }

    else if(!(strcmp(p,"=")))

    {

        type=13;

          strcpy(val,"=");

          to_outfile();

    }

    else if(!(strcmp(p,"(")))

    {

        type=21;

          strcpy(val,"(");

          to_outfile();

    }

    else if(!(strcmp(p,")")))

    {

        type=22;

          strcpy(val,")");

          to_outfile();

    }

    else if(!(strcmp(p,";")))

    {

        type=23;

          strcpy(val,";");

          to_outfile();

    }

    else

       

    {

          type=0;

          strcpy(val,p);

          strcpy(errval,p);

          to_outfile();

          to_errfile();

    }

}

Scanner.cpp

#include<iostream>

#include"val.h"

#include<fstream>

#include "function.h"

using namespace std;

ifstream sourcefile;/////源程序文件

ofstream outfile;//打开分析结果二元表

ofstream errfile;//打开错误记录表

char buffer[15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//读入缓冲区

char temp[15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

char tail[2]={0,0};

void to_outfile()

{

    outfile<<val;

    outfile<<"   ";

    outfile<<type;

    for(int i=0;i<15;i++)

    {

          val[i]=0;

    }

    outfile<<"\n";

    outfile<<"\n";

}

void to_errfile()

{

    errfile<<errval;

    errfile<<"   ";

    errfile<<type;

    for(int i=0;i<15;i++)

    {

          errval[i]=0;

    }

    errfile<<"\n";

    outfile<<"\n";

}

int main(int argc,char *argv[]){

    static char SourceFileName[256];

    static char OutputFileName[256];

    static char ErrorFileName[256];

    int count=0;//读字符计数器

    cout<<"Please input the path and the filename of your source file:"<<endl;

    cin>>SourceFileName;

    sourcefile.open(SourceFileName);

    if(!sourcefile.is_open()){

          cout<<"Open failed! Please Check The Path!"<<endl<<endl;

          cin.get();

          return 0;

    }

    cout<<"Please input the filename of your output file:"<<endl;

    cin>>OutputFileName;

    cout<<"Please input the filename of your error file:"<<endl;

    cin>>ErrorFileName;

    outfile.open(OutputFileName);

    errfile.open(ErrorFileName);

    while(sourcefile>>buffer){//当还有数据可读(没读到EOF的时候)读入一个单词长度的字符(读到空格或回车)

          if(buffer[0]==0){

               break;

          }

          int next=0;//指针指向缓存数组

          int small=0;//非运算符(标识符)数组长度      

          while((next<15)&&(buffer[next]!=0)){//遍历所有单词字符

               if((isletter(buffer[next]))||(isdigital(buffer[next]))){//将字母和数字加入small数组

                     small++;

                     tail[0]=buffer[next];

                     strcat(temp,tail);

                     next++;

                     if(buffer[next]==0){///////////////如果非运算符处于单词末尾 处理small数组

                          if(temp[0]!=0){

                                int fm=match_reserve(temp);//匹配保留字

                                if(fm==1){

                                      for(int j=0;j<15;j++){

                                           temp[j]=0;

                                      }

                                      tail[0]=0;

                                      tail[1]=0;

                                      small=0;

                                }

                                if(fm==0){//匹配保留字不成功

                                      match_small(temp,small);

                                      for(int j=0;j<15;j++){

                                           temp[j]=0;

                                      }

                                      tail[0]=0;

                                      tail[1]=0;

                                      small=0;

                                }

                          }

                     }

               }

               else{//遇到运算符

                        ////////////////////////先对small数组即标识符处理

                     if(temp[0]!=0){

                          int fm=match_reserve(temp);//匹配保留字

                          if(fm==1){

                                for(int j=0;j<15;j++){

                                      temp[j]=0;

                                }

                                tail[0]=0;

                                tail[1]=0;

                                small=0;

                          }

                          if(fm==0){  

                                match_small(temp,small);

                                for(int j=0;j<15;j++){

                                      temp[j]=0;

                                }

                                tail[0]=0;

                                tail[1]=0;

                                small=0;

                          }

                     }

                           /////////////////////////////////////////处理双操作符,向后展望一个字符

               if(((buffer[next]==':')&&(buffer[next+1]=='='))||((buffer[next]=='<')&&(buffer[next+1]=='='))||((buffer[next]=='>')&&(buffer[next+1]=='='))||((buffer[next]=='<')&&(buffer[next+1]=='>'))){

                          tail[0]=buffer[next];

                          tail[1]=buffer[next+1];

                          match_double_operator(tail);

                          next+=2;

                          tail[0]=0;

                          tail[1]=0;

                     }

                           //////////////////////////////////////////处理单操作符

                     else{

                          tail[0]=buffer[next];

                          match_single_operator(tail);

                          next++;

                          tail[0]=0;

                          tail[1]=0;

                     }

               }//else

          }//while

          for(int q=0;q<15;q++){

               buffer[q]=0;

          }

    }//while

    sourcefile.close();

    outfile.close();

    errfile.close();

    return 0;

}//main

        

学生姓名:号:  指导教师:

实验地点:计算机软件实验室         实验时间:

一、实验室名称:计算机学院软件工程实验室

二、实验项目名称:递归下降分析器的设计与实现

三、实验学时:12学时

四、实验原理

1.语法分析是对源程序经过词法分析后转换成的单词流按方法规则进行判断,对能构成正确句子的单词流,给出相应的语法树;对不能构成正确句子的单词流判断其语法错误并做出相应处理。

2.语法分析方法有自上而下和自下而上的分析方法。在不含左递归的文法G中,如果对每一个非终结符的所有候选式的第一个终结符都是两两不相交的(即无公共左因子),则可能构造出一个不带回溯的自上而下的分析程序,这个分析程序由一组递归过程组成,每个过程对应文法的一个非终结符。这样的分析程序称为递归下降分析程序。

七、实验目的

    通过设计递归下降分析器的设计与实现实验,使同学们掌握自上而下的递归分析法的语法分析原理和程序设计方法。

八、实验内容

根据给定的方法,编写相应的递归下降的语法分析程序,实现对词法分析后的单词序列的语法检查和程序结构的分析,生成相应的变量名表和过程名表,并将编译中语法检查出来的错误写入相应的文件。

语法错分类:

 (1)缺少符号错;

 (2)符号匹配错

 (3)符号无定义或重复定义。

七、实验器材(设备、元器件)

1.操作系统:Windows XP

2.开发工具:VC6.0

3.普通PC即可

十、实验步骤

 (1)启动VC6.0,创建空白工程项目。选择菜单中的“文件”->“新建”->“项目”,在弹出的对话框中,左边的“项目类型”框中,选择“Visual C++ 项目”,在右边框中,选择“空项目(.Net)”,在对话框下边,选择工程文件存放目录及输入名称,如Example1,单击“确定”。

(2)消除文法中的左递归;

(3)实现对方法进行递归向下的分析过程;

(4)利用词法分析器生成的二元式文件*.dyd进行语法分析;

(5)编译与调试以上程序;

十一、实验数据及结果分析

 

   可以对源程序进行语法分析,图中给出了出错行数及出错类型。

十一、实验结论

    本实验程序较好地完成了递归下降分析器的设计与实现,能够对所给文法的程序进行语法分析,生成变量名表和过程名表,如果源程序有语法错误则给出出错类型及所在行数。

十一、总结及心得体会

    通过该实验,对递归下降分析程序的设计,以及运用C语言进行编程有了更深刻的理解,同时加深了自己对语法分析程序的原理的理解与掌握,提高了自己的动手能力。

十二、对本实验过程及方法、手段的改进建议

程序设计合理,代码可进一步优化。

                                                     报告评分:

指导教师签字:

本实验参考源代码如下:

#include <vector>

#include <string>

#include <iostream>

#include <stdio.h>

using namespace std;

struct variable

{

    string vname,vproc,vtype;

    int vkind,vlev,vadr;

} var;

struct procedure

{

    string pname,ptype;

    int plev,fadr,ladr;

} proc;

vector <variable> v_table;

vector <procedure> p_table;

string sym;

int val,cur_line,cur_level;

bool ended=false;

void clean_output()

{

    freopen("example.dys","w",stdout);

    fclose(stdout);

    freopen("example.var","w",stdout);

    fclose(stdout);

    freopen("example.pro","w",stdout);

    fclose(stdout);

    freopen("SynAnalyze.err","w",stdout);

    fclose(stdout);

}

void advance()

{

    freopen("example.dys","a+",stdout);

    cin>>sym>>val;

    printf("%16s %2d\n",sym.c_str(),val);

    if (sym=="EOF") ended=true;

    while(sym=="EOLN")

    {

        cur_line++;

        cin>>sym>>val;

        printf("%16s %2d\n",sym.c_str(),val);

    }

}

void error(int type)

{

    freopen("SynAnalyze.err","a+",stdout);

    switch(type)

   

{

        case 0: printf("LINE %d: variable \"%s\" previously

          declared.\n",cur_line,sym.c_str());break;

        case 1: printf("LINE %d: missing declaration here.\n",

          cur_line);break;

        case 2: printf("LINE %d: missing executive statement

          here.\n",cur_line);break;

        case 3: printf("LINE %d: expected \"end\" here.\n",

          cur_line);break;

        case 4: printf("LINE %d: expected \"begin\" here.\n",

          cur_line);break;

        case 5: printf("LINE %d: missing \';\' here.\n",

          cur_line);break;

        case 6: printf("LINE %d: brackets doesn't matched.\n",

          cur_line);break;

        case 7: printf("LINE %d: illegal variable here.\n",

          cur_line);break;

        case 8: printf("LINE %d: missing \'(\' here.\n",

          cur_line);break;

        case 9: printf("LINE %d: illegal declaration here.\n",

          cur_line);break;

        case 10: printf("LINE %d: illegal executive statement

          here.\n",cur_line);break;

        case 11: printf("LINE %d: variable \"%s\"

          undeclared.\n",cur_line,sym.c_str());break;

        case 12: printf("LINE %d: missing \"else\" here.\n",

          cur_line);break;

        case 13: printf("LINE %d: missing \"then\" here.\n",

          cur_line);break;

        case 14: printf("LINE %d: illegal operator here.\n",

          cur_line);break;

        default: printf("LINE %d: unknown error\n",cur_line);

    }

    advance();

    fclose(stdout);

}

void init()

{

    clean_output();

    val,cur_line=1;

    cur_level=0;

    v_table.clear();

    p_table.clear();

    proc.pname="";

    proc.ptype="";

    proc.plev=0;

    proc.fadr=0;

    proc.ladr=-1;

    p_table.push_back(proc);

    return;

}

void v_add(int vkind)

{

    for (int i=p_table[cur_level].fadr;i<=p_table[cur_level].ladr;i++)

    {

        if (v_table[i].vname==sym && v_table[i].vlev==cur_level && v_table[i].vkind==vkind)

        {

            error(0);

            return;

        }

    }

    var.vname=sym;

    var.vproc=p_table[cur_level].pname;

    var.vtype="integer";

    var.vkind=vkind;

    var.vlev=cur_level;

    var.vadr=v_table.size();

    v_table.push_back(var);

    p_table[cur_level].ladr++;

}

bool v_check()

{

    for (int i=p_table[cur_level].fadr;i<=p_table[cur_level].ladr;i++)

    {

        if (v_table[i].vname==sym && v_table[i].vlev==cur_level)

        {

            return true;

        }

    }

    return false;

}

void A();

void B();

void C();

void D();

void E();

void F();

void G();

void H();

void I();

void J();

void A()

{

    if (sym=="begin")

    {

        advance();

        if (sym=="integer")

        {

            advance();

            B();

        }

        else error(1);

        if (sym==";")

        {

            while (sym==";")

            {

                advance();

                if (sym=="integer")

                {

                    advance();

                    B();

                }

                else

                {

                    break;

                }

            }

        }

        else error(2);

        C();

        while (sym==";")

        {

            advance();

            C();

        }

        if (sym=="end")

        {

            advance();

            return;

        }

        else error(3);

    }

    else error(4);

}

void B()

{

    if (val==10)

    {

        v_add(0);//加入变量

        advance();

    }

    else if (sym=="function")

    {

        advance();

        if (val==10)

        {

            advance();

            proc.pname=sym;

            cur_level++;

            proc.ptype="integer";

            proc.plev=cur_level;

            proc.fadr=v_table.size();

            proc.ladr=v_table.size()-1;

            p_table.push_back(proc);

            if (sym=="(")

            {

                advance();

                if (val==10)

                {

                    v_add(1);//加入形参

                    advance();

                    if (sym==")")

                    {

                        advance();

                        if (sym==";")

                        {

                            advance();

                            A();

                            cur_level--;

                        }

                        else error(5);

                    }

                    else error(6);

                }

                else error(7);

            }

            else error(8);

        }

        else error(7);

    }

    else error(9);

}

void C()

{

    if (sym=="read")

    {

        advance();

        D();

    }

    else if (sym=="write")

    {

        advance();

        D();

    }

    else if (val==10)

    {

        advance();

        E();

    }

    else if (sym=="if")

    {

        advance();

        I();

    }

    else error(10);

}

void D()

{

    if (sym=="(")

    {

        advance();

        if (val==10)

        {

            if (v_check()==true)//检查变量是否存在

            {

                advance();

                if (sym==")")

                {

                    advance();

                }

                else error(6);

            }

            else error(11);

        }

        else error(7);

    }

    else error(8);

}

void E()

{

    if (sym==":=")

    {

        advance();

        F();

    }

    else error(14);

}

void F()

{

    G();

    while (sym=="-")

    {

        advance();

        F();

    }

}

void G()

{

    H();

    while (sym=="*")

    {

        advance();

        H();

    }

}

void H()

{

    if (sym=="F")

    {

        advance();

        if (sym=="(")

        {

            advance();

            F();

            if (sym==")")

            {

                advance();

            }

            else error(6);

        }

        else error(8);

    }

    else if (val==10)

    {

        if (v_check()==true)//检查变量是否存在

        {

            advance();

        }

        else error(11);

    }

    else if (val==11)

    {

        advance();

    }

    else error(10);

}

void I()

{

    J();

    if (sym=="then")

    {

        advance();

        C();

        if (sym=="else")

        {

            advance();

            C();

        }

        else error(12);

    }

    else error(13);

}

void J()

{

    F();

    if (val>=12&&val<=17)

    {

        advance();

        F();

    }

    else error(14);

}

int main()

{

    freopen("example.dyd","r",stdin);

    init();

    advance();

    A();

    return 0;

}

更多相关推荐:
编译原理实验报告

ltlt编译原理gtgt上机实验报告编译原理上机实验报告一实验目的与要求目的在分析理解一个教学型编译程序如PL0的基础上对其词法分析程序语法分析程序和语义处理程序进行部分修改扩充达到进一步了解程序编译过程的基本...

《编译原理》课程实验报告(词法分析)完整版

编译原理课程实验报告题目专业计算机指导教师签名华东理工大学信息学院计算机系20xx年4月10日一实验序号编译原理第一次实验二实验题目词法分析三实验日期20xx32720xx410四实验环境操作系统开发语言操作系...

编译原理-词法语法分析实验报告

编译原理词法分析一、实验目的设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。二、实验要求2.1待分析的简单的词法(1)关键字:beginifthenwhiledoend所有的关键字都是小写。(2)运…

编译原理 实验报告

编译原理实验报告指导教师1一实验目的基本掌握计算机语言的词法分析程序的开发方法以及掌握计算机语言的语法分析程序设计与属性文法应用的实现方法锻炼自己的编程能力和逻辑思维能力体会计算机编译器的奥妙之处二实验内容1编...

编译原理实验报告完整版(河北工业)

编译原理实验报告班级姓名学号自我评定75实验一词法分析程序实现一实验目的与要求通过编写和调试一个词法分析程序掌握在对程序设计语言的源程序进行扫描的过程中将字符形式的源程序流转化为一个由各类单词符号组成的流的词法...

编译原理 语法分析 实验报告

编译原理实验报告编译原理实验报告1编译原理实验报告一实验内容设计编制并调式一个语法分析程序加深对语法分析原理的理解二实验目的及要求利用C或C编制确定的自顶向下预测分析语法分析程序并对简单语言进行语法分析21待分...

编译原理实验一报告

编译原理实验报告基于C语言词法分析器的设计摘要首先对编译原理进行概括的介绍1主要是描写设计内容及设计要求2介绍设计的基本原理3对程序设计的总体方案及各模块设计做了介绍4对程序进行测试引言编译原理是国内外各高等院...

编译原理课设实验报告

编译技术课程设计报告编译技术课程设计报告实验名称姓名学号班级135编译器设计编译技术课程设计报告本课设的任务是完成一个完整的编译器处理用户提交的符合所定文法的源程序代码生成四元式中间代码进而翻译成等价的X86平...

20xx广工编译原理实验报告

实验报告课程名称编译原理题目名称PL0编译器的扩充学生学院计算机学院专业班级计算机科学与技术124学号31120xx901学生姓名柏石先指导教师李杨20xx年12月20日一实验目的与要求对PL0作以下修改扩充1...

编译原理实验报告

贵州师范大学数学与计算机科学学院实验报告课程名称编译原理教师姓名班级20xx级计算机专业本科班1目录实验任务1熟悉概念图软件1实验任务2体会编译器的功能1实验任务3绘制编译原理课程学习概念图4实验任务4正则...

编译原理实验报告

编译原理实验报告

武汉理工大学学生实验报告书实验课程名称编译原理开课学院计算机科学与技术学院指导老师姓名学生姓名学生专业班级20xx20xx学年第2学期实验课程名称编译原理实验课程名称编译原理

编译原理实验报告(46篇)