私はclangを(Pythonバインディングを介してlibclang経由で)使用して、コードレビューボットをまとめています。すべての FOR_STMT カーソルには 4 つの子があると仮定しています。INIT、EVAL、INC、および BODY..
for( INIT; EVAL; INC )
BODY;
これは、次のような python で評価式の内容を確認できることを意味します。
forLoopComponents = [ c for c in forCursor.get_children() ]
assert( len( forLoopComponents ) == 4 )
initExpressionCursor = forLoopComponents[ 0 ]
evalExpressionCursor = forLoopComponents[ 1 ]
incExpressionCursor = forLoopComponents[ 2 ]
bodyExpressionCursor = forLoopComponents[ 3 ]
errorIfContainsAssignment( evalExpressionCursor ) # example code style rule
このアプローチは...そもそも素晴らしいとは言えませんが、libclangの結果として受け入れ、特にPythonバインディングはかなりまばらです。しかし、私は最近、次のようなループに気付きました:
for( ; a < 4; a-- )
;
には 3 つの子しかありません。評価は 2 番目ではなく 1 番目になります。私はいつも libclang が FOR_STMT の未使用部分に対して NULL_STMT を返すだけだと思っていました...明らかに、私は間違っていました。
FOR_STMT を解析するための適切なアプローチは何ですか? libclang でこれに役立つものは見つかりません。
更新: libclang のソースを調べてみると、これらの 4 つのコンポーネントは、ビジター オブジェクトを使用して clang::ForStmt クラスからばかに追加されているようです。ForStmt オブジェクトは null ステートメント オブジェクトを返す必要がありますが、どこかのレイヤーが訪問したノード ベクトルからこれらを取り除いているようです...?