c++ - 如何使用语法树编写 C 或 C++ 程序来检测另一个 C 程序中的模块

标签 c++ c parsing abstract-syntax-tree

我正在做一个项目,我必须将 C 程序分成多个模块,并找出执行每个模块所花费的时间。我必须使用 C 或 C++ 来执行此操作。

例如:第一个模块将是 main() 然后在里面你可能有其他模块,如 for,或 while如果

这实际上就像是为程序生成一个语法树,以文本的形式。

所以我正在寻找一种方法来做到这一点,或者任何可以帮助我解决这个问题的框架,或者任何建议,任何东西都会很棒!

提前致谢:)

编辑:

好吧,我通过给出我们研究所提到的样本输入和预期输出来让它更清楚,

输入:

  void main() { 
       int h=2,j=5,k=1;
       while (h>j) {
          h++; 
          for (k=100;k>0;k/=2) { 
             if (i<=5) {
                d=n*10;
                p=n/10;
             } 
          }
        }
   }

输出:

  main 
  begin
  h=2
  j=5
  k=1
  *************
  while 
  h>j 
  0.2087
  ************* 
  begin
  h++
  *************
  for 
  k=100 
  k>0 
  k/2
  0.8956
  ************* 
  begin
  if i<=5
  *************
  begin
  d=n*10
  p=n/10
  0.1153
  end
  *************
  end
  end

抱歉输出,它是垂直的,我认为它给了每个人一个清晰的想法! :) –

最佳答案

少于 100 行对您没有多大帮助;人们可以在这么大的程序中编写一个使用 C 语言(和编译器扩展!)的所有功能的程序。所以你说你必须处理整个 C 语言(语句、表达式、函数、结构、typedef、宏、预处理器条件,...)。如果这是一个学校项目,我认为那太难了;您需要将您的项目限制在一个有趣的子集内,例如函数、赋值、while 语句和函数调用。

你需要直接做的是

  • C 语言的解析器
  • 超越 AST 的能力
  • 修补 AST 的能力
  • 将 AST 作为源文本发出的能力

程序转换系统几乎是完成此类工作的理想引擎。 这些允许您另外对 AST 进行模式导向的更改,这使得这更容易实现。

您可能可以使用 TXL 或 Stratego 来做到这一点;我确信两者都有 C 解析器,可以处理您应该愿意做的有限的 C 子集。

你可以用我们的 DMS Software Reengineering Toolkit 来做,虽然这可能不适合学生在短时间内使用。 (TXL 和 Stratego 是免费的,但也可能有陡峭的学习曲线)。

但是你会发现这个document on instrumenting code构建测试覆盖工具可能是对使用转换系统完成任务所需执行的操作的理想介绍。

编辑:我将 Hari 的评论和一个例子转录到他的问题中。

我认为他想要一个示踪剂而不是分析器。

他可以使用检测来做到这一点,但他需要插入大量检测,因为看起来目标是跟踪每个 Action 。

在那种情况下,如果他有一个解释器会更容易,但他需要一个能够保持代码结构的解释器,以便他可以在运行时报告代码结构(因此编译成 pcode 的 CINT 不会是正确答案)。

他需要的是使用符号表将完整的 C 语言解析为 AST、一个执行 AST 的解释器和一个 pretty-print ,以便他可以将他当前正在执行的 AST 的适当部分转换回文本以报告进度。

DMS 仍然是这方面的一个很好的基础,因为它也拥有支持这项任务所需的所有机制。 解析 C 文本,构建符号表(所有这些都内置于 C 的 DMS 中),然后运行自定义解释器。 这很容易编码为 AST 上的解释器;树节点类型上的大案例语句将是解释器核心,节点类型特定案例执行 AST 节点隐含的操作(包括爬上或爬下树,用新值更新符号表条目,计算表达式中间值结果,当然还有报告进度。

ANTLR 可能会起作用;它有一个 C 解析器,但我不太确定 pretty-print 。解释器的工作方式几乎相同。

TXL 和 Stratego 可能对此感到尴尬,因为您不清楚如何使用它们的纯转换风格来交替解释和打印跟踪数据。

关于c++ - 如何使用语法树编写 C 或 C++ 程序来检测另一个 C 程序中的模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5497512/

相关文章:

c - 指向二维数组并在 C 语言的其他函数中声明的指针

parsing - 仅捕获 `PID` 中的 `netstat` 字段

c++ - 使用 Rcpp::IntegerVectors 添加 int

c - fscanf 提取文件中多个不同大小的整数

c++ - 在 C++ 中从 double 到 float 的转换

c - 带进位的递归 2 个整数相加

java - 如何使用任意数量的参数调用 Method.invoke?

c++ - TinyXML2 C++ - 从旧的/格式不正确的 XML 文件中提取特定数据

c++ - 尝试将字符串对象添加到整数

c++ - 如果 std::greater<>,那么为什么是 std::less(而不是 std::lesser<>)?