0
点赞
收藏
分享

微信扫一扫

【编译原理】【C#】简易Chomsky文法类型判别器

追风骚年 2022-04-23 阅读 82
c#

文章目录

一、设计要求

使用任一种编程语言实现对非文法、0型文法、1型文法、2型文法、3型文法这四种文法类别进行分类。程序的输入为一行文法,非终结符有英文大写字母构成,终结符包含{小写字母、数字、基本运算符、左右括弧},文法的书写格式形如 “A::=aB”、“aB::=cDaa”。

二、算法原理

Chomsky按产生式的类型把文法分为0、1、2、3型文法四种类型。

【0型文法】
产生式形式:α→β,箭头左边的α至少含有一个非终结符,其余不加任何限制。此时文法即满足0型文法。

【1型文法】
产生式形式:α→β,在0型文法的基础上,要求|α|≤|β|,即产生式左端的长度小于等于右端的长度(S→ε除外),此时文法即满足1型文法。

【2型文法】
产生式形式:A→β,在1型文法的基础上,A∈VN,β∈V *(VN∪VT),此时文法即满足2型文法。

【3型文法】
产生式形式:A→a,A→aB。在2型文法的基础上,a∈VT,A,B∈VN,即产生式右边的第一个符号必须为终结符,此时文法即满足3型文法。

【非文法】
不满足0型文法的表达式。

【文法类型判断流程】
文法类型判断流程通常从要求最严格的3型文法开始判断,之后逐级递减,进而判断出每句文法的类型。

首先判断3型文法,要求满足左边只有一个字符且为非终结符,右边最多只能有两个字符。当右边有两个字符时,必须一个为终结符,一个为非终结符;当右边只有一个字符时,此字符必须为终结符。并且,所有右边为两个字符的产生式,终结符和非终结符位置为终结符+非终结符或者非终结符+终结符,且一个文法中终结符和非终结符位置必须相同。如果满足即为3型文法。

如果不满足3型文法,则需要进行2型文法的判断。要求满足左边只有一个字符且为非终结符,并且所有产生式的右边可以含有有限个终结符和非终结符,但终结符和非终结符的数量没有限制。如果满足即为2型文法。2型文法的特点是在1型文法的基础上,左边只有一个非终结符

如果不满足2型文法,则需要进行1型文法的判断。要求所有产生式左边至少有一个非终结符,并且所有产生式的右边可以含有有限个终结符和非终结符,但终结符和非终结符的数量没有限制,如果满足即为1型文法。1型文法的特点是右边字符个数不小于左边字符个数

如果不满足1型文法,则需要进行0型文法的判断。0型文法的特点是满足左边有非终结符即可。若不满足0型文法,则为非文法。

【流程图】
在这里插入图片描述

三、源代码

【窗体设计】
在这里插入图片描述
用户可在文本框内输入形如“A::=aB”、“aB::=cDaa”的一行文法,之后点击“识别”按钮,即可显示出文法的类型。点击“退出”即可退出程序。程序源代码如下:

Program.cs:

using System;
using System.Windows.Forms;

namespace Grammar_type_discriminator
{
    internal sealed class Program
    {
        [STAThread]
        private static void Main(string[] args)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());
        }
    }
}

MainForm.cs:

/*
 * 作者:JeronZhou
 * 时间:2022-04-17
 * 名称:文法类型判别器
 * 功能:程序的输入为一行文法,点击识别按钮后即可实现对非文法、0型文法、1型文法、2型文法、3型文法这四种文法类别进行分类,
 * 非终结符由英文大写字母构成,终结符包含小写字母、数字、基本运算符和左右括弧,文法的书写格式形如 “A::=aB”、“aB::=cDaa”
 */

using System;
using System.Windows.Forms;

/*文法类型判别器*/
namespace Grammar_type_discriminator
{
    public class Gram  //文法类
    {
        public int left_length;   //文法左边长度
        public int right_length;  //文法右边长度
        public string s;          //文法对应的字符串
        
        public Gram(string ss)  //构造函数
        {
            this.s = ss;
        }
        public int Judge()  //判断文法类型
        {
            int r=-1,i,len;
            int enabled=0,flag,flag1,flag2,flagl,flagr;
            flag=flag1=flag2=flagl=flagr=1;
            char[] Vn = new char[100];  //非终结字符集
            char[] Vt = new char[100];  //终结字符集
            left_length = 0;
            right_length = 0;
            len = s.Length;
            
            for(i=0;i<len;i++)  //判断文法格式是否正确
            {
                if(s[i]==':' && s[i+1]==':' && s[i+2]=='=')
                {
                    enabled = 1;
                    break;
                }
            }
            
            for(i=0;i<len;i++)
               {
                if(s[i]!=':')
                {
                    left_length++;
                }
                else
                {
                    break;
                }
            }
            right_length = len-left_length-3;
            
            int t=0;
            for(i=0;i<left_length;i++)  //判断左边是否有非终结符
            {
                if(s[i]>='A' && s[i]<='Z')
                {
                    t=1;
                    break;
                }
            }
            
            if(enabled==1 && left_length<=right_length && t==1)  //非0型文法情况
            {
                flag=0;
            }
            else if(enabled==1 && len>=5 && t==1)  //0型文法情况
            {
                   r=0;
            }
            
            if(flag==0)  //非0型文法情况
            {
                if(left_length==1 && (s[0]>='A' && s[0]<='Z'))  //非0型、1型文法情况
                {    
                      flag1=0;
                }
                else if(left_length>=1 && right_length>=1)  //1型文法的情况
                {
                    r=1;
                }       
            }
            
            if(flag1==0)  //非0型、1型文法情况
            {       
            
                if(left_length==1 && len==5 && (s[0]>='A' && s[0]<='Z') && ((s[4]>='a' && s[4]<='z') || (s[4]>='0' && s[4]<='9') || s[4]=='+' || s[4]=='-' || s[4]=='*' || s[4]=='/' || s[4]=='%' || s[4]=='(' || s[4]==')' || s[4]=='[' || s[4]==']' || s[4]=='{' || s[4]=='}'))  //非0型、1型、2型文法情况,即3型文法情况
                {
                    flag2=0;                   
                }
                else if(left_length==1 && len==6 && (s[0]>='A' && s[0]<='Z') && ((s[4]>='a' && s[4]<='z') || (s[4]>='0' && s[4]<='9') || s[4]=='+' || s[4]=='-' || s[4]=='*' || s[4]=='/' || s[4]=='%' || s[4]=='(' || s[4]==')' || s[4]=='[' || s[4]==']' || s[4]=='{' || s[4]=='}') && (s[5]>='A' && s[5]<='Z'))
                {
                    flag2=0;
                }
                else if(left_length==1 && len==6 && (s[0]>='A' && s[0]<='Z') && ((s[5]>='a' && s[5]<='z') || (s[5]>='0' && s[5]<='9') || s[5]=='+' || s[5]=='-' || s[5]=='*' || s[5]=='/' || s[5]=='%' || s[5]=='(' || s[5]==')' || s[5]=='[' || s[5]==']' || s[5]=='{' || s[5]=='}') && (s[4]>='A' && s[4]<='Z'))
                {
                    flag2=0;
                }
                else  //2型文法情况
                {
                    r=2;
                }           
            } 
            
            if(flag2==0)  //3型文法判断
            {
                r=3;
            }
            return r;
        }
    }
    
    public partial class MainForm : Form  //主窗口
    {
        public MainForm()
        {
            InitializeComponent();
        }
        void DiscriminatorClick(object sender, EventArgs e)
        {
            string grammer = textBox.Text;
            Gram g = new Gram(grammer);
            int r = g.Judge();
            switch(r)
            {
                case 0:
                    result.Text = "0型文法"; break;
                case 1:
                    result.Text = "1型文法"; break;
                case 2:
                    result.Text = "2型文法"; break;
                case 3:
                    result.Text = "3型文法"; break;
                case -1:
                    result.Text = "非文法"; break;
            }
        }
        void ExitClick(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}

四、测试运行

① 3型文法判断
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
② 2型文法判断
在这里插入图片描述
① 1型文法判断
在这里插入图片描述
④ 0型文法判断
在这里插入图片描述
⑤ 非文法判断
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

五、资源下载

C#项目源码文件:
打包exe应用程序:

举报

相关推荐

0 条评论