如果你只是從理論角度講正則表達式,有這三種結構:
ab # concatenation
a|b # alternation
a* # repetition or Kleene closure
,那麼你可以只是做什麼:
- 創建規則
S -> (fullRegex)
- 對於每個重複項
(x)*
在fullRegex
創建規則X -> x X
和X -> ε
,然後用0123代替。
- 每一個交替
(a|b|c)
創建規則Y -> a
,Y -> b
和Y -> c
,然後用Y
更換(a|b|c)
簡單的遞歸重複此(注意,所有x,
a
,b
和c
仍然可以是複雜的正則表達式)。請注意,當然你必須爲每一步使用唯一的標識符。
這應該夠了。這肯定不會給出最優雅或有效的語法,但這就是正常化的原因(並且它應該在一個單獨的步驟中完成,並且有well-defined steps這樣做)。
一個例子:a(b|cd*(e|f)*)*
S -> a(b|cd*(e|f)*)*
S -> a X1; X1 -> (b|cd*(e|f)*) X1; X1 -> ε
S -> a X1; X1 -> Y1 X1; X1 -> ε; Y1 -> b; Y1 -> cd*(e|f)*
S -> a X1; X1 -> Y1 X1; X1 -> ε; Y1 -> b; Y1 -> c X2 (e|f)*; X2 -> d X2; X2 -> ε
... and a few more of those steps, until you end up with:
S -> a X1
X1 -> Y1 X1
X1 -> ε
Y1 -> b
Y1 -> c X2 X3
X2 -> d X2
X2 -> ε
X3 -> Y2 X3
X3 -> ε
Y2 -> e
Y2 -> f
我希望你是在開玩笑,當你問我們的算法整體概況。正如你可能已經注意到這將是很多工作。如果您對特定問題有任何疑問,請隨時提問,但不要求我們爲您設計實際的代碼。 – Jasper
你的cfg不應該是'S - > a S; S - > b S; S - > epsilon'?我認爲你提供的cfg唯一的字符串是「」,因爲它接受的其他字符串是有限的。 – Wug
這也取決於你想允許哪個正則表達式語法元素?只有理論意義上的正則表達式?或者在大多數引擎中使用它的擴展意義上的正則表達式? –