将识别正则表达式的DFA表示成转移函数表,每次都查找在转移比较麻烦。如果能表示成一个顺序的指令序列,通过顺序解释这个序列来处理字符串,将是一种很有效的方法。如果还能加入优化,把代码最小化还能提高不少效率。不过这也可能只是丫丫。
先做一个试验
对于正则表达式 (a|b)[0-9].*c,可以用以前的方法先生成语法树,然后出DFA。

状态 (1,2)表示含有叶子1,2,等等。
用伪码描述这个自动机
str ::= input string
begin
12:
if ( lookahead == a || lookahead == b ) then { accept one char; goto 3; }
else { retry; }
3:
if ( lookahead >= 0 && lookahead <= 9 ) then { accept one char; goto 45; }
else { retry; }
45:
if ( lookahead == c ) then { accept one char; goto 456; }
else if ( lookahead != 0 ) { accept one char; goto 45; }
else { retry }
456:
matched
if ( lookahead == c ) then { accept one char; goto 456; }
else if ( lookahead != 0 ) then { accept one char; goto 45; }
else stop
end
这样定义retry
begin
if ( once matched ) { stop; } // 有一次成功说明之前的匹配成功的地方已经是最长了,后面的尝试是失败的
else { str++; restart match; } // 一次都没匹配成功过,从新的位置从新尝试。这里没有考虑强制开始的运算符号。
end
这样似乎并不是足够简单,有很多重复无聊的定式。如果能想展开成汇编一样的代码就好了。
也可以不必去再解释if命令。只要一个一个执行就可以了。
困……遁觉
先做一个试验
对于正则表达式 (a|b)[0-9].*c,可以用以前的方法先生成语法树,然后出DFA。
状态 (1,2)表示含有叶子1,2,等等。
用伪码描述这个自动机
str ::= input string
begin
12:
if ( lookahead == a || lookahead == b ) then { accept one char; goto 3; }
else { retry; }
3:
if ( lookahead >= 0 && lookahead <= 9 ) then { accept one char; goto 45; }
else { retry; }
45:
if ( lookahead == c ) then { accept one char; goto 456; }
else if ( lookahead != 0 ) { accept one char; goto 45; }
else { retry }
456:
matched
if ( lookahead == c ) then { accept one char; goto 456; }
else if ( lookahead != 0 ) then { accept one char; goto 45; }
else stop
end
这样定义retry
begin
if ( once matched ) { stop; } // 有一次成功说明之前的匹配成功的地方已经是最长了,后面的尝试是失败的
else { str++; restart match; } // 一次都没匹配成功过,从新的位置从新尝试。这里没有考虑强制开始的运算符号。
end
这样似乎并不是足够简单,有很多重复无聊的定式。如果能想展开成汇编一样的代码就好了。
也可以不必去再解释if命令。只要一个一个执行就可以了。
困……遁觉