理論的な観点から正規表現について話しているだけの場合、次の3つの構成があります。
ab # concatenation
a|b # alternation
a* # repetition or Kleene closure
次にできること:
- ルールを作成する
S -> (fullRegex)
- ルールを作成し、
(x)*
で繰り返される用語ごとに、を置き換えます。fullRegex
X -> x X
X -> ε
(x)*
X
- 交代ごとに
(a|b|c)
ルールY -> a
を作成Y -> b
しY -> c
、次に(a|b|c)
、Y
これを再帰的に繰り返すだけです(すべてx,
a
、b
およびc
は複雑な正規表現である可能性があることに注意してください)。もちろん、すべてのステップで一意の識別子を使用する必要があることに注意してください。
これで十分です。これは確かに最もエレガントで効率的な文法を提供しませんが、それが正規化の目的です(そして、これは別のステップで実行する必要があり、これを実行するための明確なステップがあります)。
一例: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