Python 中 C++ 的简单标记器

Posted

技术标签:

【中文标题】Python 中 C++ 的简单标记器【英文标题】:Simple tokenizer for C++ in Python 【发布时间】:2016-04-22 19:56:32 【问题描述】:

努力寻找一个 Python 脚本库来标记化(找到特定的标记,如函数定义名称、变量名称、关键字等)。

我已经设法使用this 之类的东西找到关键字、空格等,但我发现这对于函数/类定义名称等 来说是一个很大的挑战。我希望使用预先存在的脚本;我探索了Pygments,但没有成功。它的lexer 对我想要的东西来说似乎很神奇,但不知道如何在 Python 中使用它以及为每个找到的令牌获取 positions

例如,我正在考虑做这样的事情:

int fac(int n)

    return (n>1) ? n∗fac(n−1) : 1;

从上面我想得到的源代码:

function_name: 'fac' 在位置 (x, y) variable_name: 'n' 在位置 (x, y+8)

编辑: 任何建议都将不胜感激,因为我在这里对 C++ 中的标记化和解析一无所知?

【问题讨论】:

您是在谈论“函数/类定义”来识别它们的语法吗?如果是这样,这基本上是一个不适合标记器的问题,您需要可以处理无上下文语法的东西,即解析器 Tokenizer with Pygments in Python 的可能重复项。你几分钟前问过这个问题! @ChrisP 我试图扩展它并将它与我之前的问题区分开来,因为现在我正在详细介绍另一条更通用的(也许)路线。 要求人们推荐工具的问题是题外话。 @en_Knight 我应该更清楚一点,我会编辑我的问题。为了简单地回答您的观点,不,我不想要语法,而只是提取它的名称,并且 - 显然 - 确定它是在该行定义的函数。 【参考方案1】:

Eli Bendersky 是个聪明人,有时在 SO 上也很活跃。他有一篇关于这个问题的博文,我会直接向你推荐:Parsing C++ in Python with Clang。

因为事情消失了,所以要点如下:

Eli Bendersky 用 Python 编写了一个 C 语言(不是 C++)解析器,名为 pycparser。人们一直在问他是否会增加对 C++ 的支持。他不是。他建议人们使用 libclang 的 Python 绑定来访问“Clang 团队发誓要保持相对稳定的 C API,允许用户在抽象语法树 (AST) 级别检查解析的代码”。

您可以在 PyPI here. 上单独找到绑定,但请注意,您必须安装 clang,因此您可能只想将 PYTHON_PATH 直接指向安装位置。

【讨论】:

这是一个很好的答案。我试图解决为什么 OP 不能做他想做的事情,但这似乎涉及一些更实际的解决方案。 +1【参考方案2】:

您正在努力寻找一个 Python 库来做您想做的事,因为从根本上说,您想做的事是不可能做到的。

我已经设法使用类似的方法找到关键字、空格等,但我发现它对于函数/类定义名称等来说是一个很大的挑战

你的意思是这样的:

foo = 3
def foo():pass

foo 是什么?一个标记器应该/可以告诉你的是 foo 是一个标识符。它的 context 告诉你它是一个变量还是一个函数声明。您需要一个解析器来处理上下文无关语法。在数学上,上下文无关文法的空间对于标准词法分析器来说太大了。

尝试解析器:here's one in python

通常我会尝试在此处为您提供链接以区分主题,但这太宽泛,无法提供一个好的链接。如果您有兴趣,请从任何标准编译器文本开始。在 SE 的其他地方,我们看到这个问题以theoretical question 的形式弹出,并且以某种形式出现在as a famous question about html

一旦您意识到分词器(通常)是(大部分)基于正则表达式构建的,您的任务不会顺利结束的原因就会变得更加明显。


既然你知道了术语,我想你会找到this SO article useful,它推荐gcc-ml。我不知道它是最新的,但它是您正在寻找的程序类型。

【讨论】:

你的积分真的很有帮助;事实上,我在黑暗中寻找,因为我误解了我在寻找什么。那么,您是否知道任何以我在描述中提到的方式处理 C++ 的解析器? 是的。 Gcc 是一个很好的 :) 除了开玩笑,any 解析器可以处理 C++。我不会尝试展开你自己的——C++ 是一种非常复杂的语言。我选的那个很好,但是再一次,使用现有的 C++ 编译器和解析树。我熟悉的大多数编译器都允许您在不完全编译的情况下转储这些信息 @nk-fford 看到我的编辑,我认为它有你正在寻找的东西的类型

以上是关于Python 中 C++ 的简单标记器的主要内容,如果未能解决你的问题,请参考以下文章

Python 中带有 Pygments 的分词器

使用 SWIG 的 C++ 的 Python 包装器

尝试通过 Process Pipe 发送/接收到 python 包装器,C++ 代码

Python:迭代器 Iterator

在 Python 中使用 C++ DLL

使用 python 标记日志到 gcp 日志查看器