简单算符优先文法分析程序(编译原理)

 

题目

 

                    实现算符优先文法分析程序;完成对以下表达式文法的分析程序。

       G[E]:

            E->E+T

            E->T

            T->T*F

            T->F

            F->(E)

            F->i

 

 

 

优先关系表

            

    +      

    *      

    i       

    (       

    )      

     #      

   +

    >

    <

    <

    <

   >

    >

   *

    >

    >

    <

    <

   > 

    >

   i  

    >

    >

 

 

   >

    > 

   (

    <

    <

    <

    <

   =

  

   )

    >

    >

 

 

   >

    >

   #

    <

    <

    <

    <

  

    =

 

 

 

 

测试结果

 

 

 

 

 

源程序:

 

 

 

#include<stdio.h>

int find(int a,int b)   //优先关系表
{
    int table[6][6] = {
                       1, -1, -1, -1, 1, 1,
                       1,  1, -1, -1, 1, 1,
                       1,  1,  2,  2, 1, 1,
                      -1,- 1, -1, -1, 0, 2,
                       1,  1,  2,  2, 1, 1,
                      -1, -1,- 1, -1, 2, 0
                      };

  return table[a-1][b-1];

}


int in_vt(char c)    //可以根据返回的数值去优先关系表里面查找优先关系
{                    //还可以判断是否是非终结符,不是非终结符返回0
   int n;

   switch(c)
   {
       case '+': n = 1; break;
       case '*': n = 2; break;
       case 'i': n = 3; break;
       case '(': n = 4; break;
       case ')': n = 5; break;
       case '#': n = 6; break;
       default : n = 0;
   }

   return n;

}




int judge(char *p,int k,char *psc)
{

        if(k == 1 && p[k] == '#' && (*psc == '+' || *psc == '*'))
        {
                printf("\n运算符前面没有操作数!\n");
                return 0;
        }
        if((*psc == '+' || *psc == '*') && (*(psc + 1) == '+' || *(psc + 1) == '*'))
        {
                printf("\n运算符号相邻!\n");
                return 0;
        }
        if(*psc == '#' && (*(psc - 1) == '+' || *(psc - 1) == '*'))
        {
                printf("\n运算符后面没有操作数!\n");
                return 0;
        }
        return 1;
}



int main()
{
   int  k;                   //栈顶指针
   char s[30] = {'\0'};      //分析栈
   char *ss;
   char in_c[50] = {'\0'};   //输入串
   char *psc;                //指向当前输入符号
   int  j;
   char q;
   int  flag;
   int  n;

while(1)
{

   printf("\n************************************\n");
   printf("请输入要归约的字符串(以‘#’结束):");
   scanf("%s",in_c);

   n = 1;          //记录步骤
   k = 1;
   s[k] = '#';
   s[k+1] = '\0';    //初始化
   ss = s + 1;       //指向栈底
   psc = in_c;


   printf("\n步骤\t栈内字符\t\t优先关系\t当前符号\t剩余输入串\t\t\t移进或归约\n");
   while(1)
   {
          if(judge(s,k,psc) == 0)
          {
                  printf("\n出错!\n");
                  break;
          }

          if(in_vt(s[k]))
              j = k;
          else
              j = k - 1;

          flag = find(in_vt(s[j]),in_vt(*psc));
          if(flag == 1)  //如果s[j] > 当前输入字符
          {
               do
               {
                   q = s[j];
                   if(in_vt(s[j-1]))
                        j--;
                   else
                        j = j - 2;
               }while(find(in_vt(s[j]),in_vt(q)) != -1);

               printf("(%d)\t%-24s>\t\t%c\t\t%-32s归约\n",n++,ss,*psc,psc+1);
               k = j + 1;
               s[k] = 'N';
               s[k+1] = '\0';
               continue;
          }
          else if(flag == -1)
               {
                   printf("(%d)\t%-24s<\t\t%c\t\t",n++,ss,*psc);
                   k++;
                   s[k] = *psc;
                   s[k+1] = '\0';
                   psc++;
                   printf("%-32s移进\n",psc);
                   continue;
               }
               else if(flag == 0)
                    {
                          if(s[j] == '#')
                          {
                               printf("(%d)\t%-24s=\t\t#\t\t\t\t\t\t接受\n",n,ss);
                               printf("\n归约成功!\n");
                               break;
                          }
                          else
                          {
                               printf("(%d)\t%-24s=\t\t%c\t\t",n++,ss,*psc);
                               k++;
                               s[k] = *psc;
                               s[k+1] = '\0';
                               psc++;
                               printf("%-32s移进\n",psc);
                               continue;
                          }
                     }
                     else
                     {
                          printf("(%d)\t%-24s无\t\t%c\t\t%-32s\\\n",n++,ss,*psc,psc+1);
                          printf("\n错误!\n");
                          break;
                     }



   }

}


 return 0;
}


 

 

算符优先分析文法是一种工具,在编译的过程中,隶属于语法分析环节,却又与中间代码的生成息息相关,编译可以分为五个阶段:词法分析、语法分析、语义分析(中间代码的生成)、代码优化、目标代码生成。语法分析是指:在词法分析基础上,将单词符号串转化为语法单位(语法范畴)(短语、子句、句子、程序段、程序),并确定整个输入串是否构成语法上正确的程序。也就是说语法分析是检验输入串的语法是否正确,注意这里的语法正确,只是简单地符合自己定义的规范,而不能检测出运行时错误,比如"X/0",空指针错误,对象未初始化等错误。在这一个实验中,我将通过算符优先分析文法这一个工具,在语法分析的时候,顺便进行语义分析,也就是识别出语法单位,同时简要的将识别出的中间代码进行计算(目标代码的生成+运行),得到相应的结果,来检验自己设计的正确性。可以说题目虽然叫做算符优先分析文法,其实却是一个贯穿了“词法分析+语法分析+语义分析+中间代码优化+目标代码生成+运行”全过程的一个极具概括性的程序。如果能将这个程序得心应手的完成出来,我相信诸位对编译原理的掌握也算是炉火纯青了。时隔将近两年再来整理自己以前写过的实验报告,还是挺有感慨的,对一件东西感兴趣,原来影响还会如此深远,还记得自己当时连续六个小时全神贯注写出的实验报告,现在看看竟然写了五六十页,核心内容也有三四十页,不觉的感慨当年充满热情的时代慢慢的竟走出许久
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值