在 python 脚本中,检查 str 格式的 C 代码的语法正确性

Within a python script, check syntactic correctness of C code in str format

必须在 python 程序中并给定一个包含 C 代码的 str 变量,我想检查 fast 此代码在语法上是否正确,或不。本质上,我只需要通过编译器的前端就可以了。

我当前的实现使用一个临时文件来转储字符串并调用带有子进程的 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..

环顾四周,我发现了 clang.cindex 模块 (pip clang),我试用了它。稍微阅读 main module 之后,第 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!")

然而,似乎即使源文件包含明显的语法错误,也不会抛出异常。任何人都知道我缺少什么来完成这项工作吗?

在一般情况下,我们非常欢迎任何有关如何尽快完成此任务的建议。即使使用 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)

运行它你会得到

3 broken.c:1:1: error: unknown type name 'foo'
3 broken.c:1:8: error: expected ';' after top level declarator

severity 成员是一个 int,其值来自 enum CXDiagnosticSeverity,值

  • CXDiagnostic_Ignored = 0
  • CXDiagnostic_Note = 1
  • CXDiagnostic_Warning = 2
  • CXDiagnostic_Error = 3
  • CXDiagnostic_Fatal = 4