第三步,进行有限自动机的搭建操做 正则表达式
咱们要构造一个有限自动机,而这个自动机是用一个表达式来构建的,很容易能够想到,咱们彻底能够把表达式耳的操做数看作一个小号的自动机(或者说是状态图),而操做符的效果是对状态图进行修饰,或者链接两个状态图,当咱们执行完表达式解析后,就能够获得一个完整的表达式的状态图了。 架构
像是算术表达式这种给定输入只有一个结果的,表示成树的形式就能够知足要求了,而正则表达式对给定输入会有多个结果(虽然一般咱们只要第一个结果),也确实只能用图表示。 函数
操做数有三种,连续字符;包含;分组提取比较。都用以下状态图表示: spa
注意我把全部的操做都放在边上,状态节点处不作任何行为。 指针
每个操做数所对应的状态图,都各有惟一的进入节点和退出节点(咱们不须要关系状态图内部的状况) 字符串
'?'操做符,也便是可选操做符,它的效果以下(从操做数修饰的来): 模板
'??'的效果相似,可是ε边的优先级较高(图中靠上的边优先级高) 循环
相似的,还有'*'、'*?': 方法
输出节点为新建节点,'*?'的ε边的优先级较高 im
以及'+'、'+?':
输出节点为新建节点,'+?'的ε边的优先级较高
隐藏的“链接”操做符:
左俩操做数1,右俩操做数2
选择操做符,"|":
上面一排为操做数1,下面一排为操做数2
分组"( )":
黑色分别表示报告分组的起止点的字符串位置
通常不分组的括号"(: )",这个彻底没啥操做,不用修饰,直接返回操做数就行了
限定次数的操做符(是的,看作操做符)"{a,b}":
红色表示进入循环,蓝色累计次数,绿色退出循环
如此,咱们就获得了生成操做数的方法,以及全部操做符的操做效果
结合这些,咱们就能够经过分析表达式来生成一个完整的有限自动机了。
分析表达式的方法么,天然是不少的,算术表达式分析器稍微改改就能拿来分析以前获得的列表了,无非是新的运算符,新的运算函数(函数指针真是棒啊真是棒)、新的操做数而已,总体架构变化极小。
固然,我是用的我以前写的一个可定制的表达式解析器,那是一个模板类,支持一元运算符(前置、后置)、二元运算符(左结合、右结合)、括号(普通括号、后缀括号),只要把这些运算符和它们对应的处理函数注册进去就好了。(还能够注册操做数生成函数、操做符生成函数、销毁函数等一系列函数)
因此具体写法就很少说了,拿个算术表达式解析器慢慢改就是。
下一帖,第四步。