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

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 解析器可以解决这个问题,但目前是一种矫枉过正,无论我多么需要速度。

Ant*_*ala 5

即使文件有语法错误,编译本身也会成功。考虑以下示例:

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 CXDiagnosticSeveritywith values

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