5

{}および[]および(、については、次のように C++ テンプレートの使用に使用されるように、for)を定義できるようにしたいと考えています。syntax region<>

a<b>

しかし、次のようなものと衝突することなく、そのような構文領域を作成する方法はありますか?

if( a < b<c>::d )

1 つ目<は明らかに「より小さい」演算子であり、テンプレート パラメーターの領域の開始として破棄する必要があります。

いくつかのオプションを使用しようとしましたが、機能させることができませんでした。複雑な正規表現を使用してテンプレート引数領域を識別しようとすることは実際には不可能に思えますが、ネストされた自己参照パターンを使用してバランスの取れたペアをチェックすることによってのみ機能します。

4

2 に答える 2

4

@ingo-karkatの回答に基づいて、空白の使用についてもう少し考えてみたところ、満足できる十分な一致パターンが得られたと思います(これはケースの90%以上をキャッチすると思います)。

syn region AngleBrackets matchgroup=AngleBracketContents 
start='[[:space:]<]\@<!<<\@!'
end='>'

start空白や.が前に付い<ていない一致。ほとんどの場合、リレーショナル操作は空白で囲まれるため、空白が前にあるかどうかを確認することが重要な要素であり、テンプレートの開き括弧の前に空白を置かないことも非常に一般的です。<

また、すぐに別の が続かないことも確認し<ます。

これは私がやっていることのスナップショットです(領域内の演算子は領域の色を取得し、ネストされた領域の色を変更します。これはいくつかのマイナーな修正を加えて改善されたレインボー括弧に基づいて構築されています):

VIM スナップショット

アップデート

VIM 正規表現を次のように変更しました。

\v%(<operator\_s*)@<!%(%(\_i|template\_s*)@<=\<[<=]@!|\<@<!\<[[:space:]<=]@!)

この最後のものは、実際に良いコード スタイルを適用するのに役立ちます。

于 2012-11-29T19:24:45.370 に答える
1

80% の解決策を求めて、内部のテキストを空白以外の識別子に制限する限り<...>(コーディング スタイルが比較演算子を空白で囲んでいると仮定します)、:syntax match代わりに:syntax region(これは開始一致で既にトリガーされ、チェックせずに) を使用します。これは動作するはずです (単一の正規表現が begin と end の両方に一致する必要があるため)。

(実際のコンパイラでの) C++ の解析の難しさについては既に多くのことが言われているため、正規表現を使用した汎用解析ソリューションが完璧であるとは期待しないでください。(また、シンタックス ハイライトは単なる視覚補助であることを忘れないでください。あまり頼りにしないでください)。

于 2012-11-29T14:32:46.950 に答える