我用了半个多月搜这个,搜索方向有下面这么多……
1.llvm-clang
2.gcc
3.notepad++是开源的,它也能识别函数
开源的要么要会Cmake(还有makefile,这些跨平台的玩意我还是门外汉……),
要么依赖clang、llvm库(我都不明白他们include的东西是从哪里下载的),
要么我没想出来怎么通过命令行和qtGUI程序交换得出结果(难道做出来的小工具还得先安装一个clang?)
还想过自己写一个预处理器,但是对于还有自定义类型变量,我望而却步
1.clang的方向
最近才知道clang和llvm,拿到源码我都不会用,linux虚拟机我万年没用了还得什么make那些makefile。
深入研究Clang(一)Clang和LLVM的关系及整体架构
后来不断地爬坑,发现这根本不是一个小程序能完事的!那些用clang的都得都是下载源码然后自己编译,再另写代码引用库。
基于Clang 的编程-统计源代码中的函数
后来我又找了git上几个看起来能用的,但是他们include的clang在哪?我都搞不明白,我下了9.0的和3.0的clang发现目录结构都特么不一样了,按着项目年份找不高于的,用Cmake、make都会说找不到库的情况……我真是没招了
https://github.com/shining1984/screader
https://github.com/stephenatwork/clang-extract
经过一段了解之后,又发现什么libclang说是可以不研究clang而使用里面的库(麻蛋不弄了),我安装了clang的可使用版本,然后照着命令行来敲一段
clang如何查看AST?
1.总在提示include的库不存在
(我只是要函数名和参数类型,不必要真正编译来检查错误啊!)
(删掉include,就写了个int main()函数,解决问题1)
2.发现生成的这个【dot】后缀的也不是直接就能用的……
2.gcc的方向
gcc-xml的编译、使用方法,(奈何我的msvc编译器不是符合的版本,生成的exe没法用)
GCCXML 安装
https://github.com/gccxml/gccxml
上面那个链接不错,能用,编译出gcc-xml的exe文件(但为啥就没有编译好的exe提供下载……),貌似需要本机的编译器环境支持(那个博文说的是“附庸”),不过也是提供了一种思路【cpp->xml->我需要用的工具】
3.开源IDE的方向
从notepad++里也没找到什么好办法
比如“虐心”的获取C++函数列表
我开始找源码
https://github.com/notepad-plus-plus/notepad-plus-plus
于是我找到了【functionlist.xml】里面关于c++的描述——实际上只是正则表达式
<!-- ========================================================= [ C++ ] -->
<parser
displayName="C++"
id ="cplusplus_syntax"
commentExpr="(?s:/\*.*?\*/)|(?m-s://.*?$)"
>
<classRange
mainExpr ="^[\t\x20]*(class|struct)[\t\x20]+\w+\s*(final)?\s*(:\s*(public|protected|private)\s+\w+\s*)?\{"
openSymbole ="\{"
closeSymbole="\}"
>
<className>
<nameExpr expr="(class|struct)[\t\x20]+\w+" />
<nameExpr expr="[\t\x20]+\w+" />
<nameExpr expr="\w+" />
</className>
<function
mainExpr="^[\t\x20]*((static|const|virtual)\s+)?(\w+(\s+\w+)?(\s+|(\*|\*\*|&)\s+|\s+(\*|\*\*|&)|\s+(\*|\*\*|&)\s+))?(\w+\s*::)?(?!(if|while|for|switch))[\w~]+\s*\([^\)\(]*\)(\s*const\s*)?(\s*(final|override|final\s*override|override\s*final)\s*)?[\n\s]*\{"
>
<functionName>
<funcNameExpr expr="(?!(if|while|for|switch))[\w~]+\s*\(" />
<funcNameExpr expr="(?!(if|while|for|switch))[\w~]+" />
</functionName>
</function>
</classRange>
<function
mainExpr="^[\t\x20]*((static|const|virtual)\s+)?\w+(\s+\w+)?(\s+|(\*|\*\*|&)\s+|\s+(\*|\*\*|&)|\s+(\*|\*\*|&)\s+)(\w+\s*::)?(?!(if|while|for))\w+\s*\([^\)\(]*\)(\s*const\s*)?[\n\s]*\{"
>
<functionName>
<nameExpr expr="(?!(if|while|for))\w+\s*\(" />
<nameExpr expr="(?!(if|while|for))\w+" />
</functionName>
<className>
<nameExpr expr="\w+(?=\s*::)" />
</className>
</function>
</parser>
4.自己写预处理器的方向
不可能的……
但是我找到的一篇文章,佩服这位大哥……
开发自己的IDE(系列)
5.其他方法
正则表达式方法
提取.c文件中的函数名
6.收获
编译器认识了不少:
MSVC
gcc-mingw
clang-llvm
cmake(makelist)-make(makefile)-gcc。这样的流程