Foi*_* Ts 1 c python llvm clang
必须在 python 程序中并给定一个str
包含 C 代码的变量,我想快速检查此代码在语法上是否正确。本质上,我只需要通过编译器的前端传递它。
我当前的实现使用临时文件来转储字符串并使用子进程调用 clang 进程(下面的非工作代码来说明我的解决方案)。这对于我的需求来说非常慢。
src = "int main(){printf("This is a C program\n"); return 0;}"
with open(temp_file, 'w') as f:
f.write(src)
cmd = ["clang", abs_path(f), flags]
subprocess.Popen(cmd)
## etc..
Run Code Online (Sandbox Code Playgroud)
环顾四周后,我发现了我尝试过的clang.cindex
模块 ( pip clang
)。在阅读了主要模块后,第 2763-2837 行(特别是第 2828 行)让我得出以下结论:以下代码片段将满足我的需求:
import clang.cindex
......
try:
unit = clang.cindex.TranslationUnit.from_source(temp_code_file, ##args, etc.)
print("Compiled!")
except clang.cindex.TranslationUnitLoadError:
print("Did not compile!")
Run Code Online (Sandbox Code Playgroud)
但是,似乎即使源文件包含明显的语法错误,也不会引发异常。任何人都知道我缺少什么才能完成这项工作?
在一般情况下,任何有关如何尽快完成此任务的建议都非常受欢迎。即使使用clang.cindex
,我也无法避免将字符串表示的代码写入临时文件,这可能是额外的开销。编写一个 python 解析器可以解决这个问题,但目前是一种矫枉过正,无论我多么需要速度。
即使文件有语法错误,编译本身也会成功。考虑以下示例:
import clang.cindex
with open('broken.c', 'w') as f:
f.write('foo bar baz')
unit = clang.cindex.TranslationUnit.from_source('broken.c')
for d in unit.diagnostics:
print(d.severity, d)
Run Code Online (Sandbox Code Playgroud)
运行它,你会得到
3 broken.c:1:1: error: unknown type name 'foo'
3 broken.c:1:8: error: expected ';' after top level declarator
Run Code Online (Sandbox Code Playgroud)
的severity
成员是 an int
,其值来自enum CXDiagnosticSeverity
with values