编译原理:简单优先文法分析实验

该博客探讨了简单优先文法的概念,包括短语、直接短语和句柄等概念,并详细解释了简单优先文法的判断标准和分析步骤。通过C语言实现了一个简单优先分析器,用于分析输入的字符串是否符合给定的简单优先文法。然而,该实现目前无法判断输入文法是否为简单优先文法。
摘要由CSDN通过智能技术生成

实验目的

运用简单优先语法分析的基本原理实现对于句子的语法分析

实验要求

1、文法及待分析符号串由用户输入
2、数据结构可自行设计

实验内容

1、任意输入一个文法,判断它是否为简单优先文法
2、如果是,请构造该文法对应的算符优先分析表
3、输入一个字符串,判断它是否为该文法的一个句子。

知识储备

首先要知道一些知识点
给出一个语法树:
在这里插入图片描述
短语:
若S=*=>αAδ且A=+=>β,则称β是相对于非终结符A的句型αβδ的短语。

即:语法树中以非终结符的作为根的子树的叶子所组成的字符串。

如:ba是相对于非终结符A的句型AB的短语。句型baSb的短语有ba,a,Sb,baSb。

直接短语:
若S=*=>αAδ且A=>β,则称β是相对于非终结符A的句型αβδ的直接短语。

即:语法树中以非终结符的作为根的子树,它的孩子都是叶子,没有其他子树。

如:Sb是相对于非终结符B的句型AB的短语。句型baSb的短语有a,Sb。

句柄:
位于句型最左边的直接短语称为该句型的句柄。

即:位于语法树中最左边的直接短语。

如:句型baSb的句柄是a。

简单优先文法定义

一个文法是简单优先文法,需要满足以下两个条件:

在文法符号集中V,任意两个符号之间必须之后一种优先关系存在。(显然满足)
在文法中,两个产生式不能有相同的右部。

简单优先分析法的操作步骤

将输入输入串a1a2···an#依次压栈,不断比较栈顶符号ai和下一个待输入符号aj的优先级,若ai>·aj则进行下一步,否则重复此步骤。

意思是:停止条件是ai>·aj表示前面输入串一定比后面先归约,所以只需要在前面找句柄就行了。

栈顶符号ai即为句柄尾,从此处向左寻找句柄头ak,满足ak-1<·ak。

意思是:从后向前找ak-1<·ak表示ak之前的输入串一定比ai···ak后归约,由此确定现在就是要归约ai···ak。

由句柄ai···ak在文法中寻找右部为ai···ak的产生式;找到则将句柄替换为相应左部,找不到则说明该输入串不是该文法的句子。

重复以上步骤直到归约完成。

代码实现

数据结构设计
1.用数组来存储优先关系表。
在这里插入图片描述

2.int judge(char *p,int k,char *psc);
*psc指向当前输入符号,*p和k表示为开始符号#,即p[k]=’#’&&k==1
在这里插入图片描述

3.int find(int a,int b);
查找优先关系表,得出输入符号的优先关系。
4.int in_vt(char c);
将输入的符号转为数组,方便在find函数中查找符号之间的优先关系。

在这里插入图片描述

#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;
}


运行结果
输入想要规约的字符串,以#号结尾:
在这里插入图片描述

随后便会输出分析的表格,最后会输出规约的结果。

最后,其实存在一个问题,就是无法判断输入的文法是否为简单优先文法。

摘 要 编译程序的工作过程通常是词法分析、语法分析、语义分析、代码生成、代码优化。编译程序的这些过程的执行先后就构成了编译程序的逻辑结构,但是这些逻辑结构不一定是按照某一个固定顺序的,也有可能是按照平行或者互锁的方式执行的。 本次课程设计是就简单优先文法原理来做一个简单优先分析器。简单优先分析文法的基本思想是对一个文法按一定的原则求出该文法所有符号包括终结符和非终结符之间的优先关系,按照这种关系确定规约过程中的句柄,它的规约过程实际上是规范规约。在算法实现过程中,主要使用visual C++进行编程。 关键字 简单优先关系 大于关系 小于关系 等于关系 Abstract Compiler of the process is usually lexical analysis, grammar analysis, semantic analysis, code generation, code optimization. Compiler of the implementation of these processes have posed a compiler on the logical structure, but these may not necessarily be in accordance with the logical structure of a fixed order, may also be in accordance with the parallel or interlocking approach to the implementation of the. This course is designed on the simple principle of priority to do a simpegrammar priority Analyzer。Simple grammar priority of the basic idea of a grammar obtained by certain principles of the grammar, including all the symbos at the end and at the end of the non-priority, according to this relationship in the process of determining the statute handler, it is actually the process of regulating the Statute of the Statute. In the algorithm process, the main use of visual C programming. Key Words Simple priority relations Over relations Less than relations Equal relations 目 录 摘要…………………………………………………………………………………………2 一、概述……………………………………………………………………………………4 (一)实验环境与开发工具 ………………………………………………………‥4 (二)简单优先文法简介 ……………………………………………………………4 (三)基本概念 ………………………………………………………………………4 (四)优先关系 ………………………………………………………………………4 二、需求分析 ……………………………………………………………………………5 (一)总体功能需求 …………………………………………………………………5 (二)系统的主要功能函数 …………………………………………………………5 (三)系统的设计思想 ………………………………………………………………6 三、详细设计 ……………………………………………………………………………7 (一)等于关系模块 …………………………………………………………………7 (二)小于关系模块 …………………………………………………………………8 (三)大于关系模块 …………………………………………………………………10 (四)句子识别模块 …………………………………………………………………12 四、测试结果………………………………………………………………………………16 五、小结……………………………………………………………………………………19 六、参考文献 ……………………………………………………………………………20 附录 源程序 ………………
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值