2017-10-30 16 views
3

regexNの多くは同じリテラルになりますabc | cde | abc | cde | cde | abcまたは<regex1> | <regex2> | <regex3> | <regex4> | <regex5> | <regex6>、などのregexesで繰り返しを治療するための最良の方法は何ですか?繰り返し要素

私が言っていることを説明するために、私はドイツ語の例を挙げます。ここにはいくつかの現在の緊張型の言葉を解析できるサンプルgrammarがあります。 1PLと3PLのため

grammar Verb { 
    token TOP { 
     <base> 
     <ending> 
    } 
    token base { 
     geh | 
     spiel | 
     mach 
    } 
    token ending { 
     e  | # 1sg 
     st | # 2sg 
     t  | # 3sg 
     en | # 1pl 
     t  | # 2pl 
     en  # 3pl 
    } 
} 

my @verbs = <gehe spielst machen>; 
for @verbs -> $verb { 
    my $match = Verb.parse($verb); 
    say $match; 
} 

エンディング(en)は同じですが、明確化のためには、両方のtokenにそれらを配置する方が便利です(私の実際のデータにinflexionalパラダイムは、はるかに複雑であり、迷子になるのは簡単です)。 token endingは期待どおりに動作しますが、私がenを1回だけ入力すると、プログラムは少し速く動作することになります(私はregexesのテストを繰り返しました。私のデータでは、そのような繰り返しがたくさんあるので、それらを治療する最良の方法は何か?もちろん

、私は、grammararrayに語尾を入れて、この配列.uniqueを行い、その後、ちょうど値を渡すことができます。

my @endings = <...>; 
@endings .= unique; 
... 
token ending { @endings } 

しかしgrammarからデータを取って、それはあまり明確になります。また、場合によっては、別々のトークンを別々のトークンにする必要がある場合もあります(token ending {<ending_1sg> | <ending_2sg> ... <ending_3pl>}grammarの外側に定義されている場合は不可能です)。

答えて

2

わかりやすくいただくために、

ところで、空の正規表現はこの場合無視されるので、ブランチ演算子ではなく、ブランチ演算子で始めることができます。最後に置いてください。特に、行を追加したり削除したりする必要がある場合は、もっと簡単にすることができます:

grammar Verb { 
    # ... 
    token ending { 
     | e  # 1sg 
     | st  # 2sg 
     | t  # 3sg 
     | en  # 1pl 
     #| t  # 2pl 
     #| en  # 3pl 
    } 
} 

あなたが書いているのは、人間専用のものなので、パーサー用ではありません。さて、別の正規表現を使って別の解析マッチに行き、末尾に$<_3sg>または$<_2p1>(regexesという名前でregexesという名前が付いている)という名前をつけてコメントを付けることはできません。コンピュータに余分な作業を強いることができます。そして明らかに:exhaustiveまたは:overlapを使用する必要があります。代わりに、私は3sgと2p1の両方を表す名前付き正規表現を作成し、上のように定義することをお勧めします。

+0

あなたの答え、特に第1の選択肢の前に '|'を置く可能性を示してくれてありがとう! 私は両方の解決策を考えました(重複した行をコメントするか、重複を1つの 'token'にマージする)。どちらも私にはある欠点があります(次のコメントに続きます)。 –

+1

①数多くの異なるエンディングを持っていますが、どれが唯一で重複しているのかを覚えておくのは非常に難しく、手動で多くの行をコメント/コメント解除することは必然的にエラーになりがちです。 ②私の条件が少し変わった場合(いくつかのエンディングを追加したり削除したりしたい場合)、すべての行をコメント/アンコメントする必要があります。だから、私は「ユニーク」のようなものを考えていた。唯一の解決策は、コンピュータに余分な作業をさせることです。私のテキストコーパスとベースの数が非常に多いので、それほどエキサイティングではありません。 –

+1

@EugeneBarsky文法を生成する方法や、文法の一部を生成する方法が必要なようです。そうすれば、あなたが理解している方法でジェネレータを記述し、生成コードを変更することができます。警告、これは厳しいです!私はこれについてのブログ記事を読むが、それは単なる要約である。完全な実装はより困難です。 (しかし、作者は、あなたがダウンロードして見ることができるモジュールの例にリンクしています)。https://perl6advent.wordpress.com/2015/12/08/day-8-grammars-generating-grammars/ – piojo

関連する問題