标记化和AST

时间:2012-01-19 19:17:46

标签: c++ c static-analysis abstract-syntax-tree

对你们所有人都有一个相当抽象的问题。我正在考虑参与静态代码分析项目。它使用C和C ++作为开发语言,因此,如果您的响应中的任何一种语言中的任何一种语言都很好。

我的问题: 我需要了解一些用于处理静态分析代码的基本概念/构造。我听说人们使用AST和标记化等等。我只是想知道是否有什么可以澄清这些东西如何应用于创建静态分析工具?我更像是对标记化的解释,因为我真的不太了解它。我知道这是一种处理字符串的方法,但我对这个答案没有信心。此外,我知道我正在研究的项目在分析之前将代码传递给预处理器。有谁能解释一下?当然,如果它是静态代码分析,它不需要预处理?

希望有人可以为我解决这个问题。

干杯。

3 个答案:

答案 0 :(得分:5)

如果您对静态分析感兴趣,那么您不应该为语法分析(即lexing,解析,构建抽象语法树)而烦恼,因为这对您没有太多了解。

所以我建议你使用一些现有的解析基础设施。如果要分析C ++源代码,尤其如此,因为编写C ++解析器是一件困难的事情。

例如,您可以利用GCC编译器或LLVM/Clang编译器。请注意他们的开源许可证:GCC属于GPLv3,而Clang / LLVM具有类似BSD的许可证。 GCC不仅能够处理C& C ++,还有Fortran,Go,Ada,Objective-C。

由于GCC的GPLv3许可,您在其上的开发应该也是GPLv3下的免费软件。但是,这也意味着海湾合作委员会社区规模很大。如果您了解Ocaml并且只对C的静态分析感兴趣,您可以考虑Frama-C(LGPL许可)

实际上,我正在致力于GCC,提供MELT扩展框架(MELT也获得GPLv3许可)。 MELT是一种扩展GCC的高级域特定语言,应该是使用GCC的强大框架和内部表示(Gimple,Tree,...)进行静态分析的理想选择。

(当然,LLVM人员也很高兴能够使用他们的工作;没有人知道LLVM和GCC,因为学习这么大的软件已经是一个挑战,所以人们必须选择他们投入的时间)

所以我的建议是加入现有的静态分析或编译工作,不要从头开始重新发明轮子(因为这意味着多年的努力,只是为了拥有一个好的解析器)。

通过这样做,您将利用现有的基础架构(因此您不必担心AST-s和解析),并且您将改进一些现有项目。

如果您对MELT感兴趣,我将非常高兴。 FWIW,2012年1月24日在巴黎举行了MELT教程,HiPEAC conference

答案 1 :(得分:4)

标记化是将源文本分解为语言元素(如运算符,变量名,数字等)的行为。解析读取标记序列并构建Abstract Syntax Trees,这是一种特定的程序表示。对于静态分析来说,标记化和解析是必要的,但是很难有趣,就像玩扑克而不是游戏的有趣部分一样,这是一种必要的方式。

如果你正在构建一个静态分析器(你暗示你希望使用在C或C ++中实现的那个),那么你将需要基本的编译知识(解析不是很多,除非你为这个语言构建一个语法分析器)分析),但肯定关于程序表示(ASTs,三元组,控制和数据流图,......),类型和属性推断,以及分析准确性的限制(保守分析的原因)。 程序表示是基础,因为这些是大多数静态分析器真正处理的数据结构;它很难直接从程序文本中榨出有用的事实。这些概念可用于在任何编程语言中实现静态分析功能,以实现分析类型工具;在C或C ++中实现它们并没有什么特别之处。

对于第一部分,请运行,不要走到最近的编译器类。如果您没有它,您将无法在工具构建中执行任何有效的操作。第二部分你将更有可能在研究生计算机科学课上找到。

如果您超越了基本知识问题,您将决定从头开始实施分析工具,或者在现有分析工具基础架构的基础上构建。很少有人决定从头开始建造一个;需要大量的工作(数年或数十年)来构建强大的解析器,流量分析器等,作为任何特定静态分析的基础。大多数人都试图使用一些现有的基础设施。

http://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis

有很多候选人

如果您坚持处理C或C ++并构建自己的自定义复杂分析,那么真的真的需要一个能够处理真正的C和C ++代码的工具。恕我直言,有限数量的优秀候选人:

  • GCC(以及Starynkevitch的MELT等各种移植物,对此我知之甚少)
  • Clang(相当壮观的工具集)
  • DMS(及其C and C++ front ends)[我公司的工具]
  • Open64编译器基础结构
  • Rose编译器基础架构(基于EDG的行业前端)

这些都是大系统,需要大量投资才能理解并开始使用。不要低估学习曲线。

有很多其他工具可以使用C和C ++进程,但是“有点”对静态分析来说是无用的。

如果您打算简单地使用静态分析工具,您可以避免学习大多数解析和程序表示问题;相反,您需要尽可能多地了解您打算使用的特定分析工具。使用上面的编译器背景你仍然会好多了,因为你会理解这个工具的作用,它为什么会这样做,以及它为什么会产生它所做的答案(通常它会产生很多不满意的答案)由于分析准确性的保守限制而导致的方式)。

最后,您应该清楚地了解静态分析动态分析之间的区别[使用在运行时收集的数据来确定程序属性]。大多数最终用户不关心如何获取有关其代码的信息,并且每种分析方法都有其优点和缺点。

答案 2 :(得分:2)

如果您正在研究C&amp ;;的静态分析C ++,你的第一站应该是libclang,以及它的相关论文。

就运行预处理器的原因而言,静态分析意味着捕获错误和可能的非预期代码功能(非常基本),这必须分析编译器将编译的内容,而不是用户看到的内容。

我很确定@Ira Baxter会弹出一个更完整的答案:)