【问题标题】:Unable to modify pycparser AST | Convert AST to C code无法修改 pycparser AST |将 AST 转换为 C 代码
【发布时间】:2012-06-07 17:27:19
【问题描述】:

我正在尝试修改/重构输入 C 源代码。 我正在尝试在输入代码的每一行之后添加 printf 语句。

例如如果我的输入是 -

void foo(){
    // Sample input code
    int a = 0, b = 0;
    a++;
    if(a<5)
         b++;
    b--;
}

我想添加声明printf('Hi');,导致-

void foo(){
    int a = 0, b = 0;
    printf('Hi');
    a++;
    printf('Hi');
    if(a<5){
         b++;
         printf('Hi');
    }
    printf('Hi');
    b--;
    printf('Hi');
}

作为第一步,我只是尝试声明一个变量test 并尝试将其插入到由随机源代码生成的 AST 的开头。 这是我在将 AST 提取到对象 ast 后所涉及的 python 代码 -

for i in range(0,len(ast.ext)):
    ## Look for a function named 'foo'
    if(type(ast.ext[i]) == c_ast.FuncDef and ast.ext[i].decl.name == 'foo'):
        ## Store the list of AST node objects in functionBody
        functionBody    = ast.ext[i].body

        ## Create a Decl object for the variable test
        id_obj          = c_ast.ID('test')
        identifier_obj  = c_ast.IdentifierType(['int'])
        typedecl_obj    = c_ast.TypeDecl(id_obj.name,[],identifier_obj)
        decl_obj        = c_ast.Decl(id_obj.name,[],[],[],typedecl_obj,[],[])

        ## Append the object to a list.
        ## Concatenate to a copy of existing list of AST objects     
        lst1 = []
        lst1.append(decl_obj)
        lst2 = []
        lst2 = copy.deepcopy(functionBody.block_items)
        lst3 = []
        lst3 = lst1+lst2

        ## Create a modified AST and print content
        functionBody1 = c_ast.Compound(lst3)
        functionBody1.show()

我发现生成的结构 functionBody1 没有任何变化,并且每当我尝试使用其 show( ) 方法时也会收到以下错误。

'list' object has no attribute 'show'

知道我要去哪里偏离轨道吗?

谢谢

【问题讨论】:

  • lst2 和 lst3 被初始化为 [] 然后分配别的东西有什么原因吗?你不要对 lst1 那样做。
  • @IraBaxter 我也将 lst1 初始化为 [ ] 。而且没有真正的理由。只是表明这些变量是 list 类型的。
  • 能否为未修改的函数重新生成文本?

标签: python abstract-syntax-tree pycparser


【解决方案1】:

我找到了三个地方,你传递了一个列表,而你应该传递的地方没有。

## Create a Decl object for the variable test
id_obj          = c_ast.ID('test')
identifier_obj  = c_ast.IdentifierType(['int'])
typedecl_obj    = c_ast.TypeDecl(id_obj.name,None,identifier_obj)
decl_obj        = c_ast.Decl(id_obj.name,[],[],[],typedecl_obj,None,None)

我对此不是很熟悉,因为我也在学习 pycparser,但是这个更改为我修复了你的回溯。

【讨论】:

  • 谢谢!这就是诀窍。你又是怎么想出来的?我真的无法从可用的文档中看出这一点。
  • 我深入研究了 pycparser 代码中的类声明以查看它的预期。我追求的最大线索是错误消息,这是因为当您执行 show() 时,它会调用每个孩子执行 show()。因此,错误表明您提供了一个列表,而预期的对象是支持 show() 调用的对象。花了一段时间才弄清楚参数何时不正确,因为除了模块本身包含的示例之外,似乎真的缺乏此代码的示例。
  • 没问题。我可能会很快开始发布 pycparser 问题。也许你会回答我的……似乎没有多少人再用这个模块做事了。
  • 那是真的很想帮忙:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-27
  • 1970-01-01
  • 2018-09-12
  • 1970-01-01
  • 2019-07-10
相关资源
最近更新 更多