pycparserを使ってみた/libclang+sealangでPythonでC++をパースする
いろいろあってC言語のASTを扱う必要が出てきて最終的に行き着いたのがこれ。某uccがPythonで書かれてたらucc使ったんだけどね。
インストールはpipで終了。以下自分用のメモ。書いてて気づいたけどc_ast参照すればいいことに気付いた
FuncDef:関数宣言
decl:宣言関連の情報
param_decls:パラメータの情報
body:関数本体
coord:ソースコード中での位置?
Compound:いろいろ
block_items:リストでいろいろ入ってる
例
[<pycparser.c_ast.Decl object at 0x7f77d48456d8>, <pycparser.c_ast.Decl object at 0x7f77d4845748>, <pycparser.c_ast.FuncCall object at 0x7f77d3ee8168>, <pycparser.c_ast.Decl object at 0x7f77d48457b8>, <pycparser.c_ast.Decl object at 0x7f77d4845828>, <pycparser.c_ast.Decl object at 0x7f77d4845898>, <pycparser.c_ast.For object at 0x7f77d79ad518>, <pycparser.c_ast.If object at 0x7f77d3eee0e8>, <pycparser.c_ast.FuncCall object at 0x7f77d3ee8e58>, <pycparser.c_ast.Return object at 0x7f77d3eea908>]
coord:略
Decl:変数宣言?
name:変数名
quals=spec['qual'],:謎
storage=spec['storage']:謎
funcspec=spec['function']:謎
type:型。c_ast.TypeDeclが入ってる
init=decl.get('init'):謎
bitsize=decl.get('bitsize'):取得できなかった
coord:位置
FuncCall:関数呼び出し
name:呼ばれる関数名。c_ast.IDが入ってる
args: 引数リスト。c_ast.ExprListが入ってる
追記(6/22)
pyparcer貧弱だったので結局libclang+seaclangを使うことにしましたとさ。clangなのでCもC++もパースできる。
libclangのPython bindingが貧弱なのを拡張するやつ。便利でした。使い方がよく分からなかったんですが、libclangのPython binding自体を拡張します。なので使い方としては、普通にlibclangでパースして得られたオブジェクトにbinary_operatorとかが生えてる感じです。当初これが分からなくてめっちゃ時間がかかってしまった。