一个简单的公式解析器

 
   为了理解算法中的文法分析,用一个简单的公式解析器来说明。

   公式计算是电子表格中的常用功能。主要是实现了些简单的公式计算:
   比如:=Sum(A1,A2)

   假设我们要实现简单的公式解析,我们从头开始:

分析:
   首先,确认采用标准的递归下降法,采用自上而下(预测式)的语法分析(LL方式)。
   上下文无关文法(BNF)采用左结合推导树,

下面,也采用由上而下式的进行分析:

1:顶层的文法:
   expression  -> term expression'
   expression' -> add_op term expression'
                  | minus_op term expression'
                  | and_op term expression'
   add_op -> +
   minus_op -> -
   and_op -> &
说明:
   对于+,-运算,优先级最低,总是最后执行,所以,将其提取为最顶文法。
   而 & ,指的是字串连接,作为一个基本补充。如: ="abcd" & "efgh"   结果是: abcdefgh
   问题:
      将 &与 +,-做为同一优先级,似乎有些不对? 先不管它,后面再看。
   规定左右操作数:简化操作。
   +,-的处理,左右操作数可以只支持数值型(可转为数字的值)。
   &的处理,左右操作数只支持字符串。
   所以,再看问题:
       &与 +,-应该是不能并存的,所以,不用考虑上面的问题。如果并存,一定报错。
       类似 = 2 + 3 & 4    先计算 2+3,然后计算 5 & 4,报错。所以,虽然同优先级,
       也没啥错误。
   嗯,对于我们能处理的公式,我们有了一些限定,也是简化处理,如果要进一步处理,可以据此深一层探索。

2:term 文法
   term  -> factor term'
   term' -> mult_op factor term'
           |divide_op factor term'
   mult_op -> *
   divide_op -> /
说明:
   这种做法,也是常用算法书中一种技巧,将 优先级高于 +,-的* / 运算提取出来,放入term中,简化问题。
   看看左右操作数,*,/ 只支持 可以只支持数值型
 
3:factor文法
   factor  -> [PLUS | MINUS] factor'
   factor' -> NUM
             |STRING 
             |FUNC LP args RP
             |FUNC LP      RP
             |[Cell | Cell COLON Cell]
             |LP expression RP
   args    -> expression
             |expression COMMA args
   COMMA   -> ,
   LP      -> (
   RP      -> )
   COLON   -> :
   好了,这是最关键的部分了。
3.1: [PLUS | MINUS]:表示 正,负号,对于负号,你应该进行处理。比如结果是数值,则取反值。
3.2: NUM:数值处理:
3.3: STRING: 字串处理。由配对双引号来识别。
3.4: FUNC LP args RP | FUNC LP RP:函数,带参数或不带参数。
     此处,函数应该做判定,将已知函数转向相应的函数指针,如果是未知函数,则抛出语法错误。
     注意:如果公式解析器处理底层,而做为上层应用的调用模块,那么,还可以将未知公式向上抛出,
将控制权暂交于上层,由上层计算结果后返回。
    看看函数的详细处理:
    解析参数(args):
       多个参数用,隔开。 
       参数可能有两种,一是表达式方式,另一种是字串(其实,由双引号包含的也可以当表达式处理)。
       字串可直接处理,表达式可递归调用expresion
       参数压栈。以便后续的函数调用。
3.5: Cell[Range): 引用单元格(或者是范围),范围引的格式,如 A1:B2
3.6: LP Expresion RP:左右括号必须配对,中间递归表达式。

4:好了,上面已经把文法解释清楚了,可以用以下的公式来说明:
    = SUM(A1,("abcd & "efgh"),(3+4*5)) + SUM_USER()
   以上,也差不多就是本公式解析器的解析复杂度了。
   看一下未处理的标记,如果需要,可以很方便的加进去。
   %:应该定位于[PLUS | MINUS]同层。
   !:如果做为非运算,可以定位于[PLUS | MINUS]同层。
   $:看实际的含义而定。
   @:看实际的含义而定。
   #:这个比较特珠,看具体应用
   |:如果是位运算的话,应该是与 * / 同层
   /:如果是整除的话,可以与 * / 同层
   = , < , >:这个是逻辑运算,这个暂时不讨论
   [ , ] :看实际的含义而定。 
   `:视情况而定
   ^:如果是异或操作,可以与 * / 同层
   ;:视情况而定,
   ':单引号,视情况而定
   ?:视情况而定,一般会做为三目逻辑运算。
   _:视情况而定

5:最后,不能漏了最关键的预测器程序(Advance程序)。
   文法的解析,都是通过探测器来判定标识,并进行递推的。
   一般会有以下几种处理;
5.1:返回本公式解析支持标识。正常情况。
5.2:返回本公式暂不支持的标识。一般会在文法解释时抛出语法无法解析的错误。
5.3:忽略的标识,比如 空格 /n /t ,跳动它,视其不存在。

6:其它:
   上面的公式解析器缺少逻辑运算,其实呢,方法都是一样,只不过文法有些区别,并没有实际的复杂度。

   以上差不多就是一个简单的公式解析器的处理方法。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值