第 1 单元博客

基于度量来分析自己的程序结构

属性数 方法数
CalcMul 4 17
CalcSum 1 14
CogC ev(G) iv(G) v(G)
Total 157 166 186 220
Avg. 1.40 1.55 1.74 2.06

类图

Parser, Result, Token, T(?) 部分提供一种表达形式语法的方式。
Tokenize中各对象存储形式语法,Convert存储自定义函数。
Calculate, Calc(?), Function是计算。

分析 BUG

  • 第 1 次
  • 第 2 次作业
    • sin/cos 内部的因子前出现了正号
      不符合因子语法
    • 整数-1 的符号错误
      toString()中,按分段产生各因子的字符串,常数项绝对值为 1 时直接返回了字符串"1",没有考虑符号。
      以上两项都在 calculate.CalcMul.toString(); 圈复杂度 = 8
    • sum 语法错误
      sum 的语法为 "sum" "(" empty "i" empty { "," empty factor_const empty }[2] "," empty sum_expr empty ")"
      而处理语法重复项的类中,写了<=号,导致实际匹配了 3 次,而不是 2 次。使得后面 sum_expr 出现语法错误。
      parsing.TRep.parse(); 圈复杂度 = 5
  • 第 3 次

发现 BUG

很遗憾,没有发现别人的 BUG.

架构设计体验

从开始即确定使用递归下降方法,并按照形式语法实现输入解析。然而我很快发现这样会导致多数编码时间用于实现解析。
于是我改为将语法也用类来实现,这样就能用一句代码描述一条语法,并且能简单对应代码与语法。如表达式:

// expr = empty [sign empty] item {empty sign empty item} empty
expr.setTokenList(empty, new TList(sign, empty).opt(), item, new TList(empty, sign, empty, item).rep(), empty);

这样解析之后得到语法的树,再在语法的树上进行计算。
尝试从语法树上获得不适当的结果类型时会抛出异常,易于定位代码写错的地方。

计算部分分为两个类,一个是项类:内容从A*x**B发展到A*x**B*sin(...)**C*cos(...)**D
一个是表达式类,为因子的合。在计算过程中即展开,合并同类项。

学习体会

有时并不是任务本身有多“难”,而是在编码过程中的大量重复工作导致更容易犯错误。这时有必要自己制造工具来减少这种困难。
即适合造轮子的时候就要果断造。

posted on 2022-03-26 13:40  VKQYYU  阅读(54)  评论(0)    收藏  举报