vera ++ルールを使用してローカル(またはその他の)変数定義を解析するのはかなり複雑ですが、もちろん実行可能です。基本的なC++の解析とトークン化は、vera++によって行われます。
getTokens
基本的なアプローチは、完成したC++ステートメントをチェックする小さなステートマシンと組み合わせてvera++の関数を使用することです。トークンを収集し(後でリストを設定するために変数名が必要になるため、それらの値になる場合もあります)、完全なステートメントが得られるまでそれらを連結する必要があります。完全なステートメントがある場合は、正規表現を使用して、それが変数定義であるかどうかを確認し、部分一致から変数名を抽出できます。{}
また、それがローカル変数定義であるかどうかを知るために、ブロック内にいるかどうかを覚えておく必要があります。
開始点として、コードの完全な中括弧付きブロックをチェックするvera++のルールT019のステートメントへのトークンを収集するための単純なステートマシンを構築するためのサンプルを見つけることができます。
vera ++を使用して変数定義の解析を実行しましたが(さまざまな命名規則を確認するため)、残念ながら、完全なコードを投稿することはできません。これは、雇用主の専有作業であるためです。しかし、変数宣言をチェックするために使用している正規表現を示すスニペットを提供できます。
set isVar false
if [regexp {\s+((extern\s+)?(static\s+|mutable\s+|register\s+|volatile\s+)?(const\s+)?)?((identifier#[^#]+#\s+colon_colon\s+)*identifier#[^#]+#)\s+(star\s+|const\s+|and\s+|less.*greater\s+|greater\s+)*(identifier#[^#]+#\s+colon_colon\s+)*identifier#([^#]+)#(\s+leftbracket.*rightbracket)?(\s+assign)?.*semicolon$} $statement m s1 s2 s3 s4 s5 s6 s7 s8 s9 s10] {
set locVarname $s9
set isVar true
set currentMatch $m
} elseif [regexp {\s+((extern\s+)?(static\s+|mutable\s+|register\s+|volatile\s+)?(const\s+)?)?(char\s+|int\s+|short\s+|long\s+|void\s+|bool\s+|double\s+|float\s+|unsigned\s+|and\s+|star\s+|unsigned\s+)+(identifier#[^#]+#\s+colon_colon)*\s+identifier#([^#]+)#(\s+leftbracket.*rightbracket)?(\s+assign)?.*semicolon$} $statement m s1 s2 s3 s4 s5 s6 s7 s8] {
set locVarname $s7
set isVar true
set currentMatch $m
}
$statement
前述の完全なステートメントが含まれています。identifier
を使用してトークン値をトークンに連結しidentifier#<value>#
、正規表現グループを使用してそれを抽出していることに注意してください。