タイトルが示すように、私は先週末、Perl互換の正規表現に一致する言語のクラスについて思いを巡らせて、パターン内の任意のコードを実行できるマッチング演算子を除外しようとして数時間を費やしました。
あなたはPCREsが何であるかわからない場合は、お読みください。このとこれを。
問題は、インターネットで利用可能なリソースがコンテキストフリー言語でほとんど停止し、PCREがそれらよりも多く一致する可能性があることです(以下を参照)。しかし、この種のことに関する定理や論文をどこで見つけることができるのか、本当にわかりません。
特に、PCREは明らかに通常の言語のスーパーセットです(PCRE構文にはすべての通常の言語演算子があるため)。
任意のCFGをGreibachの標準形式にすることができます。これにより、左再帰が削除されます。私はこれを(?(DEFINE)...)
グループによって使用して、文法を一致するサブルーチンに「翻訳」し、翻訳することによって左再帰でのチョークを回避することができると思います:
- 各制作の先頭にある非終端記号はサブルーチンになります
(?<HEAD>...)
- 各プロダクションの本体はサブルーチンに入れられます。端末はそのまま残され、非端末はプロシージャ呼び出し(つまり
(?&NONTERMINAL)
)になります。 - headと同じ非終端記号を持つすべてのプロダクションは、
|
演算子を使用してORで結合されます((?:...)
必要に応じて、との追加のグループ化) - パターンは、
(?(DEFINE)...)
すべての「翻訳された」プロダクションを含むグループになり、文字列全体に一致する開始シンボルのプロシージャの呼び出し、つまり^(?(DEFINE)...)(?&START)$
これは、すべてのCFGに対処する必要があります。したがって、PCREは任意のCFLと一致できる必要があります。
さらにあります:単純な言語 つまり、文字列の言語を二回繰り返し。この言語はCFLではありません-CFLのポンピング補題は失敗します。(ペイ特に注意することを | VのX ワット| ≤ pが 保持しなければならない、ので、あなただけの始まりまたは2つの繰り返し文字列の端をポンプすることはできません。)
ただし、この言語はPCRE:によって簡単に一致します^(.*)\1$
。したがって、厳密にCFLを上回っています。
どれくらいですか?さて、私が言ったように、私にはわからない。CSLやその間の他のすべてのクラスに関するリソースを見つけることができませんでした。これについて議論したい専門家はいますか?
補遺: PCRE構文のどのサブセットを許可する必要があるかを正確に指定するように求められました。投稿の冒頭で書いたように、パターン内の任意のコードの実行を許可する演算子(など)を除外したかったの??{}
です。
引数のために、pcresyntax(3)のマニュアルページで定義されている構文に固執できると思います。これは、Perl 5.10-5.12が提供するものの合理的なサブセットで、コールアウト(パターン内にないため)を除きます。バックトラッキング制御動詞を追加または削除しても、認識できる言語が変わるかどうかはわかりません。もしそうなら、どのクラスを取得するか、取得しないかを把握しておくとよいでしょう。