解析器前面想做一个公式编辑器,正好在学习设计模式,想起解释器模式。
解释器模式有5个角色,抽象表达式角色、终结符表达式角色、非终结符表达式角色、上下文角色、客户角色。
为什么 说我这是半解释器模式呢?
我这里以我的理解分为 上下文角色 和 表达式角色 ,因为偷懒所以没有抽象表达式角色。就造成应该分为4个解释器的合并到一个里面了。
在我这个解释器里有四个方法 OneLevel,KracketLevel,TwoLevel,ThreeLevel,分别为 %比解释、()括号解释(其中有用递归解释括号里的表达式)、*/解释、+-解释,构成了我这个解析运算功能。
下面请大家欣赏代码。。。
using System;
using System.Collections.Generic;
using System.Text;
namespace JTK.CalculateInterpreter
{
public class Expression
{
public void Interpret(Context context) //解释
{
try
{
context.Input = OneLevel(context.Input);
context.Input = KracketLevel(context.Input);
context.Input = TwoLevel(context.Input);
context.Input = ThreeLevel(context.Input);
context.Output = Convert.ToDouble(context.Input);
}
catch
{
throw new ExceptionExpression();
}
}
private string KracketLevel(string input)//括号级别
{
//验证括号
if (!CommonFunction.CheckKracket(input))
{
throw new ExceptionExpression("括号不匹配");
}
//去除层括号 递归调用
while (input.IndexOf(")") > 0)
{
int nEndIndex = input.IndexOf(")");
if (nEndIndex > 0)
{
int nStartIndex = CommonFunction.DaoZhao('(', input.Substring(0, nEndIndex));
string strSub = input.Substring(nStartIndex + 1, nEndIndex - nStartIndex - 1);
Expression exp = new Expression();
Context context = new Context(strSub);
exp.Interpret(context);
input = input.Replace(string.Format("({0})", strSub), context.Input);
}
}
return input;
}
private string OneLevel(string input)//级别1 %
{
int SignPostion = input.IndexOf("%");
while (SignPostion >= 0)
{
string strTemp = input.Substring(0, SignPostion);
int nTemp1 = CommonFunction.DaoZhao('+', strTemp);
int nTemp2 = CommonFunction.DaoZhao('-', strTemp);
nTemp1 = nTemp1 >= nTemp2 ? nTemp1 : nTemp2;
nTemp2 = CommonFunction.DaoZhao('*', strTemp);
nTemp1 = nTemp1 >= nTemp2 ? nTemp1 : nTemp2;
nTemp2 = CommonFunction.DaoZhao('/', strTemp);
nTemp1 = nTemp1 >= nTemp2 ? nTemp1 : nTemp2;
string strResult = "";
if (nTemp1 == -1)
{
strResult = strTemp.Substring(0, strTemp.Length);
}
else
{
strResult = strTemp.Substring(nTemp1 + 1, strTemp.Length - nTemp1 - 1);
}
double dTemp = Convert.ToDouble(strResult);
dTemp /= 100;
dTemp = Math.Round(dTemp, 4);
input = input.Replace(strResult + "%", dTemp.ToString());
SignPostion = input.IndexOf("%");
}
return input;
}
private string TwoLevel(string input) //级别2 * /
{
string Sign = "*";
int SignPostion = input.IndexOf("*");
if ((SignPostion > input.IndexOf("/") && input.IndexOf("/") != -1) || (SignPostion == -1))
{
Sign = "/";
SignPostion = input.IndexOf("/");
}
while (SignPostion >= 0)
{
string[] strs = CommonFunction.ZhaoShuZi(input, SignPostion);
double dTemp = 0.0;
if (Sign == "*")
{
dTemp = Convert.ToDouble(strs[0]) * Convert.ToDouble(strs[1]);
dTemp = Math.Round(dTemp, 2);
input = input.Replace(strs[0] + "*" + strs[1], dTemp.ToString());
}
else
{
dTemp = Convert.ToDouble(strs[0]) / Convert.ToDouble(strs[1]);
dTemp = Math.Round(dTemp, 2);
input = input.Replace(strs[0] + "/" + strs[1], dTemp.ToString());
}
Sign = "*";
SignPostion = input.IndexOf("*");
if ((SignPostion > input.IndexOf("/") && input.IndexOf("/") != -1) || (SignPostion == -1))
{
Sign = "/";
SignPostion = input.IndexOf("/");
}
}
return input;
}
private string ThreeLevel(string input) //级别 3 + -
{
string Sign = "+";
int SignPostion = input.IndexOf("+");
if ((SignPostion > input.IndexOf("-") && input.IndexOf("-") != -1) || (SignPostion == -1))
{
Sign = "-";
SignPostion = input.IndexOf("-");
}
while (SignPostion > 0)
{
string[] strs = CommonFunction.ZhaoShuZi(input, SignPostion);
double dTemp = 0.0;
if (Sign == "+")
{
dTemp = Convert.ToDouble(strs[0]) + Convert.ToDouble(strs[1]);
dTemp = Math.Round(dTemp, 2);
input = input.Replace(strs[0] + "+" + strs[1], dTemp.ToString());
}
else
{
dTemp = Convert.ToDouble(strs[0]) - Convert.ToDouble(strs[1]);
dTemp = Math.Round(dTemp, 2);
input = input.Replace(strs[0] + "-" + strs[1], dTemp.ToString());
}
Sign = "+";
SignPostion = input.IndexOf("+");
if ((SignPostion > input.IndexOf("-") && input.IndexOf("-") != -1) || (SignPostion == -1))
{
Sign = "-";
SignPostion = input.IndexOf("-");
}
}
return input;
}
}
public class ExceptionExpression : Exception
{
string message = "";
public ExceptionExpression()
{
}
public ExceptionExpression(String Message)
{
message = Message;
}
public override string Message
{
get
{
if (message != "") return message;
return "表达式错误";
}
}
}
}
using System.Collections.Generic;
using System.Text;
namespace JTK.CalculateInterpreter
{
public class Expression
{
public void Interpret(Context context) //解释
{
try
{
context.Input = OneLevel(context.Input);
context.Input = KracketLevel(context.Input);
context.Input = TwoLevel(context.Input);
context.Input = ThreeLevel(context.Input);
context.Output = Convert.ToDouble(context.Input);
}
catch
{
throw new ExceptionExpression();
}
}
private string KracketLevel(string input)//括号级别
{
//验证括号
if (!CommonFunction.CheckKracket(input))
{
throw new ExceptionExpression("括号不匹配");
}
//去除层括号 递归调用
while (input.IndexOf(")") > 0)
{
int nEndIndex = input.IndexOf(")");
if (nEndIndex > 0)
{
int nStartIndex = CommonFunction.DaoZhao('(', input.Substring(0, nEndIndex));
string strSub = input.Substring(nStartIndex + 1, nEndIndex - nStartIndex - 1);
Expression exp = new Expression();
Context context = new Context(strSub);
exp.Interpret(context);
input = input.Replace(string.Format("({0})", strSub), context.Input);
}
}
return input;
}
private string OneLevel(string input)//级别1 %
{
int SignPostion = input.IndexOf("%");
while (SignPostion >= 0)
{
string strTemp = input.Substring(0, SignPostion);
int nTemp1 = CommonFunction.DaoZhao('+', strTemp);
int nTemp2 = CommonFunction.DaoZhao('-', strTemp);
nTemp1 = nTemp1 >= nTemp2 ? nTemp1 : nTemp2;
nTemp2 = CommonFunction.DaoZhao('*', strTemp);
nTemp1 = nTemp1 >= nTemp2 ? nTemp1 : nTemp2;
nTemp2 = CommonFunction.DaoZhao('/', strTemp);
nTemp1 = nTemp1 >= nTemp2 ? nTemp1 : nTemp2;
string strResult = "";
if (nTemp1 == -1)
{
strResult = strTemp.Substring(0, strTemp.Length);
}
else
{
strResult = strTemp.Substring(nTemp1 + 1, strTemp.Length - nTemp1 - 1);
}
double dTemp = Convert.ToDouble(strResult);
dTemp /= 100;
dTemp = Math.Round(dTemp, 4);
input = input.Replace(strResult + "%", dTemp.ToString());
SignPostion = input.IndexOf("%");
}
return input;
}
private string TwoLevel(string input) //级别2 * /
{
string Sign = "*";
int SignPostion = input.IndexOf("*");
if ((SignPostion > input.IndexOf("/") && input.IndexOf("/") != -1) || (SignPostion == -1))
{
Sign = "/";
SignPostion = input.IndexOf("/");
}
while (SignPostion >= 0)
{
string[] strs = CommonFunction.ZhaoShuZi(input, SignPostion);
double dTemp = 0.0;
if (Sign == "*")
{
dTemp = Convert.ToDouble(strs[0]) * Convert.ToDouble(strs[1]);
dTemp = Math.Round(dTemp, 2);
input = input.Replace(strs[0] + "*" + strs[1], dTemp.ToString());
}
else
{
dTemp = Convert.ToDouble(strs[0]) / Convert.ToDouble(strs[1]);
dTemp = Math.Round(dTemp, 2);
input = input.Replace(strs[0] + "/" + strs[1], dTemp.ToString());
}
Sign = "*";
SignPostion = input.IndexOf("*");
if ((SignPostion > input.IndexOf("/") && input.IndexOf("/") != -1) || (SignPostion == -1))
{
Sign = "/";
SignPostion = input.IndexOf("/");
}
}
return input;
}
private string ThreeLevel(string input) //级别 3 + -
{
string Sign = "+";
int SignPostion = input.IndexOf("+");
if ((SignPostion > input.IndexOf("-") && input.IndexOf("-") != -1) || (SignPostion == -1))
{
Sign = "-";
SignPostion = input.IndexOf("-");
}
while (SignPostion > 0)
{
string[] strs = CommonFunction.ZhaoShuZi(input, SignPostion);
double dTemp = 0.0;
if (Sign == "+")
{
dTemp = Convert.ToDouble(strs[0]) + Convert.ToDouble(strs[1]);
dTemp = Math.Round(dTemp, 2);
input = input.Replace(strs[0] + "+" + strs[1], dTemp.ToString());
}
else
{
dTemp = Convert.ToDouble(strs[0]) - Convert.ToDouble(strs[1]);
dTemp = Math.Round(dTemp, 2);
input = input.Replace(strs[0] + "-" + strs[1], dTemp.ToString());
}
Sign = "+";
SignPostion = input.IndexOf("+");
if ((SignPostion > input.IndexOf("-") && input.IndexOf("-") != -1) || (SignPostion == -1))
{
Sign = "-";
SignPostion = input.IndexOf("-");
}
}
return input;
}
}
public class ExceptionExpression : Exception
{
string message = "";
public ExceptionExpression()
{
}
public ExceptionExpression(String Message)
{
message = Message;
}
public override string Message
{
get
{
if (message != "") return message;
return "表达式错误";
}
}
}
}
公共函数
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
namespace JTK.CalculateInterpreter
{
public class CommonFunction
{
public static int DaoZhao(char separator, string txt)
{
int length = txt.Length - 1;
for (int i = length; i >= 0; i--)
{
if (txt[i].CompareTo(separator) == 0)
{
return i;
}
}
return -1;
}
public static string[] ZhaoShuZi(string txt, int postion)
{
string[] strs = txt.Split('+', '-', '*', '/');
int n = 0;
for (int i = 0; i < txt.Length; i++)
{
switch (txt[i])
{
case '+':
n++;
break;
case '-':
n++;
break;
case '*':
n++;
break;
case '/':
n++;
break;
}
if (i == postion)
{
break;
}
}
string[] strsResult = new string[2];
strsResult[0] = strs[n - 1];
strsResult[1] = strs[n];
return strsResult;
}
public static bool CheckKracket(string InputString)
{
bool isok = true;
Stack stack = new Stack();
for (int i = 0; i < InputString.Length; i++)
{
if (InputString[i].ToString() == "(")
{
stack.Push(i);
}
if (InputString[i].ToString() == ")")
{
try
{
stack.Pop();
}
catch
{
isok = false;
break;
}
}
}
if (isok)
{
if (stack.Count == 0) { return true; } else { return false; };
}
else
{
return false;
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Collections;
namespace JTK.CalculateInterpreter
{
public class CommonFunction
{
public static int DaoZhao(char separator, string txt)
{
int length = txt.Length - 1;
for (int i = length; i >= 0; i--)
{
if (txt[i].CompareTo(separator) == 0)
{
return i;
}
}
return -1;
}
public static string[] ZhaoShuZi(string txt, int postion)
{
string[] strs = txt.Split('+', '-', '*', '/');
int n = 0;
for (int i = 0; i < txt.Length; i++)
{
switch (txt[i])
{
case '+':
n++;
break;
case '-':
n++;
break;
case '*':
n++;
break;
case '/':
n++;
break;
}
if (i == postion)
{
break;
}
}
string[] strsResult = new string[2];
strsResult[0] = strs[n - 1];
strsResult[1] = strs[n];
return strsResult;
}
public static bool CheckKracket(string InputString)
{
bool isok = true;
Stack stack = new Stack();
for (int i = 0; i < InputString.Length; i++)
{
if (InputString[i].ToString() == "(")
{
stack.Push(i);
}
if (InputString[i].ToString() == ")")
{
try
{
stack.Pop();
}
catch
{
isok = false;
break;
}
}
}
if (isok)
{
if (stack.Count == 0) { return true; } else { return false; };
}
else
{
return false;
}
}
}
被解析
namespace JTK.CalculateInterpreter
{
public class Context
{
private string _input;
public string Input
{
get { return _input; }
set { _input = value; }
}
private double _output;
public double Output
{
get { return _output; }
set { _output = value; }
}
public Context(string input)
{
this._input = input;
}
}
{
public class Context
{
private string _input;
public string Input
{
get { return _input; }
set { _input = value; }
}
private double _output;
public double Output
{
get { return _output; }
set { _output = value; }
}
public Context(string input)
{
this._input = input;
}
}
}