前面几篇文章介绍了各种分析过程,本篇作为完结篇,介绍如何调用之前实现的代码,如何实现多行表达式或者选择部分表达式进行运算, 以及如何定位错误。
本程序可以不需要UI界面,独立成一个模块。如果表达式分析与计算功能打包成一个dll,那入口只有一个,SyntaxAnalyse类。new一个 SyntaxAnalyse类之后,调用其中的Analyse方法,将要计算的运算表达式作为参数传递进去,返回一个顶级TokenRecord对象,再根据返回的 TokenRecord对象的值类型取得结果,整个计算过程就完成了,使用起来非常方便。
/// <summary>
/// 表达式分析计算类,功能入口
/// </summary>
/// <remarks>Author:Alex Leo</remarks>
public class SyntaxAnalyse
{
/// <summary>
/// 构造函数
/// </summary>
/// <remarks>Author:Alex Leo; Date:2007-8-2</remarks>
public SyntaxAnalyse()
{ }
/// <summary>
/// 分析语句并返回记号记录对象
/// </summary>
/// <param name="Code">运算表达式</param>
/// <returns>顶级TokenRecord对象</returns>
public TokenRecord Analyse(string Code)
{
if (Code.Trim().Equals(string.Empty))
{
return new TokenValue(0,1);
}
List<TokenRecord> ListToken = new List<TokenRecord>();//TokenRecord列表
int intIndex = 0;
TokenFactory.LexicalAnalysis(ListToken, Code, ref intIndex);//词法分析,将代码转换为TokenRecord列表
//语法树分析,将Token列表按优先级转换为树
TokenRecord TokenTop = SyntaxTreeAnalyse.SyntaxTreeGetTopTokenAnalyse(ListToken, 0, ListToken.Count - 1);
TokenTop.Execute();
return TokenTop;
}
}
从代码中可以看出,首先是词法分析,得到一个记号对象列表List<TokenRecord>,然后进行语法分析,调用SyntaxTreeAnalyse的 SnytaxTreeGetTopTokenAnalyse方法,分析出顶级记号对象,这样一棵树就出来了。接下来执行顶级节点的Execute方法,该方法中首先会执行 下级节点的Execute方法,然后再针对下级节点的值执行自身的运算。所有的TokenRecord都是这样的模式,逐级递归调用,最后得到计算结果 。TokenRecord基类中包含一个object类型的Value属性和一个Type类型的TokenValueType属性,通过这两个属性可以得到具体的值及其类型, 然后做下一步处理。因为这里不只能执行数学运算,还能做字符串和逻辑值运算,所以必须通过TokenValueType来确定值的类型。如果只需要 实现数学运算,程序会简单一些。