C# 正规式转NFA

正规式转NFA

1、正规式和NFA

  定义(参考编译原理教材)

2、转换思想

  1.使用一个首尾栈来存储表达式首尾节点组的集。

  2.使用一个边栈来存储边的集。

  3.利用后缀表达式,利用首尾栈对表达式做运算并将生成的边加入边栈。

3、转换步骤

 接下来以正规表达式a*b(b|a)*构造与之等价的ε-NFA来演示
(1)转换规则
 <1>基础

在这里插入图片描述

 <2> 归纳 

在这里插入图片描述

(2)转成后缀表达式
          a*b.ba|*.
(3)运算
(1)遇到“a”

在这里插入图片描述

 (2)遇到“*”

在这里插入图片描述

 (3)遇到“b”

在这里插入图片描述

 (4)遇到“.”

在这里插入图片描述

 (5)遇到“b”

在这里插入图片描述

 (6)遇到“a”

在这里插入图片描述

 (7)遇到“|”

在这里插入图片描述

 (8)遇到“*”

在这里插入图片描述

 (9)遇到“.”

在这里插入图片描述

 (10)程序执行完毕,首尾中的唯一首尾组即NFA的开始状态和终结状态;边栈中的边集合即NFA。
 结果展示:

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  C# 代码:
  链接:https://pan.baidu.com/s/1kdKZoOD4OyWs-8Wuxn6uJw 
  提取码:p57w 
//Forms1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace practice__2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void dFAToolStripMenuItem_Click(object sender, EventArgs e)
        {
            NFA_DFA_MFA f = new NFA_DFA_MFA();
            f.ShowDialog();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
    }
}

//Forms2.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Collections;

namespace practice__2
{
    public partial class NFA_DFA_MFA : Form
    {
        public NFA_DFA_MFA()
        {
            InitializeComponent();
        }
        
        private void Form2_Load(object sender, EventArgs e)
        {

        }

        private void label1_Click(object sender, EventArgs e)
        {

        }

        private void groupBox1_Enter(object sender, EventArgs e)
        {
           
        }

        private void listView1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {

			Regex r = new Regex("[\\(|\\)|\\*|\\||[a-z]|\\d#949]+");
            string a= textBox1.Text;
			bool t = r.IsMatch(a);
            if (t == false)
            {
                MessageBox.Show("表达式错误", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                MessageBox.Show("正确", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
	
		private String addConnect(String s)
		{ // 为表达式加上连接符
			Stack stack = new Stack();
			char[] chr = s.ToCharArray();
			int point = 0;
			Console.WriteLine(s);
			Console.WriteLine("ZZ");
			Console.WriteLine(chr.Length);
			//a*b(b|a)*
			//a*.b.(b|a)*
			//a*b.ba|*.
			while (point != chr.Length)
			{
			
				Regex r = new Regex("[\\(|\\)|\\*|\\||[a-z]]+");
				Regex r1 = new Regex("[a-z]");
				

				// 对*[a-z]的情况在中间加上连接符后入栈
				if (chr[point] == '*' && point != chr.Length - 1
				&& r1.IsMatch(chr[point + 1] + ""))
				{
					stack.push(chr[point]);
					stack.push('.');
				}
				else if (chr[point] == '(' && point != 0 && chr[point - 1] != '|')
				{
					// 对)(、*(、[a-z](的情况在中间加上连接符后入栈
					stack.push('.');
					stack.push('(');
				}
				else if (point != 0 && r1.IsMatch(chr[point] + "")
			  && (r1.IsMatch(chr[point - 1] + "") || chr[point - 1] == ')'))
				{
					stack.push('.');
					stack.push(chr[point]);
				}
				else
				{
					stack.push(chr[point]);
					Console.WriteLine("ttt");
				}
				point++;
			}
			Console.WriteLine(stack.getString());
			return stack.getString();
		}

		private String change(String s)
		{ // 生成后缀表达式
			char[] chr = s.ToCharArray();
			int point = 0;
			Stack stack = new Stack();
			String str = "";

			while (point != chr.Length)
			{
				switch (chr[point])
				{
					case '(':
						stack.push(chr[point]);
						point++;
						break;
					case ')':
						while (stack.peek() != '(' && !stack.isEmpty())
						{
							str += stack.pop();
						}
						if (!stack.isEmpty() && stack.peek() == '(')
							stack.pop();
						point++;
						break;
					case '*':
						str += chr[point];
						point++;
						break;
					case '|':
					case '.':
						while (!stack.isEmpty() && stack.peek() != '('
						&& stack.peek() != ')'
						&& !compare(chr[point], stack.peek()))
						{
							str += stack.pop();
						}
						stack.push(chr[point]);
						point++;
						break;
					default:
						str += chr[point];
						point++;
						break;
				}
			}
			while (!stack.isEmpty())
			{
				if (stack.peek() == ')' || stack.peek() == ')')
					return "";
				else
					str += stack.pop();
			}
			Console.WriteLine(str);
			return str;

		}

		private bool compare(char a, char b)
		{ //比较操作符的优先级
			if (a == b)
				return false;
			if (a == '*')
				return true;
			if (a == '.')
			{
				if (b == '*')
					return false;
				else
					return true;
			}
			return false;
		}

		private bool check(String str)
		{ // 对后缀表达式做消除运算
			Stack stack = new Stack();
			Stack result = new Stack();
			char[] chr = str.ToCharArray();
			Regex r1 = new Regex("[a-z]");
			for (int i = chr.Length - 1; i >= 0; i--)
				stack.push(chr[i]);
			while (!stack.isEmpty())
			{
				switch (stack.peek())
				{
					case '*':
						if (!r1.IsMatch(result.peek() + ""))
							return false;
						stack.pop();
						break;
					case '.':
					case '|':
						if (result.length() < 2 || !r1.IsMatch(result.pop() + "")
								|| !r1.IsMatch(result.peek() + ""))
							return false;
						stack.pop();
						break;
					default:
						result.push(stack.peek());
						stack.pop();
						break;
				}
			}
			return result.length() == 1 && r1.IsMatch(result.peek() + "");

		}


		int x = 1;
		Stack<int[]> list = new Stack<int[]>();
		Stack<string[]> res = new Stack<string[]>();
		Stack<string[]> res_T = new Stack<string[]>();

		private int getFacoter()
		{
			int s = x;
			x++;
			return s;
		}
		public int[] getElement(Stack<int[]> stack, int position)
		{
			int[] result = stack.Pop();
			if (stack.Count == position)
			{			
				return result;
			}
			else
			{
				int[] element = getElement(stack, position);
				stack.Push(element);
				return element;
			}
		}

		public int[] getfactor()
		{
			return getElement(list, 0);
		}

		public Stack<String[]> getlist()
		{
			return res;
		}
		
		public void ToNFA(String str)
		{
			// TODO Auto-generated constructor stub
			char[] chr = str.ToCharArray();
			for(int i=0;i<chr.Length;i++)		
			{
				char ch = chr[i];
				int[] a = new int[2];
				int[] b = new int[2];
				int[] c = new int[2];
				switch (ch)
				{
					case '.':
						String[] st = new String[3];
						// 取出list中上面的两个关系
						a = list.Peek();
						Console.WriteLine(a);
						list.Pop();
						b = list.Peek();
						Console.WriteLine(b);
						list.Pop();
						// 创建新的关系
						c = new int[2];
						c[0] = b[0];
						c[1] = a[1];
						// 将上面的两个关系替换成新的关系
						list.Push(c);
						// 添加新的NFA项
						st[0] = b[1] + "";
						st[1] = "#";
						st[2] = a[0] + "";
						res.Push(st);
						break;
					case '|':
						c[0] = getFacoter();
						c[1] = getFacoter();
						a = list.Peek();
						list.Pop();
						b = list.Peek();
						list.Pop();
						list.Push(c);
						String[] st1 = new String[3];
						String[] st2 = new String[3];
						String[] st3 = new String[3];
						String[] st4 = new String[3];
						st1[0] = c[0] + "";
						st1[1] = "#";
						st1[2] = a[0] + "";
						res.Push(st1);
						st2[0] = c[0] + "";
						st2[1] = "#";
						st2[2] = b[0] + "";
						res.Push(st2);
						st3[0] = a[1] + "";
						st3[1] = "#";
						st3[2] = c[1] + "";
						res.Push(st3);
						st4[0] = b[1] + "";
						st4[1] = "#";
						st4[2] = c[1] + "";
						res.Push(st4);
						break;
					case '*':
						String[] st5 = new String[3];
						String[] st6 = new String[3];
						String[] st7 = new String[3];
						String[] st8 = new String[3];
						c[0] = getFacoter();
						c[1] = getFacoter();
						a = list.Peek();
						list.Pop();
						list.Push(c);
						st5[0] = c[0] + "";
						st5[1] = "#";
						st5[2] = c[1] + "";
						res.Push(st5);
						st6[0] = c[0] + "";
						st6[1] = "#";
						st6[2] = a[0] + "";
						res.Push(st6);
						st7[0] = a[1] + "";
						st7[1] = "#";
						st7[2] = a[0] + "";
						res.Push(st7);
						st8[0] = a[1] + "";
						st8[1] = "#";
						st8[2] = c[1] + "";
						res.Push(st8);
						break;
					default:
						String[] st9 = new String[3];
						c[0] = getFacoter();
						c[1] = getFacoter();
						list.Push(c);
						st9[0] = c[0] + "";
						st9[1] = ch + "";
						st9[2] = c[1] + "";
						res.Push(st9);
						break;
				}
			}
		}

		private void button4_Click(object sender, EventArgs e)
		{

			Console.WriteLine("AAA");
			string st = textBox1.Text;
			string ss = addConnect(st);
			Console.WriteLine(ss);
			string ss1 = change(ss);
			string ss2;
			if (check(ss1))
			{
				ss2 = ss1;
			}
			else
			{
				ss2 = "";
			}
			//a*b(b|a)*
			//a*b.ba|*.
			Console.WriteLine("BBB");
			Console.WriteLine(ss2);
			Console.WriteLine("CCC");

			ToNFA(ss2);		   
			foreach(string[] ch in res)
			{
				String[] st_t = new String[3];
				st_t[0] = ch[0];
				st_t[1] = ch[1];
				st_t[2] = ch[2];
				res_T.Push(st_t);	
			}
			
			foreach (string[] ch in res_T)
			{
				Console.WriteLine(ch[0] + " " + ch[1] + " " + ch[2] + " ");
				ListViewItem item = new ListViewItem();      
				item.Text = ch[0];
				item.SubItems.Add(ch[1]);
				item.SubItems.Add(ch[2]);
				listView1.Items.Add(item);
			}


		}

		private void textBox1_TextChanged(object sender, EventArgs e)
		{

		}

		private void button9_Click(object sender, EventArgs e)
		{
			string st = textBox1.Text;
			string ss = addConnect(st);
			textBox2.Text = ss;
		}

		private void button10_Click(object sender, EventArgs e)
		{
			string st = textBox1.Text;
			string ss = addConnect(st);
			string ss1 = change(ss);
			textBox3.Text = ss1;
		}

		private void button2_Click(object sender, EventArgs e)
		{
			System.Environment.Exit(0);
		}
	}
}

public class Stack
{

	private int maxSize;// 栈的大小
	private int top;
	private char[] arr;

	public Stack()
	{
		maxSize = 30;
		top = -1;
		arr = new char[maxSize];
	}

	public void push(char value)
	{ // 压入数据

		arr[++top] = value;
	}

	public char pop()
	{ // 弹出数据

		return arr[top--];
	}

	public char peek()
	{ // 访问栈顶元素

		return arr[top];
	}

	public bool isFull()
	{ // 栈是否满了

		return maxSize - 1 == top;
	}

	public bool isEmpty()
	{ // 栈是否为空

		return top == -1;
	}

	public int length()
	{
		return top + 1;
	}

	public String getString()
	{
		if (top == -1)
			return "";
		String s = "";
		int point = 0;
		while (point <= top)
		{
			s += arr[point];
			point++;
		}
		return s;
	}
}













  • 4
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值