- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
一款设计精巧的表达式解析器
----开发MIS系统时,报表设计中经常会碰到表达式解释器,完成用户自定义的公式运算。这种程序的设计需 要有比较高的技巧,以下介绍一款用 DELPHI4.0开发的程序[程序重在算法,语言特性很少,用其它语言的人 也能读懂],只要按自已的要求稍加修改,即可做成组件或全局方法发部。它支持 ”加[+]、减[-]、乘[*]、除[/]、
商[$ :两整数相除,结果的整数部分]、模[%]、括号[()]四则混合运算,支持与[]、或[|]、异或F]、左移[< ]、 右移[ >]和非[!]逻辑运算功能,同时它们可以出现在同一个表达式中,它们的优先级依次为括号、非、与或异
或左右移、乘除商模、加减。如式: 12.45+3*16 >2*(3+6*(3+2)-1)=12.45+3*4*32 ,计算结果为:396.45。程序包
括两大部分功能:表达式拆解、因子计算,分别由两个类 TBdsProc和TPUSHPOP完成。具体如下:
CDIKi nd=record
case id: Boolea n of
True: (dval: Double);
False: (ival: In teger);
en d;
CDKind :区别表达式中的整数和浮点数类型, 因为有些运算符不支持浮点数(如逻辑运算)
ValKi nd = CDIKi nd;
TBdsProc = class
private
Fghpd : In teger;//识别并标记左右括号是否成对出现
function lsCalcFh(c: Char): boolea n;
//判别一个字符是否运算符
function CopyRight(abds: Strin g;start: In teger):
Stri ng;//截取字符串表达式
function BdsSs(var abds: String): ValKind;
//返回一个子表达式的值
function BdsYz(var abds: String): ValKind;
〃表达式因子,如:15、(13+5)
function BdsItm(var abds: Strin g): ValK ind;
//读取表达式中的一个因子
public
function CalcValue(const bds: String): ValKind;
//返回计算结果
en d;
TPUSHPOP = class
private
ffh: array [0..2] of Char;// 符号数组
value: array [0..3] of CDIKind;// 值数组
flevel: Byte;// 因子个数
fisfh: Boolean;〃识别等待输入值或运算符
fisnot: Boolean;〃识别待计算数据项是否执行非运算
function Calcsj(av1,av2: CDIKind;fh: Char): CDIKind; //执行两个数值的四则运算
function Calclg(av1,av2: CDIKind; fh: Char): CDIKind;
//执行两个数的逻辑运算
procedure Calccur;{当输入数据项满足四个数后
[依运算优先级层数求得,见下述算式解析原理]执行中间运算}
fun ctio n lsLgFh(fh: Char): Boolea n;
〃一个符号是否逻辑运算符
function IsCcFH(fh: Char): Boolean;
// 一个符号乘除商模运算符
public
con structor Create;
procedure PushValue(avalue: CDIKind);// 存入一个数据项
procedure PushFh(afh: Char);// 存入一个符号
function CalcValue: CDIKind;// 计算并返回值 en d;
----表达式解析基本原理: ----1 .表达式处理:
----表达式的一个个数据项组成,中间由运算符连接,每个数据项为一个分析基本分析单元。表达式中如果包
含有改变运算优先级别的括号运算,先计出括号中式子的值,再把该值当一个数据项处理 ,这一点在程序设计中
只要运用递归功就能实现。
----2 ?数据项计算处理
-__- a >非运算:
----它为单目运算符,级别最高,在存入符号时做标记,存入数据时即时计算并去除标记。
----b >表达式运算:
----设f1、f2、f3分别表示一二三级运算符, V1、V2、V3、V4分别表示顺序四个数, 则极端表达式模型为 R=V1
f1 V2 f2 V3 f3 V4 ,计算时顺序应为 R=- V4 f3 V3 f2 V2 f 1 V1。为了简化运算,把其中
文档评论(0)