首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

ABNF 模式字符串匹配(2)

ABNF 模式字符串匹配(2)

[size=1.0625]我实现的 ABNF 和真正的 RFC2234 的 ABNF 模式不太一样,RFC2234 里面:字符串的顺序模式 (Concatational Rules,在正则表达式里面叫 Sequential Pattern 吧 ) 定义为 :element1 element2 element3 这样的形式,中间用 LWS(Linear White Space,就是 Tab 与空格的组合 ) 隔开 , 我的定义多了一个分组符号 (Gruping Rules)element1 element2 element3) 一个字符串只有按顺序匹配了 element1 element2 element3 才是匹配了这个顺序模式
[size=1.0625]备选模式 (Optional Rules): element1 / element2 / element3
[size=1.0625]我也加了分组符号: (element1 / element2 / element3)
[size=1.0625]不过在 RFC2234 里面虽然备选模式没有分组符号,但是它强力推荐使用,这样使文法更加清晰而没有二义性一个字符串只要匹配了 element1, element2 或 element3 中间的任何一个就算匹配了这个备选模式
[size=1.0625]字符串 (Strings):"element"这个和我的一样,也适用双引号"来标志一个完整的字符串
[size=1.0625]重复模式 (Repetition):<m>*<n>element
[size=1.0625]为了清晰起见我改成了:m*n(element) 原来 RFC2234 里面还有省略形式的重复模式的,我把他们去掉了
[size=1.0625]范围选择模式 (Value range):m-n
[size=1.0625]省略号 (Comment):; element 这个我没有,不过要加应该也不难
[size=1.0625]在程序里面我定义了 ZConcatSelector 对应顺序模式,ZAlterSelector 对应备选模式,ZQuoteSelector 对应字符串模式,ZRepetSelector 对应重复模式,ZRangeSelector 对应范围选择模式
[size=1.0625]它们都继承了 ZSubSelector 这个接口,而由于最高一层的接口需要单独提出来,我特地定义了一个 ZEnhancedSelector 接口,在程序里面只有 ZConcatSelector 实现了这个接口
[size=1.0625]在 ABNF 分析的核心代码里面有一个 Factory Pattern 的应用,由于模版可以嵌套,整个 BNF 表达式是一个 Composite Pattern. 所以每个模版都可能有子模版,子模版的生成是由一个 Factory 统一产生的,每次需要产生子模版的时候就会调用 ZSubSelectorFactory 的 getSubSelector 方法得到一个子模版,这个工厂封装了生成各种模版的不同的参数和方法,这样每个模版都只知道工厂而对其他模版的生成细节不了解,程序的可维护性和扩展性比较好
[size=1.0625]在 ZSubsSelector 的 interface 里面有 parseNext 方法,实际上这个方法就暗示了 Composite Pattern 的存在,一个非叶节点的模版会调用每个子模版的 parseNext 方法得到匹配的字符串,每个叶结点如 ZQuoteSelector 直接比较内部的数据返回比较值
[size=1.0625]为了能得到一个用户制定模版里面的每个域的长度,在 ZEnhancedSelector 接口里面定义了新的方法 parseNext2 返回的是一个 List,里面是对应用户各个域的匹配出的字符串,免得用户进行第二次处理用户使用的 class 最后是 ZBNFSelector,这个类相对简单,用户传进去一个 BNF 表达式作为匹配的模版,然后调用 select 返回多个匹配的字符串或者调用 select2 返回一个迭代器,迭代器里每个元素是一个 List,让用户可以直接得到每个域的匹配字符串
山不在高,有仙则名;水不在深,有龙则灵。
返回列表