首页 范文大全 古典文学 职场知识 中国文学 公文书信 外国名著 寓言童话 百家讲坛 散文/诗歌 美文欣赏 礼仪知识 民俗风情
  • 工作总结
  • 工作计划
  • 心得体会
  • 竞聘演讲
  • 会议发言
  • 爱国演讲
  • 就职演说
  • 开业开幕
  • 思想学习
  • 征文演讲
  • 经验材料
  • 述职报告
  • 调研报告
  • 工作汇报
  • 年终总结
  • 申报材料
  • 学习体会
  • 企划方案
  • 活动方案
  • 技巧经验
  • 模板范例
  • 思想宣传
  • 经济工作
  • 工作报告
  • 组织人事
  • 反腐倡廉
  • 慰问贺电
  • 先进事迹
  • 思想汇报
  • 入党申请书
  • 党会发言
  • 先进性教育
  • 入团申请书
  • 个人简历
  • 演讲稿
  • 调查报告
  • 实习报告
  • 和谐社会
  • 观后感
  • 读后感
  • 作文范文
  • 自我鉴定
  • 讲话稿
  • 自查报告
  • 合肥工业大学编译原理实验报告(完整代码版)

    时间:2020-07-03 11:48:56 来源:蒲公英阅读网 本文已影响 蒲公英阅读网手机站

    相关热词搜索:合肥 工业大学 编译

      计算机与信息学院

      编译原理

      实验报告 专

     业

     班

     级

      信息安全 131 班

      学生姓名及学号

      马骏 2013211869

     课 程 教 学 班 号

     任

     课

     教

     师

     李宏芒

      实 验 指 导 教 师

     李宏芒

     实 验 地 点

     实验楼机房

      2015

      ~2016

      学年第 二 学期 验 实验 1

     词法分析设计 一、

     实验目得

      通过本实验得编程实践,使学生了解词法分析得任务,掌握词法分析程序设 计得原理与构造方法,使学生对编译得基本概念、原理与方法有完整得与清楚得 理解,并能正确地、熟练地运用 二、 实验要求

      1、编程时注意编程风格:空行得使用、注释得使用、缩进得使用等。

     2、将标识符填写得相应符号表须提供给编译程序得以后各阶段使用。

     3、根据测试数据进行测试。测试实例应包括以下三个部分:

      全部合法得输入。

      各种组合得非法输入。

      由记号组成得句子。

     4、词法分析程序设计要求输出形式:

     例:输入 VC++语言得实例程序:

     If i=0 then

      n++;

     a﹤= 3b %);

     输出形式为:

     单词

      二元序列

     类

     型

     位置(行,列)

      (单词种别,单词属性)

     for

     (1,for )

      关键字

     (1,1)

     i

     ( 6,i )

     标识符

      (1,2)

     =

      ( 4,= )

     关系运算符

     (1,3)

      12

     0

      ( 5,0 )

      常数

     (1,4)

     then

     ( 1,then)

      关键字

     (1,5)

     n

      (6,n )

      标识符

     (1,6)

     ++

     Error

      Error

      (1,7)

     ;

      ( 2, ; )

      分界符

      (1,8)

     a

      (6,a )

     标识符

     (2,1)

     ﹤=

      (4,<= )

      关系运算符

      (2,2)

     3b

     Error

      Error

      (2,4)

     %

     Error

      Error

      (2,4)

     )

      ( 2, ) )

     分界符

     (2,5)

     ;

      ( 2, ; )

     分界符

      (2,6)

     三、

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

     以下就是实现词法分析设计得主要工作:

     (1)从源程序文件中读入字符。

     (2)统计行数与列数用于错误单词得定位。

     (3)删除空格类字符,包括回车、制表符空格。

     (4)按拼写单词,并用(内码,属性)二元式表示。(属性值——token 得机内 表示)

     (5)如果发现错误则报告出错

      7

     (6)根据需要就是否填写标识符表供以后各阶段使用。

     四、实验步骤 1、根据流程图编写出各个模块得源程序代码上机调试。

     2、 编制好源程序后,设计若干用例对系统进行全面得上机测试,并通过所设计 得词法分析程序;直至能够得到完全满意得结果。

     3、书写实验报告 ;实验报告正文得内容:

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

     程序结构描述:函数调用格式、参数含义、返回值描述、函数功能;函数 之间得调用关系图。

     详细得算法描述(程序总体执行流程图) 。

     给出软件得测试方法与测试结果。

     实验总结 (设计得特点、不足、收获与体会)。

     五、实验 截图

     先创建 salary 文件 输入 If i=0 then

      n++;

     a<= 3b %);

     六、 核心代码

     #include<iostream> #include<string> #include<fstream> #include <sstream> using namespace std; const char* salaryfile="salary"; const int max=40; string id[max]={"do","end","for","if","printf","scanf","then","while"};// 关键字表 string s[max]={",",";","(",")","[","]","+","","*","/","<","<=","=",">",">=","<>"};// 分界符表 算数运算符表

     关系运算符表 string k[max];// 标识符 string ci[max];// 常数 int fjfpoint=5;// 分界符表尾 int mathpoint=9;// 算数运算符表尾 int cipointer=0;// 常数表尾 int idpointer=0;// 关键字表尾 int kpointer=0;// 标识符表尾 int fjf;//0 不就是分界符 1 就是

     int rowy=1;// 识别输入行位置 int rowx=1;// 识别输入列位置 int outkey=0;// 打印控制 0 为数字后有字母 其她可以 void searcht(int i,string m)// 根据已识别得首字母识别字符串 { // cout<<"enter searcht!!"<<endl;

     int x;

     if(i==0)// 首字符就是字母识别关键字

     { //

     cout<<" a word!!"<<endl;

      for(x=0;x<max;x++)

      {

     if(id[x]==m)

     {

      cout<<"(1,"<<id[x]<<")"<<" 字 关 键 字 ("<<rowy<<","<<rowx<<")"<<endl;

      break;

     }

      }

      if(x==max)// 不就是关键字再识别标识符

      {

     for(x=0;x<max;x++)

     {

      if(k[x]==m)

      {

     cout<<"(6,"<<m<<") "<<" 符 标 识 符 ("<<rowy<<","<<rowx<<")"<<endl;

      break;

      }

     }

     if(x==max)// 标识符表没有时插入标识符

     {

      cout<<"(6,"<<m<<") "<<" 符 标 识 符 ("<<rowy<<","<<rowx<<")"<<endl;

      k[kpointer]=m;

      kpointer++;

     }

      }

     }

     if(i==1)// 识别常数

     {

     // cout<<"

     a number!!"<<endl;

      for(x=0;x<max;x++)

      {

      if(ci[x]==m)

     {

      cout<<"(5,"<<x<<")"<<endl;

      break;

     }

      }

      if(x==max)

      {

      cout<<"(5,"<<m<<") 常数 ("<<rowy<<","<<rowx<<")"<<endl;

     ci[cipointer]=m;

     cipointer++;

      }

     }

     if(i==2)// 识别 分界符 算数运算符

     关系运算符

     {

     // cout<<"

     a signal!!"<<endl;

      for(x=0;x<max;x++)

      {

     if(s[x]==m)

      break;

      }

     // x;

      if(x<6)

      {

     fjf=1;

      }

      if(x>5&&x<10)

      {

     if(outkey==1)

     {

      cout<<"(3,"<<s[x]<<") 符 算 数 运 算 符 ("<<rowy<<","<<rowx<<")"<<endl;

     outkey=0;

     }

     fjf=0;

      }

      if(x>9&&x<max1)

      {

     if(outkey==1)

     {

     cout<<"(4,"<<s[x]<<") 符 关 系 运 算 符 ("<<rowy<<","<<rowx<<")"<<endl;

     outkey=0;

     }

      fjf=0;

      }

      if(x==max)

      {

     if(outkey==1)

     {

     cout<<"Error

      Error ("<<rowy<<","<<rowx<<")"<<endl;

     outkey=0;

     }

     fjf=0;

      }

     } }; void wordlook(char t,string sn)// 识别首字符, 分类识别字符串 {

     if(t>=48&&t<=57)

      searcht(1,sn);

     else

     {

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

      searcht(0,sn);

      else searcht(2,sn);

     } }; void split(string s)// 分割字符串 { // cout<<s<<endl;

     string now[max];

     string sn;

     int nowpointer=0;

     int i=0;

     int x;

     int sign=2;// 非法数字标志

     int diannumber=0;// 数中点得个数

     for(x=0;x<s 、length;x++)

     {

      if((s[x]>64&&s[x]<91)||(s[x]>96&&s[x]<123)||(s[x]>=48&&s[x]<=57)||(x>0&&s[x]==46&&sign==1))// 判断数字后跟字母还就是字母后有数字

      {

     if(i==0)

     {

     if(s[x]>=48&&s[x]<=57)

      sign=1;

     else sign=2;

     }

     else

     {

      if(sign==1)

      {

     if(s[x]>=48&&s[x]<=57||s[x]==46)

     {

      if(s[x]==46)

      {

     if(diannumber==0)

      diannumber++;

     else sign=0;

      }

     }

     else sign=0;

      }

     }

     i++;

     if(x==(s 、length1))

     {

     sn=s 、substr(xi+1,i);

     if(i>0)

     {

     //

     cout<<sn<<" i="<<i<<endl;

      cout<<sn<<" ";

      if(sign==0)// 数字后有字母得情况

      cout<<"

      Error

     Error

     ("<<rowy<<","<<rowx<<")"<<endl;

     else // 字母开头得字符串

      {

     //

     cout<<"

      true"<<endl;

     wordlook(sn[0],sn);

      rowx++;

      }

     }

     }

      }

      else

      {

     if(x>0&&(s[x1]>64&&s[x1]<91)||(s[x1]>96&&s[x1]<123)||(s[x1]>=48&&s[x1]<=57))// 遇到分界符运算符 如果前面就是数字或字母

     {

     sn=s 、substr(xi,i);

      if(i>0)

      {

     //

     cout<<sn<<" i="<<i<<endl;

     cout<<sn<<" ";

     if(sign==0)

     cout<<" Error Error ("<<rowy<<","<<rowx<<")"<<endl;

     else

     {

      //

      cout<<"

      true"<<endl;

      wordlook(sn[0],sn);

     rowx++;

     }

      }

      i=0;

     }

     string ll=s 、substr(x,1);// 判断就是运算符还就是分界符

     wordlook(s[x],ll);

     if(fjf==0)// 就是运算符

     {

      i++;

      if((s[x+1]>64&&s[x+1]<91)||(s[x+1]>96&&s[x+1]<123)||(s[x+1]>=48&&s[x+1]<=57))// 如果后面就 是数字或字母

      {

     sn=s 、substr(xi+1,i);

     // cout<<sn<<" 运算符 i="<<i<<endl;

     cout<<sn<<" ";

     outkey=1;

     wordlook(sn[0],sn);

     rowx++;

      i=0;

      }

     }

     if(fjf==1)

     {

      if((s[x1]>64&&s[x1]<91)||(s[x1]>96&&s[x1]<123)||(s[x1]>=48&&s[x1]<=57))// 如 如果前面就是数字或字母

     {

     }

     else if(i>0)

     {

     sn=s 、substr(xi,i);

      // cout<<sn<<" 运算符 i="<<i<<endl;

     cout<<sn<<" ";

     outkey=1;

     wordlook(sn[0],sn);

     rowx++;

      i=0;

     }

     cout<<s[x]<<" (2,"<<s[x]<<") 符 分 界 符 ("<<rowy<<","<<rowx<<")"<<endl;

     rowx++;

     /*

     if(ll==";")

     {

     rowy++;

     rowx=1;

     }

     */

     }

      }

     } }; int main {

     int x;

     string instring;// 读入一行

     string sn; /*

      getline(cin,sn);// string 带空格输入

     cout<<sn<<endl;

     char t=sn[0];

     if(t>=48&&t<=57)

      searcht(1,sn);

     else

     {

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

      searcht(0,sn);

      else searcht(2,sn);

     } */

     ifstream input

      input(salaryfile); // inputfile>>noskipws;

     if(!inputfile)

     {

      cout<<"no file"<<endl;

      }

     string pp;

     while(!input)

      {

      getline(input);

      istringstream istr(pp);

      string ppword;

      while(istr>>ppword)// 按照空格分割字符串

      {

     split(ppword);

      } /*

      int begin = 0;// 去掉字符串得所有空格

      begin = pp 、find(" ",begin);

     // 查找空格在 str 中第一次出现得位置

      while(begin != 1)

     // 表示字符串中存在空格

      {

      pp 、replace(begin, 1, "");

     // 用空串替换 str 中从 begin 开始得 1 个字符 符

      begin = pp 、find(" ",begin);

     // 查找空格在替换后得 str 中第一次出现得位置

      }

      */ // cout<<"good

     "<<pp<<endl; // rowx++;

      rowy++;// 换行

      rowx=1;

     }

     return 0; } 七、 实验总结

     通过本次试验使我不仅对词法分析器有了更深得了解,而且提高了编程能力,希望在以后得学习中可以解决词法分析更多得问题。

     验 实验 2

     LL(1) 分析法

     一、 实验目得 通过完成预测分析法得语法分析程序,了解预测分析法与递归子程序法得区 别与联系。使学生了解语法分析得功能,掌握语法分析程序设计得原理与构造方 法,训练学生掌握开发应用程序得基本方法。有利于提高学生得专业素质,为培 养适应社会多方面需要得能力。

     二、 实验要求 1、编程时注意编程风格:空行得使用、注释得使用、缩进得使用等。

     2、如果遇到错误得表达式,应输出错误提示信息。

     3、对下列文法,用 LL(1)分析法对任意输入得符号串进行分析:

     (1)E>TG

     (2)G>+TG|—TG

     (3)G>ε

     (4)T>FS

     (5)S>*FS|/FS

     (6)S>ε

     (7)F>(E)

     (8)F>i

     三、 实验内容 根据某一文法编制调试

     LL (

     1 )分析程序,以便对任意输入得符号串 进行分析。

      构造预测分析表,并利用分析表与一个栈来实现对上述程序设计语言得分 析程序。

      分析法得功能就是利用 LL(1)控制程序根据显示栈栈顶内容、向前瞧符号 以及 LL(1)分析表,对输入符号串自上而下得分析过程。

     四、实验步骤

      1、根据流程图编写出各个模块得源程序代码上机调试。

     2、 编制好源程序后,设计若干用例对系统进行全面得上机测试,并通过所设计 得 LL(1)分析程序;直至能够得到完全满意得结果。

     3、书写实验报告 ;实验报告正文得内容:

      写出 LL(1)分析法得思想及写出符合 LL(1)分析法得文法。

      程序结构描述:函数调用格式、参数含义、返回值描述、函数功能;函数 之间得调用关系图。

      详细得算法描述(程序执行流程图) 。

      给出软件得测试方法与测试结果。

      实验总结 (设计得特点、不足、收获与体会)。

     五、实验 截图

      六、 核心代码

      #include<iostream> #include<string> using namespace std; string pp;// 输出字符串 string hh="\r\n";// 换行 const int max=50; int endfu[max];// 终止符序号表 int endfupointer=8; char endfureal[max]={"+","","*","/","(","i",")","#"}; int unendfu[max]; int unendfupointer=5; char unendfureal[max]={"E","G","T","S","F"}; string makemath[max]={"E>TG","G>+TG","G>TG","G>$","T>FS","S>*FS","S>/FS","S>$","F>(E)","F>i"}; //0 E>TG,1 G>+TG,2 G>TG,3 G>$,4 T>FS,5 S>*FS,6 S>/FS,7 S>$,8 F>(E),9 F>i //$ 代表空串 string behavior[max]={" 初始化","POP"}; int smarttable[max][max];// 分析表 int checkendfu(char fu)// 查终结符序号 {

     int x;

     for(x=0;x<endfupointer;x++)

     {

      if(endfureal[x]==fu)

     {

     break;

      }

     }

     if(x<endfupointer)

     return x;

     else return 1; }; int checkunendfu(char fu)// 查非终结符序号 {

     int x;

     for(x=0;x<unendfupointer;x++)

     {

      if(unendfureal[x]==fu)

     break;

     }

     if(x<unendfupointer)

     return x;

     else return1; }; string checkmakemath(int x)// 查产生式表 {

     return makemath[x]; }; int checksmarttable(int x,int y)// 查分析表 {

     return smarttable[x][y]; }; class smartbox { public:

     smartbox

     {

      box[0]="#";

      box[1]="E";

      boxpointer=1;

     }

     void push(char fu)

     {

      boxpointer++;

      box[boxpointer]=fu;

     }

     char pop

     {

     char a=box[boxpointer];

      if(a!="#")

      { //

     cout<<"pop: "<<boxpointer<<"

     "<<a<<endl; //

     stringstream oss; /*

      pp=pp+"pop: ";

      char buffer[max];

      sprintf(buffer,"%d",boxpointer);

      string s=buffer;

      pp=pp+" ";

      pp=pp+s;

      pp=pp+hh; */

      boxpointer;

      return a;

      }

     }

     void check

     {

      if(checkendfu(box[boxpointer])!=1)

      {

      char a; //

     cout<<box[boxpointer]<<checkendfu(box[boxpointer])<<"

      ";

      //char buffer[max];

      //sprintf(buffer //

     pp=pp+box[boxpointer];

     // pp=pp+checkendfu(box[boxpointer]); //

     pp=pp+"

      ";

      a=pop;

     // cout<<"out "<<a<<endl;

      }

     }

     char box[max];

     int boxpointer; }; int main {

     // TODO: Add extra validation here // pp=pp+" 步骤

     分析栈

      剩余输入串

     所用产生式

      动作"+hh; /*

     string s1="sdsfs

     \r\nsdfsds";

     string s3="aaaaaaaaaaaaa";

     s3=s3+s1;

      CString s2(s3 、c_str); // CString s2=CString(s1);

     SetDlgItemText(IDC_EDIT2,s2);// 用 SetDlgItemText( 文本框 ID, 字符串), 将文本框得内容设置为字符串得内容、

     SetDlgItemText(IDC_EDIT2,s2); */ // MessageBox(str); string str; cin>>str;

     int x,y;

     for(x=0;x<max;x++)

     // 初始化分析表 99 为错误代号

      for(y=0;y<max;y++)

     smarttable[x][y]=99;

      smarttable[0][4]=0;

     smarttable[0][5]=0;

     smarttable[1][0]=1;

     smarttable[1][1]=2;

     smarttable[1][6]=3;

     smarttable[1][7]=3;

     smarttable[2][4]=4;

     smarttable[2][5]=4;

     smarttable[3][0]=7;

     smarttable[3][1]=7;

     smarttable[3][2]=5;

     smarttable[3][3]=5;

     smarttable[3][6]=7;

     smarttable[3][7]=7;

     smarttable[4][4]=8;

     smarttable[4][5]=9;

     smartbox mark;

     char fu;

     char enterfu;

     int endfunumber;

     int unendfunumber;

     string readyin;

     string enter; // cin>>enter;

     //enter="i+i*i#";

     enter=str; //enter="(i)#";

     int count=0; // 步骤

     char buffer1[max];

      sprintf(buffer1,"%d",count);

     string s1=buffer1;

     pp=pp+s1+"

      ";

      // 分析栈

     for(int qq1=0;qq1<=mark 、boxpointer;qq1++)

     {

      pp=pp+mark 、box[qq1];

     }

     for(qq1=0;qq1<10mark 、boxpointer;qq1++)

     {

      pp=pp+" ";

     }

     // 剩余输入栈

     string jiequ1=enter 、substr(0,enter 、length);

     pp=pp+jiequ1;

     for(int t1=0;t1<20;t1++)

     {

      pp=pp+" ";

     }

     pp=pp+"

      初始化"+hh;

     for(x=0;x<enter 、length;)

     {

     // 步骤

      count++;

     char buffer[max];

      sprintf(buffer,"%d",count);

      string s=buffer;

     pp=pp+s+"

      ";

      // 分析栈

     for(int qq=0;qq<=mark 、boxpointer;qq++)

     {

      pp=pp+mark 、box[qq];

     }

     for(qq=0;qq<10mark 、boxpointer;qq++)

     {

      pp=pp+" ";

     }

     // 剩余输入栈

     string jiequ=enter 、substr(x,enter 、lengthx);

     pp=pp+jiequ;

     for(int t=0;t<x+10;t++)

     {

      pp=pp+" ";

     }

      enterfu=enter[x];

      // cout<<"enterfu: "<<enterfu<<endl;

      mark 、check;

      fu=mark 、pop; //

     cout<<"fu: "<<fu<<endl;

      if(fu=="#")//&&enterfu=="#")

      {

     //

     cout<<"sucessed!!!!

      over!!!!"<<endl;

     pp=pp+"sucessed!!!!

      over!!!!"+hh;

     break;

      }

      unendfunumber=checkunendfu(fu);

      endfunumber=checkendfu(enterfu);

     // cout<<unendfunumber<<endl;

     // cout<<endfunumber<<endl;

      if(smarttable[unendfunumber][endfunumber]==99)

      {

     pp=pp+"error!!";

     break;

      }

      readyin=makemath[smarttable[unendfunumber][endfunumber]];

      pp=pp+readyin;

      for(int ddd=0;ddd<14readyin 、length;ddd++)

      {

     pp=pp+" ";

      }

     pp=pp+"POP,PUSH(";

      for(y=readyin 、length1;y>2;y)

      {

     pp=pp+readyin[y];

      }

      pp=pp+")"+hh;

     // cout<<"readyin:

     "<<readyin<<endl;

      int firsttime=0;

      for(y=readyin 、length1;y>2;y)

      {

      // cout<<readyin[y]<<" ";

     if(readyin[y]!="$")

     {

      mark 、push(readyin[y]);

      if(firsttime==0)

      {

     if(checkendfu(readyin[y])!=1)

      {

     //

     cout<<"now x: "<<x<<"

     ";

     // 步骤

      count++;

     char buffer[max];

      sprintf(buffer,"%d",count);

      string s=buffer;

     pp=pp+s+"

      ";

      // 分析栈

     for(int qq=0;qq<=mark 、boxpointer;qq++)

     {

      pp=pp+mark 、box[qq];

     }

     for(qq=0;qq<10mark 、boxpointer;qq++)

     {

      pp=pp+" ";

     }

     // 剩余输入栈

     string jiequ=enter 、substr(x,enter 、lengthx);

     pp=pp+jiequ;

     for(int t=0;t<x+10;t++)

     {

      pp=pp+" ";

     }

     pp=pp+"

     GETNEXT(I)"+hh;

     x++;

     //

      cout<<"next x: "<<x<<"

     "<<endl;

     firsttime=1;

      }

      }

     }

      }

      mark 、check;

     // cout<<endl; //

     pp=pp+hh;

     } cout<<pp; return 0;

     //CDialog::OnOK; } 七、 实验总结

      通过本次试验使我不仅对 ll(1)分析法有了更深得了解,而且提高了编程能力,希望在以后得学习中可以解决自动构造 follow 集得问题。

      实验 3

      LR(1) 分析法

     一、 实验目得 构造 LR(1)分析程序,利用它进行语法分析,判断给出得符号串就是否为该文 法识别得句子,了解 LR(K)分析方法就是严格得从左向右扫描,与自底向上得 语法分析方法。

     二、 实验要求 1、编程时注意编程风格:空行得使用、注释得使用、缩进得使用等。

     2、如果遇到错误得表达式,应输出错误提示信息。

     3、程序输入/输出实例:

     输入一以#结束得符号串(包括+*i#):在此位置输入符号串

     输出过程如下:

     步骤

     状态栈

     符号栈

     剩余输入串

     动 作

      1

     0

      #

     i+i*i#

     移进

      i+i*i 得 LR 分析过程

     步骤

     状态栈

     符号栈

     输入串

     动作说明

     1

     0

     #

     i+i*i#

     ACTION[0,i]=S5,状态 5 入栈

     2

     05

     #i

     +i*i#

     r6: F→i 归约,GOTO(0,F)=3 入栈

     3

     03

     #F

     +i*i#

     r4: T→F 归约,GOTO(0,T)=3 入栈

     4

     02

     #T

     +i*i#

     r2: E→T 归约,GOTO(0,E)=1 入栈

     5

     01

     #E

     +i*i#

     ACTION[1,+]=S6,状态 6 入栈

     6

     016

     #E+

     i*i#

     ACTION[6,i]=S5,状态 5 入栈

     7

     0165

     #E+i

     *i#

     r6: F→i 归约,GOTO(6,F)=3 入栈

     8

     0163

     #E+F

     *i#

     r4: T→F 归约,GOTO(6,T)=9 入栈

     9

     0169

     #E+T

     *i#

     ACTION[9,*]=S7,状态 7 入栈

     10

     01697

     #E+T*

     i#

     ACTION[7,i]=S5,状态 5 入栈

     11

     016975

     #E+T*i

     #

     r6:F→i 归约,GOTO(7,F)=10 入栈

     12

     0169710

     #E+T*F

     #

     r3: T→T*F 归约,GOTO(6,T)=9 入栈

     13

     0169

     #E+T

     #

     r1:E→E+T,GOTO(0,E)=1 入栈

     14

     01

     #E

     #

     Acc:分析成功

     三、 实验内容 对下列文法,用 LR(1)分析法对任意输入得符号串进行分析:

     (1)E> E+T

     (2)E>T

     (3)T> T*F

     (4)T>F

     (5)F> (E)

     (6)F> i

     四、实验步骤 1、根据流程图编写出各个模块得源程序代码上机调试。

     2、编制好源程序后,设计若干用例对系统进行全面得上机测试,并通过所设计 得 LR(1)语法分析程序;直至能够得到完全满意得结果。

     3、书写实验报告 ;实验报告正文得内容:

      描述 LR(1)语法分析程序得设计思想。

      程序结构描述:函数调用格式、参数含义、返回值描述、函数功能;函数

     之间得调用关系图。

      详细得算法描述(程序执行流程图) 。

      给出软件得测试方法与测试结果。

     五、实验 截图

      六、 核心代码 #include<iostream> #include<string> using namespace std; int count=1; string pp;// 输出字符串 string hh="\r\n";// 换行 const int max=100; char endfureal[max]={"i","+","*","(",")","#","E","T","F"}; int endfupointer=8; string creatword[max]={"E>E+T","E>T","T>T*F","T>F","F>(E)","F>i"}; //(0)E> E+T(1)E>T (2)T> T*F (3)T>F (4)F> (E) (5)F> i

      // 注意 rj 时 时 j 应对应数组下标 int checkendfu(char fu)// 查终结符序号 {

     int x;

     for(x=0;x<=endfupointer;x++)

     {

      if(endfureal[x]==fu)

      {

     break;

      }

      }

     if(x<=endfupointer)

     return x;

     else return 1; }; class actiongo// 原子动作 { public:actiongo

      {

      // cout<<"eroor! wrong action or goto creat"<<endl;

     actype=4;

      }

      action(int i,int j)

      {

     actype=i;

     number=j;

     //

     cout<<i<<" "<<j<<endl;

      }

      int actype;//0=s 1=r 2=acc 3=goto 表 4=wrong

      int number; }; actiongo smarttable[max][max]; class stylebox// 状态栈 { public:

     stylebox

     {

      box[0]=0;

      boxpointer=0;

     }

     void push(int style)

     {

      boxpointer++;

      box[boxpointer]=style;

     }

     int pop

     {

      int a=box[boxpointer];

     boxpointer; //

     cout<<"pop now"<<endl;

      return a;

     }

     int box[max];

     int boxpointer;

     }; class readybox// 已归约栈 { public:

     readybox

     {

      box[0]="#";

      boxpointer=0;

     }

     void push(char fu)

     {

      boxpointer++;

      box[boxpointer]=fu;

     }

     char pop

     {

      char a=box[boxpointer];

      boxpointer;

      return a;

     }

     char box[max];

     int boxpointer; }; int program(stylebox&style,readybox&ready,char fu,int icount,string ptr,int control)// 返回就是否需要移进信号 { if(control==1) {

      //////////////////////////////

     char ber[max];

      sprintf(ber,"%d",count);

      string st=ber;

     pp=pp+st+"

     ";

      count++;

      ////////////////////////////////////

     //

      pp=pp+"

      ";

     for(int qq=0;qq<=style 、boxpointer;qq++)

     {

     char bss[max];

     sprintf(bss,"%d",style 、box[qq]);

     string st=bss;

      pp=pp+st;

     }

      for(qq=0;qq<10style 、boxpointer;qq++)

     {

      pp=pp+" ";

     }

     for( qq=0;qq<=ready 、boxpointer;qq++)

     {

      pp=pp+ready 、box[qq];

     }

     for(qq=0;qq<10ready 、boxpointer;qq++)

     {

      pp=pp+" ";

     }

     for(int dj=icount;dj<ptr 、length;dj++)

     {

      pp=pp+ptr[dj];

     }

     pp=pp+"

      "; //

      ////////////////////////////////////////

     }

     int i=style 、pop;// 如果就是 s 则状态还要入栈 // cout<<" 现在状态"<<i;

     int j=checkendfu(fu);

     if(j==1)

     {

      pp=pp+"error!!!";

      return 4;//wrong!!!

     } // cout<<"

     现在符号: "<<fu<<" "<<j<<endl;

     int checkstyle=smarttable[i][j] 、actype;// 查表

     if(checkstyle==4)

     {

      pp=pp+"error!!!";

      return 4;//wrong!!!

     }

     if(checkstyle==0||checkstyle==3)

     {

      style 、push(i);// 如果就是 s 则状态还要入栈

      if(checkstyle==0)

      {

     //cout<<"ACTION["<<i<<","<<fu<<"]=S"<<smarttable[i][j] 、number<<",状 状态 态"<<smarttable[i][j] 、number<<" 入栈"<<endl;

     pp=pp+"ACTION[";

      char buffer[max];

     sprintf(buffer,"%d",i);

      string s=buffer;

      pp=pp+s;

      pp=pp+",";

      pp=pp+fu;

      pp=pp+"]=S";

     char buf[max];

      sprintf(buf,"%d",smarttable[i][j] 、number);

      s=buf;

      pp=pp+s;

      pp=pp+", 状态";

      pp=pp+s+" 入栈"+hh;

      }

      if(checkstyle==3)

      {

      // cout<<i<<","<<endfureal[j]<<")="<<smarttable[i][j] 、 number<<"入栈"<<endl;

      char bf[max];

      sprintf(bf,"%d",i);

      string s=bf;

      pp=pp+s;

      pp=pp+","+endfureal[j]+")=";

     char bfff[max];

      sprintf(bfff,"%d",smarttable[i][j] 、number);

     s=bfff;

      pp=pp+s+" 入栈"+hh;

      }

      ready 、push(fu);

      style 、push(smarttable[i][j] 、number); //

     cout<<style 、box[style 、boxpointer]<<endl;

      return 1;// 移进

     }

     if(checkstyle==1)

     {

      string l=creatword[smarttable[i][j] 、number];

     // cout<<"r"<<smarttable[i][j] 、number+1<<": "<<l<<" 归约,GOTO(";

      pp=pp+"r";

      int dd=smarttable[i][j] 、number+1;

      char bfc[max];

      sprintf(bfc,"%d",dd);

      string ss=bfc;

     pp=pp+ss+": "+l+" 归约,GOTO(";

      char n;//pop 用得

      int x;

      // cout<<l 、length<<endl;

      char sq=ready 、pop;

      for(x=0;x<l 、length4;x++)// 前面 pop 一次了

      {

     n=style 、pop;

     n=ready 、pop; //

      cout<<n<<endl;

      }

     // cout<<l[0]<<endl;

      x=program(style,ready,l[0],icount,ptr,0);// 识别非终结符

      return 0;// 归约

     }

     if(checkstyle==2)

      {

      return 2;// 接受

     } } int main {

     // TODO: Add extra validation here

     string str;

     cin>>str; //0=i 1=+ 2=* 3=( 4=) 5=# 6=E 7=T 8=F

     smarttable[0][0] 、action(0,5);

     smarttable[0][3] 、action(0,4);

     smarttable[0][6] 、action(3,1);

     smarttable[0][7] 、action(3,2);

     smarttable[0][8] 、action(3,3);

     smarttable[1][1] 、action(0,6);

     smarttable[1][5] 、action(2,0);

     smarttable[2][1] 、action(1,1);

     smarttable[2][2] 、action(0,7);

     smarttable[2][4] 、action(1,1);

     smarttable[2][5] 、action(1,1);

     smarttable[3][1] 、action(1,3);

     smarttable[3][2] 、action(1,3);

     smarttable[3][4] 、action(1,3);

     smarttable[3][5] 、action(1,3);

     smarttable[4][0] 、action(0,5);

     smarttable[4][3] 、action(0,4);

     smarttable[4][6] 、action(3,8);

     smarttable[4][7] 、action(3,2);

     smarttable[4][8] 、action(3,3);

     smarttable[5][1] 、action(1,5);

      smarttable[5][2] 、action(1,5);

     smarttable[5][4] 、action(1,5);

     smarttable[5][5] 、action(1,5);

     smarttable[6][0] 、action(0,5);

     smarttable[6][3] 、action(0,4);

     smarttable[6][7] 、action(3,9);

     smarttable[6][8] 、action(3,3);

     smarttable[7][0] 、action(0,5);

     smarttable[7][3] 、action(0,4);

     smarttable[7][8] 、action(3,10);

     smarttable[8][1] 、action(0,6);

     smarttable[8][4] 、action(0,11);

     smarttable[9][1] 、action(1,0);

     smarttable[9][2] 、action(0,7);

     smarttable[9][4] 、action(1,0);

     smarttable[9][5] 、action(1,0);

     smarttable[10][1] 、action(1,2);

     smarttable[10][2] 、action(1,2);

     smarttable[10][4] 、action(1,2);

     smarttable[10][5] 、action(1,2);

     smarttable[11][1] 、action(1,4);

     smarttable[11][2] 、action(1,4);

     smarttable[11][4] 、action(1,4);

     smarttable[11][5] 、action(1,4); string enter=str;

     int i;

     int x;

     stylebox st;

     readybox ready;

     for(i=0;i<enter 、length;)

     {

     // cout<<"enter:

      "<<enter[i]<<"

     "<<endl;

      x=program(st,ready,enter[i],i,enter,1);

      if(x==1)i++;

      if(x==2)

      {

      // cout<<"Acc: 分析成功 功"<<endl;

     pp=pp+"Acc: 分析成功"+hh;

     break;

      }

      if(x==4)

     break;

     // cout<<endl;

     // cout<<endl;

      // pp=pp+hh;

     } cout<<pp; // CDialog::OnOK; } 七、 实验总结

      通过本次试验使我不仅对 LR(1)分析法有了更深得了解,而且提高了编程能力,希望在以后得学习中可以解决 LR(1)中确定化得问题。

    • 范文大全
    • 职场知识
    • 精美散文
    • 名著
    • 讲坛
    • 诗歌
    • 礼仪知识