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

时间:2024.5.2

                        词法分析

一、实验目的

设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。

二、实验要求

2.1 待分析的简单的词法

(1)关键字:

 begin  if  then  while  do  end

所有的关键字都是小写。

(2)运算符和界符

: =  +  -  *  /  <  <=  <>  >  >=  =  ; (  )  #

(3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义:

ID = letter (letter | digit)*

NUM = digit digit*

(4)空格有空白、制表符和换行符组成。空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。

2.2 各种单词符号对应的种别码:

表2.1 各种单词符号对应的种别码

2.3 词法分析程序的功能:

输入:所给文法的源程序字符串。

输出:二元组(syn,token或sum)构成的序列。

其中:syn为单词种别码;

      token为存放的单词自身字符串;

      sum为整型常数。

例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列:

(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)……

三、词法分析程序的算法思想:

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

3.1 主程序示意图:

主程序示意图如图3-1所示。其中初始包括以下两个方面:

⑴ 关键字表的初值。

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

Char *rwtab[6] = {“begin”, “if”, “then”, “while”, “do”, “end”,};

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

图3-1

(2)程序中需要用到的主要变量为syn,token和sum

3.2 扫描子程序的算法思想:

首先设置3个变量:①token用来存放构成单词符号的字符串;②sum用来整型单词;③syn用来存放单词符号的种别码。扫描子程序主要部分流程如图3-2所示。

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

图 3-2

四、词法分析程序的C语言程序源代码:

#include

#include

#include

#include

char prog[80],token[8],ch;

int syn,p,m,n,sum;

char *rwtab[6]={"begin","if","then","while","do","end"};

 scaner();

main()

{p=0;

 printf("\n please input a string(end with '#'):\n");

 do{

    scanf("%c",&ch);

    prog[p++]=ch;

    }while(ch!='#');

 p=0;

 do{

    scaner();

    switch(syn)

     {case 11:printf("( %-10d%5d )\n",sum,syn);

          break;

      case -1:printf("you have input a wrong string\n");

          getch();

          exit(0);

      default: printf("( %-10s%5d )\n",token,syn);

          break;

      }

    }while(syn!=0);

    getch();

 }

 scaner()

 {  sum=0;

    for(m=0;m<8;m++)token[m++]=NULL;

    ch=prog[p++];

    m=0;

    while((ch==' ')||(ch=='\n'))ch=prog[p++];

    if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A')))

      { while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9')))

      {token[m++]=ch;

       ch=prog[p++];

      }

      p--;

      syn=10;

      for(n=0;n<6;n++)

    if(strcmp(token,rwtab[n])==0)

       { syn=n+1;

         break;

       }

      }

    else if((ch>='0')&&(ch<='9'))

      { while((ch>='0')&&(ch<='9'))

    { sum=sum*10+ch-'0';

      ch=prog[p++];

    }

    p--;

    syn=11;

      }

    else switch(ch)

    { case '<':token[m++]=ch;

          ch=prog[p++];

           if(ch=='=')

            {  syn=22;

               token[m++]=ch;

            }

          else

            {  syn=20;

               p--;

            }

          break;

     case '>':token[m++]=ch;

          ch=prog[p++];

          if(ch=='=')

            { syn=24;

              token[m++]=ch;

            }

          else

            { syn=23;

              p--;

            }

          break;

     case '+': token[m++]=ch;

          ch=prog[p++];

          if(ch=='+')

            { syn=17;

              token[m++]=ch;

            }

          else

            { syn=13;

              p--;

            }

          break;

     case '-':token[m++]=ch;

          ch=prog[p++];

          if(ch=='-')

            { syn=29;

              token[m++]=ch;

            }

          else

            { syn=14;

              p--;

            }

          break;

     case '!':ch=prog[p++];

          if(ch=='=')

           { syn=21;

             token[m++]=ch;

           }

          else

          { syn=31;

             p--;

          }

          break;

     case '=':token[m++]=ch;

          ch=prog[p++];

          if(ch=='=')

            { syn=25;

              token[m++]=ch;

            }

          else

            { syn=18;

              p--;

            }

          break;

     case '*': syn=15;

           token[m++]=ch;

           break;

     case '/': syn=16;

           token[m++]=ch;

           break;

     case '(': syn=27;

           token[m++]=ch;

           break;

     case ')': syn=28;

           token[m++]=ch;

           break;

     case '{': syn=5;

           token[m++]=ch;

           break;

     case '}': syn=6;

           token[m++]=ch;

           break;

     case ';': syn=26;

          token[m++]=ch;

          break;

     case '\"': syn=30;

           token[m++]=ch;

           break;

     case '#': syn=0;

           token[m++]=ch;

           break;

     case ':':syn=17;

           token[m++]=ch;

           break;

    default: syn=-1;

         break;

       }

    token[m++]='\0';

    }

五、结果分析:

输入begin x:=9: if x>9 then x:=2*x+1/3; end # 后经词法分析输出如下序列:(begin  1)(x  10)(:17)(=  18)(9  11)(;26)(if   2)……  如图5-1所示:

                                图5-1

六、总结:

词法分析的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。通过本试验的完成,更加加深了对词法分析原理的理解。

                            语法分析

一、实验目的

编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。

二、实验要求

利用C语言编制递归下降分析程序,并对简单语言进行语法分析。

2.1 待分析的简单语言的语法

用扩充的BNF表示如下:

⑴<程序>::=begin<语句串>end

⑵<语句串>::=<语句>{;<语句>}

⑶<语句>::=<赋值语句>

⑷<赋值语句>::=ID:=<表达式>

⑸<表达式>::=<项>{+<项> | -<项>}

⑹<项>::=<因子>{*<因子> | /<因子>

⑺<因子>::=ID | NUM | (<表达式>)

2.2 实验要求说明

输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”。

例如:

    输入  begin a:=9; x:=2*3; b:=a+x end #

    输出  success!

    输入  x:=a+b*c end #

    输出  error

2.3 语法分析程序的酸法思想

(1)主程序示意图如图2-1所示。

 

图2-1 语法分析主程序示意图

(2)递归下降分析程序示意图如图2-2所示。

(3)语句串分析过程示意图如图2-3所示。

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

(4)statement语句分析程序流程如图2-4、2-5、2-6、2-7所示。

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

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

三、语法分析程序的C语言程序源代码:

#include "stdio.h"
#include "string.h"
char prog[100],token[8],ch;
char *rwtab[6]={"begin","if","then","while","do","end"};
int syn,p,m,n,sum;
int kk;
factor();
expression();
yucu();
term();
statement();
lrparser();
scaner();
main()
{
 p=kk=0;
 printf("\nplease input a string (end with '#'): \n");
 do
   { scanf("%c",&ch);
     prog[p++]=ch;
   }while(ch!='#');
 p=0;
 scaner();
 lrparser();
 getch();
}
lrparser()
{
 if(syn==1)
   {

scaner();       /*读下一个单词符号*/
     yucu();     /*调用yucu()函数;*/
     if (syn==6)
       { scaner();
  if ((syn==0)&&(kk==0))

 printf("success!\n");
 }
     else { if(kk!=1) printf("the string haven't got a 'end'!\n");
     kk=1;
   }
    }
 else { printf("haven't got a 'begin'!\n");
 kk=1;
       }
 return;
}
yucu()
{

statement();         /*调用函数statement();*/
  while(syn==26)
   {

 scaner();          /*读下一个单词符号*/
    if(syn!=6)

statement();         /*调用函数statement();*/
   }
  return;
}
statement()
{ if(syn==10)
   {

 scaner();        /*读下一个单词符号*/
     if(syn==18)
       { scaner();      /*读下一个单词符号*/
  expression();      /*调用函数statement();*/
       }
     else { printf("the sing ':=' is wrong!\n");
     kk=1;
    }
   }
  else { printf("wrong sentence!\n");
  kk=1;
       }
  return;
}
expression()
{ term();
  while((syn==13)||(syn==14))
    { scaner();             /*读下一个单词符号*/
      term();               /*调用函数term();*/
    }
  return;
}
term()
{ factor();
  while((syn==15)||(syn==16))
    { scaner();             /*读下一个单词符号*/
      factor();              /*调用函数factor(); */
    }
  return;
}
factor()
{ if((syn==10)||(syn==11)) scaner();
  else if(syn==27)
    { scaner();           /*读下一个单词符号*/
      expression();        /*调用函数statement();*/
      if(syn==28)

scaner();          /*读下一个单词符号*/
      else { printf("the error on '('\n");
      kk=1;
     }
    }
  else { printf("the expression error!\n");
  kk=1;
       }
  return;
}
 scaner()
 {  sum=0;
    for(m=0;m<8;m++)token[m++]=NULL;
    m=0;
    ch=prog[p++];
    while(ch==' ')ch=prog[p++];
    if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A')))
      { while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9')))
   {token[m++]=ch;
    ch=prog[p++];
   }
      p--;
      syn=10;
      token[m++]='\0';
      for(n=0;n<6;n++)
 if(strcmp(token,rwtab[n])==0)
    { syn=n+1;
      break;
    }
      }
    else if((ch>='0')&&(ch<='9'))
      { while((ch>='0')&&(ch<='9'))
 { sum=sum*10+ch-'0';
   ch=prog[p++];
 }
 p--;
 syn=11;
      }
    else switch(ch)
       { case '<':m=0;
    ch=prog[p++];
    if(ch=='>')
      {  syn=21;
      }
    else if(ch=='=')
      {  syn=22;
      }
    else
      {  syn=20;
         p--;
      }
    break;
  case '>':m=0;
    ch=prog[p++];
    if(ch=='=')
      { syn=24;
      }
    else
      { syn=23;
        p--;
      }
    break;
  case ':':m=0;
    ch=prog[p++];
    if(ch=='=')
      { syn=18;
      }
    else
      { syn=17;
        p--;
      }
    break;
  case '+': syn=13; break;
  case '-': syn=14; break;
  case '*': syn=15;break;
  case '/': syn=16;break;
  case '(': syn=27;break;
  case ')': syn=28;break;
  case '=': syn=25;break;
  case ';': syn=26;break;
  case '#': syn=0;break;
 default: syn=-1;break;
       }
    }

四、结果分析:

输入 begin a:=9; x:=2*3; b:=a+x end # 后输出success! 如图4-1所示:

图4-1

输入 x:=a+b*c end  #  后输出  error 如图4-2所示:

图4-2

五、总结:

通过本次试验,了解了语法分析的运行过程,主程序大致流程为:“置初值”à调用scaner函数读下一个单词符号à调用IrParseà结束。递归下降分析的大致流程为:“先判断是否为begin”à不是则“出错处理”,若是则“调用scaner函数”à调用语句串分析函数à“判断是否为end”à不是则“出错处理”,若是则调用scaner函数à“判断syn=0&&kk=0是否成立”成立则说明分析成功打印出来。不成立则“出错处理”。

更多相关推荐:
编译原理语法分析报告+代码

语法分析一、实验目的编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。二、实验要求利用C语言编制递归下降分析程序,并对简单语言进行语法分析。2.1待分析的简单语言的语法用扩充的B…

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

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

编译原理语法分析实验报告(含有源代码)

《编译原理》实验报告

编译原理LL(1)语法分析实验报告

学号20xx2798专业软件工程姓名薛建东实验日期20xx0408教师签字成绩实验报告实验名称LL1语法分析实验目的通过完成预测分析法的语法分析程序了解预测分析法和递归子程序法的区别和联系使了解语法分析的功能掌...

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

目录一语法分析方法11判断为算符优先文法12求FirstVT集和LastVT集13根据FirstVT和LastVT集构造算符优先表1二程序设计21总体设计22子程序设计2三程序中的结构说明31重要函数介绍32函...

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

南华大学计算机科学与技术学院实验报告20xx20xx学年度第二学期课程名称实验名称姓名专业地点寻友旭软件工程6413学号20xx4350227编译原理语法分析班级软件工程052班教师陈星南华大学计算机科学与技术...

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

课程实验报告课程名称:编译原理(语法分析)专业班级:信息安全1001班学号:姓名:指导教师:报告日期:20XX/11/8计算机科学与技术学院1、实验目的1)设计并编制一个语法分析程序,加深对语法分析程序中递归下…

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

TitlecLR语法分析器cppAuthorvolantfishnum10211xxxClass20xx211309Date20xx11volantfishIntroductionVersionincludel...

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

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

编译原理课程设计(语法分析程序)

编译原理实验报告题目:对下面的文法对象,使用c语言构造它的预测分析程序;并任意给一算术表达式进行分析测试.分析对象对象定义如下:实验日期:20##-6-15至20##-6-30指导教师:班级:计算机029班学号…

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

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

编译原理实验报告(PL_0语言功能扩充)

编译原理课程实验报告题目PL0编译程序的C语言扩充专业化学工程与工艺班级学号姓名任课教师华东理工大学信息学院一实验题目PL0编译程序的C语言扩充二实验目的在分析理解PL0编译程序的基础上对其词法分析程序语法分析...

编译原理语法分析报告(37篇)