实验二语法分析

时间:2024.3.31

实验二:语法分析器

一、实验目的:

1.强化对系统软件综合工程实现能力的训练;
2.加强对语法分析原理、方法和基本实现技术的理解;

二、实验内容:

1) 用C语言或者其他的高级语言作为宿主语言完成C0语言的词法分析器的设计和实现.

2) 针对if语句的文法编写一个递归下降分析程序,输出结果为抽象语法树。注意,if语句文法中的表达式E采用四则运算表达式的文法;抽象语法树的格式自行设计,如果需要降低难度的话,也可用具体语法树而不用抽象语法树作为输出.

三、实验要求:

1. 编写C0语言的语法分析器的源程序并调试通过。其中语法分析程序既可以自己手动去完成,也可以利用YACC自动生成。

2. 通过测试程序的验收;
3.实验报告按照提供的模板填写:

(1)功能描述:该程序具有什么功能?

(2)程序结构描述:函数调用格式、参数含义、返回值描述、函数功能;另外可以附加函数之间的调用关系图、程序总体执行流程图。

(3)实验总结:你在编程过程中花时多少?多少时间在纸上设计?多少时间上机输入和调试?多少时间在思考问题?遇到了哪些难题?你是怎么克服的?你对你的程序的评价?你的收获有哪些?

四、评判标准:

    1. 输出正确的实验结果;

    2. 代码清晰,格式良好;

    3. 提交报告,报告阐述清楚。

五、程序工作说明:(以C0语言为例)

     由于语法分析是在词法分析上做的进一步分析,所以要求在上次输出词法分析结果的同时,也需要输出语法分析的结果。该结果用xml格式的文件表示,如:

<root>

<Tree lineNo=’…’ nodeType=’…’ string=’…’ dataType=’…’ isArray=’…’ value='...'>

<Child>

<Tree >

</Tree>

</Child>

</Tree>

</root>

程序输入/输出示例:

如源程序为如下:

void main()

{

   int a=0;

   int b=2;

   while(a==b)

     ++a;

}

则要求得到如下输出文件:

<?xml version="1.0"?>

<root>

<Tree lineNo=1 nodeType="function"  string="main"

        dataType="void" value="none">

<Child>

    <Tree lineNo=3 nodeType="var_declarations" string="none" 

            dataType="none" value="0">

    <Child>

           <Tree lineNo=3 nodeType="var_declaration" string="a"  

                   dataType="int" value="0">

           </Tree>

    </Child>

    <Child>

           <Tree lineNo=4 nodeType="var_declaration" string="b"  

                  dataType="int" value="2">

           </Tree>

    </Child>

    </Tree>

</Child>

<Child>

    <Tree lineNo=5 nodeType="sentences" string="none" 

           dataType="none" value="none">

    <Child>

           <Tree lineNo=5 nodeType="while" string="none"

               dataType="none" value="none">

           <Child>

               <Tree lineNo=5 nodeType="condition" 

               string="a==b" dataType="boolean" value="unknown">

               </Tree>

               <Tree lineNo=6 nodeType="sentences" ...>

                   <Child>

                      <Tree lineNo=6 nodeType="expression"

                              String="++a" ...>

                      </Tree>

                   </Child>

               </Tree>

           </Child>

           </Tree>

    </Child>

    </Tree>

</Child>

</Tree>

</root>

     说明:NodeType实际输出的内容可根据你定的节点类型来输出,也可以后面附带附加信息。另外,对于nodeType为"var_declaration"和"sentences"的标签,你可以输出,也可以不输出,这里这样输出主要是为了让变量声明和语句更好地区分,建议大家也这样输出。这里的实例只列举一个函数,为了考虑多个函数的情况,你可能还需要"function_declaration"和参数表。

     

六、相关知识:

  词法分析器任务:

 

     将词法分析过程输出的记号输入到语法分析器中,按照C0的文法规则,将记号和相关数据输出到语法树中。

    

1)语法树中节点的类型 

   public enum NodeKind

   {

      FuncK,SenK,ExpK

        };

        public enum SenKind

       {

           IfK,WhileK,RetureK

           ...

       }   

       public enum ExpKind

       {

           SimpleK,AssignK

       }

     2)语法树的节点数据结构

   public class treeNode

   {

      Struct treeNode * child[MAXCHILD];

      NodeKind nodeKind;

      Union

      {

         SenKind sen;

         ExpKind exp;

      }kind;

      Union

      {

         TokenType op;

         Int val;

         Char * name;

      }attr;

      ExpType type;

      int lineNo;

   }

3)C0的语法

    program→ { var-declaration | fun-declaration }

        var-declaration→ int ID { , ID }   

        fun-declaration→ ( int | void ) ID ( params ) compound-stmt

        params → int ID { , int ID } | void | empty

        compound-stmt→ { { var-declaration } { statement } }

        statement→ expression-stmt∣compound-stmt ∣if-stmt ∣while-stmt

        |return-stmt

        expression-stmt→ [ expression ] ;

        if-stmt→ if( expression ) statement [ else statement ]

        while-stmt→ while( expression ) statement

        return-stmt→ return [ expression ] ;

        expression→ ID = expression | simple-expression

        simple-expression→ additive-expression [ relop additive-expression ]

        relop → < | <= | > | >= | == | !=

        additive-expression→ term [( + | - ) term ]

        term→ factor [ ( * | / ) factor ]

       factor→ ( expression )| ID | call | NUM

       call→ ID( args )

       args→ expression { , expression } | empty

       ID →…  ;参见C语言标识符定义

       NUM →… ;参见C语言数的定义

    

七、参考书目:

1.    Kenneth C. Louden著,冯博琴译《编译原理及实践》,机械工业出版社,20##年

2.    Andrew W.Appel著,赵克佳等译《现代编译原理C语言描述》人民邮电出版社,20##年

3.    陈火旺,刘春林等,《程序设计语言编译原理》第三版,国防科大出版社,20##年


第二篇:实验二 递归下降语法分析报告


 学 生 实 验 报 告

(理工类)

课程名称:   编译原理   专业班级: 08计算机科学与技术(单)

所属院部: 信息技术学院 指导教师:   

20XX   ——20XX  学年          第 二  学期

 金陵科技学院教务处制

实验报告书写要求

实验报告原则上要求学生手写,要求书写工整。若因课程特点需打印的,要遵照以下字体、字号、间距等的具体要求。纸张一律采用A4的纸张。

实验报告书写说明

实验报告中一至四项内容为必填项,包括实验目的和要求;实验仪器和设备;实验内容与过程;实验结果与分析。各院部可根据学科特点和实验具体要求增加项目。

填写注意事项

(1)细致观察,及时、准确、如实记录。

(2)准确说明,层次清晰。

(3)尽量采用专用术语来说明事物。 

(4)外文、符号、公式要准确,应使用统一规定的名词和符号。

(5)应独立完成实验报告的书写,严禁抄袭、复印,一经发现,以零分论处。

实验报告批改说明

实验报告的批改要及时、认真、仔细,一律用红色笔批改。实验报告的批改成绩采用百分制,具体评分标准由各院部自行制定。

实验报告装订要求

实验批改完毕后,任课老师将每门课程的每个实验项目的实验报告以自然班为单位、按学号升序排列,装订成册,并附上一份该门课程的实验大纲。

实验项目名称: 递归下降语法分析  实验学时:     6       

同组学生姓名:         无        实验地点:    B513     

实验日期:   2011.3.10/3.24/4.7  实验成绩:             

批改教师:                       批改时间:             

一、实验目的和要求

通过本实验,了解递归下降预测分析的原理和过程以及可能存在的回溯问题,探讨解决方法,为预测分析表方法的学习奠定基础。分析递归下降子程序的优缺点。

二、实验仪器和设备

硬件系统:586以上计算机、服务器要求内存256以上、Cpu 2.0GHz以上、Clinet内存128以上、CPU奔腾III以上,硬盘,光驱等

软件系统:Visual Studio 2005中文版软件

三、实验过程

1、设计框架

图1-1 递归下降程序框架图

2、设计步骤

1)给定文法:

  EàE+T|T

   TàT*F|F

   Fà(E)|i

2)构造FIRST()集和FOLLOW()集

           表2-1 FIRST()集和FOLLOW()集

3、程序源代码

using System;

using System.Collections.Generic;

using System.Text;

namespace 递归下降语法分析

{

  public  class Program

    {

        public static char []a=new char[50];

      public static char []b=new char[50];

      public static char []d=new char[200];

      public static char []e=new char[10];

public static char ch;

public static int n1,i1=0,flag=1,n=5;

public static int total=0;/*步骤计数器*/

      public  static int E1()

{  

    int f,t;

    Console.Write(total);

   Console.Write("\tE-->TG\t");total++;

   flag=1;

   input();

    input1();

    f=T();

    if (f==0) return(0);

    t=G();

    if (t==0) return(0);

           else return(1);

}

public static int E()

      int f,t;

      Console.Write(total);

      Console.Write("\tE-->TG\t");total++;

      e[0]='E';e[1]='=';e[2]='>';e[3]='T';e[4]='G';e[5]='#';

       output();

       flag=1;

       input();

       input1();

       f=T();

       if (f==0) return(0);

       t=G();

       if (t==0) return(0);

              else return(1);

}

public static int T()

{  

       int f,t;

       Console.Write(total);

     Console.Write("\tT-->FS\t");total++;

       e[0]='T';e[1]='=';e[2]='>';e[3]='F';e[4]='S';e[5]='#';

       output();

       flag=1;

       input();

       input1();

       f=F();

       if (f==0) return(0);

       t=S();

       if (t==0) return(0);

              else return(1);

}

public static int  G()

{  

       int f;

       if(ch=='+') { 

              b[i1]=ch;

              Console.Write(total);

             Console.Write("\tG-->+TG\t");total++;

              e[0]='G';e[1]='=';e[2]='>';e[3]='+';e[4]='T';e[5]='G';e[6]='#';

              output();

              flag=0;

              input();input1();

              ch=a[++i1];

              f=T();

              if (f==0) return(0);

              G();

              return(1);

       }

       Console.Write(total);

       Console.Write("\tG-->^\t");total++;

       e[0]='G';e[1]='=';e[2]='>';e[3]='^';e[4]='#';

       output();

       flag=1;

       input();input1();

       return(1);

}

public static int S()

{

       int f,t;

       if(ch=='*') {

              b[i1]=ch;

              Console.Write(total);

           Console.Write("\tS-->*FS\t");total++;

              e[0]='S';e[1]='=';e[2]='>';e[3]='*';e[4]='F';e[5]='S';e[6]='#';

              output();

              flag=0;

              input();input1();

              ch=a[++i1];

              f=F();

              if (f==0) return(0);

              t=S();

              if (t==0) return(0);

                   else return(1);}

                   Console.Write(total);

      Console.Write("\tS-->^\t");total++;

       e[0]='S';e[1]='=';e[2]='>';e[3]='^';e[4]='#';

       output();

       flag=1;

       a[i1]=ch;

       input();input1();

       return(1);

}

public static int F()

       int f;

       if(ch=='(') {

              b[i1]=ch;

              Console.Write(total);

           Console.Write("\tF-->(E)\t");total++;

              e[0]='F';e[1]='=';e[2]='>';e[3]='(';e[4]='E';e[5]=')';e[6]='#';

              output();

              flag=0;

              input();input1();

              ch=a[++i1];

              f=E();

              if (f==0) return(0);

              if(ch==')') {

                     b[i1]=ch;

                     Console.Write(total);

                  Console.Write("\tF-->(E)\t");total++;

                  flag=0;input();input1(); 

                     ch=a[++i1];

              }

               else {

                    Console.Write("error\n");

                      return(0);

               }

       }

       else if(ch=='i') {

              b[i1]=ch;

              Console.Write(total);

           Console.Write("\tF-->i\t");total++;

              e[0]='F';e[1]='=';e[2]='>';e[3]='i';e[4]='#';

              output();

              flag=0;input();input1();

              ch=a[++i1];

       }

          else {Console.Write("error\n");return(0);}

         return(1);

}

public static void input()

{

        int j=0;

        for (;j<=i1-flag;j++)

        Console.Write(b[j]);                    /*输出分析串*/

        Console.Write("\t\t");

        Console.Write("\t\t",ch);                  /*输出分析字符*/ 

}

public static void input1()

{

        int j;

        for (j=i1+1-flag;j

        Console.Write(a[j]);                     /*输出剩余字符*/

     Console.Write("\n");

}

public static void output()

{                              /*推导式计算*/

       int m,k,j,q;

       int i=0;

       m=0;k=0;q=0;

       i=n;

       d[n]='=';d[n+1]='>';d[n+2]='#';n=n+2;i=n;

       i=i-2;

       while(d[i]!='>'&&i!=0) i=i-1;

       i=i+1;

       while(d[i]!=e[0]) i=i+1;

       q=i;

       m=q;k=q;

       while(d[m]!='>')  m=m-1;

       m=m+1;

       while(m!=q) {

              d[n]=d[m];m=m+1;n=n+1;

       }

      d[n]='#';

      for(j=3;e[j]!='#';j++){

              d[n]=e[j];

              n=n+1;

       }

       k=k+1;

       while(d[k]!='=')  {

              d[n]=d[k];n=n+1;k=k+1;

       }

       d[n]='#';

       //system("pause");

}

        static void Main(string[] args)

        {                    /*递归分析*/

       int f,p,j=0;

       char x;

            d[0]='E';

    d[1]='=';

    d[2]='>';

    d[3]='T';

    d[4]='G';

    d[5]='#';

    Console.Write("请输入字符串(长度<50,以#号结束)\n");

    do{

              ch=(char)Console.Read();

              a[j]=ch;

              j++;

    }while(ch!='#');

      n1=j;

       ch=b[0]=a[0];

       Console.Write("步骤\t文法\t分析串\t\t分析字符\t剩余串\n");

            f=E1();

       if (f==0) return;

       if (ch=='#') 

       {

         Console.Write("accept\n");      

         p=0;

         x=d[p];

              while(x!='#') {

                     Console.Write(x);p=p+1;x=d[p];          /*输出推导式*/

              }

       }else {

              Console.Write("error\n");

              Console.Write("回车返回\n");

              Console.ReadLine();

              Console.ReadLine();

              return;

       }

       Console.Write("\n");

       Console.Write("回车返回\n");

       Console.ReadLine();

       Console.ReadLine();

        }

    }

}

程序输入输出举例:

1、输入“(i+i)*i”,分析如下图所示:

2、输入“i#”,分析如下图所示:

3、输入“i+i#”,分析如下图所示:

四、实验结果与分析

通过本次实验基本掌握了语法分析的原理和递归下降子程序分析方法,并且能将学到的知识学以致用,提高了对代码的分析能力,掌握了递归下降语法的构造,对自上再而下的语法分析模式有了更好的认识和理解。

通过编写程序进一步复习巩固了C#语言的相关知识,由于对C#语言的掌握不扎实,在编程过程中遇到了很多基础性问题,通过不断的查阅课本,最终解决了问题,但程序仍然存在很多值得改进和完善的地方,这就提醒我们在以后的学习过程当中应该及时复习巩固以前学过的相关知识。

更多相关推荐:
语法分析实验报告

编译原理实验报告实验名称实验类型指导教师专业班级姓名学号实验地点实验成绩编写语法分析程序上机实验蒋勇软件1002班20xx1东6A319日期20xx年05月日20一实验目的通过设计编写调试一个递归下降语法分析程...

语法分析器实验报告

语法分析器的设计实验报告一实验内容语法分析程序用LL1语法分析方法首先输入定义好的文法书写文件所用的文法可以用LL1分析先求出所输入的文法的每个非终结符是否能推出空再分别计算非终结符号的FIRST集合每个非终结...

语法分析实验报告(实验二)

编译原理语法分析实验报告软工082班兰洁20xx31104044一实验内容二实验目的三实验要求四程序流程图主函数scannerirparser函数yucu语句串分析statement语句分析函数expressi...

语法分析器实验报告

实验三语法分析器一实验目的理解和掌握LL1语法分析方法的基本原理根据给出的LL1文法掌握LL1分析表的构造及分析过程的实现掌握语法分析方法和程序设计方法二实验要求对每个非终极符按其产生式结构构造相应语法分析子程...

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

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

词法分析器语法分析器实验报告(编译原理超实用)

山东大学编译技术课程设计班级软件一班学号20xx008000XX姓名软件一班万岁指导老师贺老师二零一一年三月一目的ltlt编译技术gtgt是理论与实践并重的课程而其实验课要综合运用一二年级所学的多门课程的内容用...

编译原理实验报告(词法分析器 语法分析器)

编译原理实验报告实验一一实验名称词法分析器的设计二实验目的1词法分析器能够识别简单语言的单词符号2识别出并输出简单语言的基本字标示符无符号整数运算符和界符三实验要求给出一个简单语言单词符号的种别编码词法分析器四...

实验二 LL(1)分析法实验报告

实验二LL1分析法一实验目的通过完成预测分析法的语法分析程序了解预测分析法和递归子程序法的区别和联系使学生了解语法分析的功能掌握语法分析程序设计的原理和构造方法训练学生掌握开发应用程序的基本方法有利于提高学生的...

LR语法分析器 北邮 编译原理 实验

TitlecLR语法分析器cppAuthorvolantfishnum10211xxxClass20xx211309Date20xx11volantfishIntroductionVersionincludel...

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

中北大学软件学院实验报告专业课程名称学号姓名辅导教师成绩

北邮-语法分析实验报告

编译原理语法分析实验报告by坏学长一实验题目和要求题目语法分析程序的设计与实现实验内容编写语法分析程序实现对算术表达式的语法分析要求所分析算术表达式由如下的文法产生EETETTTTFTFFFidEnum实验要求...

编译原理词法分析和语法分析报告 代码(C语言版)

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

语法分析实验报告(41篇)