⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 form1.cs

📁 自己编的一个小程序
💻 CS
字号:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace test3
{
	public class Form1 : System.Windows.Forms.Form
	{
		private System.Windows.Forms.TextBox textBox1;
		private System.Windows.Forms.Button button1;
		private System.Windows.Forms.TextBox textBox2;
		private System.Windows.Forms.Label label1;
		/// <summary>
		/// 必需的设计器变量。
		/// </summary>
		private System.ComponentModel.Container components = null;
		public Form1()
		{
			//
			// Windows 窗体设计器支持所必需的
			//
			InitializeComponent();

			//
			// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
			//
		}

		/// <summary>
		/// 清理所有正在使用的资源。
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows 窗体设计器生成的代码
		/// <summary>
		/// 设计器支持所需的方法 - 不要使用代码编辑器修改
		/// 此方法的内容。
		/// </summary>
		private void InitializeComponent()
		{
			this.textBox1 = new System.Windows.Forms.TextBox();
			this.button1 = new System.Windows.Forms.Button();
			this.textBox2 = new System.Windows.Forms.TextBox();
			this.label1 = new System.Windows.Forms.Label();
			this.SuspendLayout();
			// 
			// textBox1
			// 
			this.textBox1.Location = new System.Drawing.Point(24, 40);
			this.textBox1.Name = "textBox1";
			this.textBox1.Size = new System.Drawing.Size(256, 21);
			this.textBox1.TabIndex = 0;
			this.textBox1.Text = "";
			// 
			// button1
			// 
			this.button1.Location = new System.Drawing.Point(296, 40);
			this.button1.Name = "button1";
			this.button1.TabIndex = 1;
			this.button1.Text = "确定";
			this.button1.Click += new System.EventHandler(this.button1_Click);
			// 
			// textBox2
			// 
			this.textBox2.Location = new System.Drawing.Point(24, 88);
			this.textBox2.Multiline = true;
			this.textBox2.Name = "textBox2";
			this.textBox2.ReadOnly = true;
			this.textBox2.Size = new System.Drawing.Size(352, 72);
			this.textBox2.TabIndex = 2;
			this.textBox2.Text = "";
			// 
			// label1
			// 
			this.label1.Location = new System.Drawing.Point(40, 16);
			this.label1.Name = "label1";
			this.label1.Size = new System.Drawing.Size(240, 16);
			this.label1.TabIndex = 3;
			this.label1.Text = "输入表达式以#结束";
			// 
			// Form1
			// 
			this.AutoScale = false;
			this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
			this.ClientSize = new System.Drawing.Size(392, 174);
			this.Controls.Add(this.label1);
			this.Controls.Add(this.textBox2);
			this.Controls.Add(this.button1);
			this.Controls.Add(this.textBox1);
			this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D;
			this.MaximizeBox = false;
			this.Name = "Form1";
			this.ResumeLayout(false);

		}
		#endregion

		/// <summary>
		/// 应用程序的主入口点。
		/// </summary>
		[STAThread]
		static void Main() 
		{
			Application.Run(new Form1());
		}
	public char [,]O_Table = 
	{
   // +   -   *   /   (   )   i   # 
	{'>','>','<','<','<','>','<','>'},
	{'>','>','<','<','<','>','<','>'},
	{'>','>','>','>','<','>','<','>'},
	{'>','>','>','>','<','>','<','>'},
	{'<','<','<','<','<','=','<','-'},
	{'>','>','>','>','-','>','-','>'},
	{'>','>','>','>','-','>','-','>'},
	{'<','<','<','<','<','-','<','='}
	};//优先关系表:八个字符分别是 +  -  *  /  (  )  i  # ,其中'-'表示出错
		public struct SToken
		{
			public char ch;	//存放字符:+-* /()i#E
			public int No;	//存放算符优先关系表中的序号
	
		}
		public SToken[] Token=new SToken[50] ;	//单词序列,最后一个以“#”结束,
                                                //各个字符用一数字表示其在表中的下标。
		int TokenNumber = 0;	//单词序列中包含的单词个数
		int ipToken = 0;	//进行“移进-规约”时的位置指示
		//词法分析专用全局变量:
		char ch;	//存放取得的一个字符
		public char[] Buffer;//=new char[BUFFER_SIZE];	//表达式缓冲区,以'\0'表示结束
		int ipBuffer = 0;		//表达式缓冲区当前位置序号
		//运算符定义:
		const int O_NUMBER= 8;	//运算符个数,+-* /()i#
		const int O_PLUS= 0;	// 加      +
		const int  O_MINUS= 1;	// 减      -
		const int  O_TIMES =2;	// 乘      *
		const int  O_SLASH= 3;	// 除      /
		const int  O_L_PAREN= 4;//左括号   (
		const int  O_R_PAREN= 5;//右括号   )
		const int  O_IDENT= 6;	//标识符   i
		const int  O_NUL= 7;	//语法界符 #
		const bool TRUE =true;
		const bool FALSE= false;
		//错误信息:
		string ErrMsg;	//这个字符串存放 出错信息
		//堆栈:由专门的函数操作(PopUp(),Push(),…)
		const int STACK_MAX_SIZE = 50;	//堆栈最大存储量
		SToken[] Stack = new SToken[STACK_MAX_SIZE];	//堆栈
		int ipStack = 0;		//堆栈指针,指向栈顶(下一个空位置)
		const int OG_NUMBER= 6;	//文法个数
		//char OG[OG_NUMBER][4] = {"E+E","E-E","E*E","E/E","(E)","i"};	//文法右部
		//文法:
		public	char [,]OG = {  {'E','+','E','\0'},
								{'E','-','E','\0'},
								{'E','*','E','\0'},
								{'E','/','E','\0'},
								{'(','E',')','\0'},
								{'i','\0','\0','\0'}
							 };//文法右部
		const int  TOKEN_MAX_LENTH = 100;		//最大的单词长度+1
		private void button1_Click(object sender, System.EventArgs e)
		{
			char[] charRange =textBox1.Text.Trim().ToCharArray();
					Buffer = charRange;
			ipBuffer = 0;//做完一次后,表达式缓冲区当前位置序号返回开头。
				if(ChangeToTokens())	//将表达式分割成单词序列
			{
				if(Judge())	//利用算符优先关系表判断表达式(单词序列)是否正确
					OutPut(textBox1.Text,"正确!");
				else
					OutPut(textBox1.Text,ErrMsg); //输出错误信息
			}
			else //出错
			{
				OutPut(textBox1.Text,ErrMsg); //输出错误信息
			}
		}


		bool Judge()
		{
			JudgeInit();
			PushToken('#',O_NUL);	//将“#”号置栈底
			while(TRUE)	//进行“移进-规约”操作
			{
				switch(MoveIn())
				{
					case 1: //需要规约
					switch(GuiYue())//规约
					{
						case 1: //这一步规约成功
							break;
						case 2: //规约全部完成
							return TRUE;
						default: //出错
							ErrMsg = "规约错误。";
							return FALSE;
					}
						break;
					case 2: //需要继续移进
						break;
					default: //出错
						return FALSE;
				}
			}
		}

		//规约,并判断是否完成
		//返回:-1出错,1这一步规约成功,2规约全部完成
		int GuiYue()
		{
			int n0,n;
			char r; //存优先关系

			n = FindPriorOp(-1); //取得堆栈中第一个终结符
			if(Peek(n).ch == '#') //出错或全部结束
			{
				if(IsOK())
					return 2;
				else
					return -1;
			}
			while(TRUE)
			{
				n0 = n;
				n = FindPriorOp(n0); //前一个终结符的堆栈位置
				if(n - n0 > 2) //出错(多个非终结符相邻)
					return -1;
				r = O_Table[Peek(n).No,Peek(n0).No];
				if(r == '<') //寻找结束
				{
					if(! GuiYueN(n - 1)) //规约(从前一个后的字符开始)规约失败
						return -1;
					else //规约成功,还要判断是否全部完成
					{
						if(IsOK())
							return 2; //规约全部完成
						else
							return 1; //这一步规约成功
					}
				}
				else if(r == '=') //继续向前找
				{
					continue;
				}
				else //出错(r为>或没有关系)
					return -1;
			}
		}

		//判断规约是否全部完成
		//返回:TRUE全部完成;FALSE没有完成
		bool IsOK()
		{
			if(Peek(0).ch == 'E'&& Peek(1).ch == '#' && Token[ipToken].ch == '#')
				return TRUE;
			else
				return FALSE;
		}

		//返回:TRUE成功,FALSE失败
		bool GuiYueN(int n) //将堆栈中0~n单词规约
		{
			int i,j;
			bool k;
			for(i=0;i<OG_NUMBER;i++) //将规约串和文法右部OG[][]每一个进行比较
			{
				for(j=n,k=FALSE;j>=0;j--)
				{
					if(OG[i,n-j] != Peek(j).ch)
					{
						k = TRUE; //TRUE表示规约串和文法右部不符,
						break;
					}
				}
				if(k) continue; 
				//k==FALSE表示规约串判断完成
				if(OG[i,n+1]=='\0') //文法也判断完成,匹配成功
				{
					PopUp(n + 1); //弹出规约串
					PushToken('E',O_IDENT); //压入左部“E”
					return TRUE;
				}
			}
			return FALSE;
		}

		//在堆栈中,从Begin开始,查找前一个终结符位置
		//如果从开始找,让 Begin = -1
		int FindPriorOp(int Begin)
		{
			int n;
			n = Begin + 1;
			while(Peek(n).ch == 'E')
			{
				n ++;
			}
			return n;
		}

		int MoveIn()
		{
			SToken s,t; //分别存堆栈顶单词和单词序列的第一个单词
			char r; //存放优先关系
			s = Peek(FindPriorOp(-1)); //取得堆栈中第一个终结符位置
			t = Token[ipToken];
			r = O_Table[s.No,t.No];
			if(t.ch == '#') //单词结束,无法移进,需要规约
				return 1;
			else //单词没有结束,需判断是否可以移进
			{
				if(r == '<' || r == '=') //需要移进
				{
					Push(t);
					ipToken ++;
					return 2;
				}
				else if(r == '>') //不能移进,需要规约
					return 1;
				else //没有优先关系,出错
				{
					MakeErr("移进时出现两个没有优先关系的相邻单词。");
					return -1;
				}
			}
		}

		//(利用算符优先关系表判断单词序列是否正确)判断前的初始化
		//由于多个表达式需要依次判断,因此对每个表达式判断前都需要初始化
		void JudgeInit()
		{
			ipStack = 0; //堆栈初始化(如果有专门的StackClear()函数则更好)

			ipToken = 0; //指向首个单词
		}

		//窥视堆栈
		//成功返回:返回单词
		//不成功返回:NULL
		SToken Peek(int n)
		{
			SToken Token;
			if(n > 0 || n < ipStack) 
				Token = Stack[ipStack - n - 1];
			else if(n < 0)
				Token = Stack[ipStack - 1];
			else
				Token = Stack[0];
			return Token;
		}

		void OutPut(string Formula, string Result)
		{
			textBox2.Text=Result;
		}
		//弹出堆栈
		//不成功返回:FALSE
		//成功返回:TRUE
		bool PopUp(int n)
		{
			if(ipStack < 2) return FALSE; //只剩0个或1个
			if(n > ipStack - 1) n = ipStack - 1;
			ipStack -= n;
			return TRUE;
		}

		//压栈(以字符形式)
		//参数:ch是要压栈的字符(+-*/()i#E 之一),O_No运算符序号
		//调用:Push()
		void PushToken(char ch, int O_No)
		{
			SToken Token;//SToken是值类型的 不用new 关键字。
			Token.ch = ch;
			Token.No = O_No;
			Push(Token);
		}

		//压栈
		//参数:Token是要压栈的SToken结构体类型的单词
		void Push(SToken Token)
		{
			Stack[ipStack ++] = Token;
		}
	
		bool ChangeToTokens()
		{
			TokenNumber = 0;
			if(GetFirstChar() == '\0') return ! MakeErr("表达式为空。");//如果GetFirstChar()返回空,则表示表达示为空。
																		//ChangeToTokens()也到此为止。
			while(TRUE) //对缓冲区进行循环读
			{
				if(ch <= 32 && ch > 0) GetFirstChar(); //滤去空格,如果为空,则再读入下一个字符。

				switch(ch) //对单词的第一个进行判断,在下面一次处理整个单词
				{
					case '#':
						Token[TokenNumber].ch = '#';
						Token[TokenNumber].No = O_NUL;
						return TRUE; //处理结束,因为#号为最后一个字符。
					case '+':
						Token[TokenNumber].ch = '+';
						Token[TokenNumber].No = O_PLUS;
						GetChar();
						break;
					case '-':
						Token[TokenNumber].ch = '-';
						Token[TokenNumber].No = O_MINUS;
						GetChar();
						break;
					case '*':
						Token[TokenNumber].ch = '*';
						Token[TokenNumber].No = O_TIMES;
						GetChar();
						break;
					case '/':
						Token[TokenNumber].ch = '/';
						Token[TokenNumber].No = O_SLASH;
						GetChar();
						break;
					case '(':
						Token[TokenNumber].ch = '(';
						Token[TokenNumber].No = O_L_PAREN;
						GetChar();
						break;
					case ')':
						Token[TokenNumber].ch = ')';
						Token[TokenNumber].No = O_R_PAREN;
						GetChar();
						break;
					default:
						if(ch >= '0' && ch <= '9') //整数
						{
							while(GetChar()>0)
							{
								if(ch < '0' || ch > '9') break;//不是数字时返回。如果是的话继续。
							}
							Token[TokenNumber].ch = 'i';//这里把所有的连在一起的数字用i表示。
							Token[TokenNumber].No = O_IDENT;
						}
						else
						{
							return ! MakeErr("表达式中含有非法字符。");
						}
						break;
				}
				TokenNumber ++;
			}

		}

		//从表达式缓冲区中取到下面第一个非空字符
		//成功:返回字符;不成功:返回'\0'
		char GetFirstChar()
		{
			while(GetChar() != '\0')//非空字符 时才返回这个字符。在这里去掉了所有的空格。
			{						//如果为空则返回空。
				if(ch>32) return ch;
			}
			return '\0';
		}

		//成功:返回字符;不成功:返回'\0'
		char GetChar() //返回缓冲区中的字符直到#号结束。
		{
			if(Buffer.Length == 0)//表达示为空。返回'\0'。asc码这0。
				return ch = '\0';
			if((ch = Buffer[ipBuffer]) != '#')//如果ch等于#则不做ipBuffer ++
				ipBuffer ++;
			
			return ch;
		}
		//出错
		bool MakeErr(string ErrMassage)
		{
			ErrMsg = ErrMassage;
			return TRUE;
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -