Ham Xue
Ham Xue

Reputation: 11

Parsing C in python with libclang but generated the wrong AST

I want to use the libclang binding python to generate a C code's AST. OK, the source code is portrayed below .

#include <stdlib.h>
#include "adlist.h"
#include "zmalloc.h"


list *listCreate(void)
{
    struct list *list;

    if ((list = zmalloc(sizeof(*list))) == NULL)
        return NULL;
    list->head = list->tail = NULL;
    list->len = 0;
    list->dup = NULL;
    list->free = NULL;
    list->match = NULL;
    return list;
}

And a implementation I wrote :

#!/usr/bin/python
# vim: set fileencoding=utf-8


import clang.cindex
import asciitree
import sys

def node_children(node):
    return (c for c in node.get_children() if c.location.file.name == sys.argv[1])

def print_node(node):
    text = node.spelling or node.displayname
    kind = str(node.kind)[str(node.kind).index('.')+1:]
    return '{} {}'.format(kind, text)

if len(sys.argv) != 2:
    print("Usage: dump_ast.py [header file name]")
    sys.exit()

clang.cindex.Config.set_library_file('/usr/lib/llvm-3.6/lib/libclang-3.6.so')
index = clang.cindex.Index.create()
translation_unit = index.parse(sys.argv[1], ['-x', 'c++', '-std=c++11', '-D__CODE_GENERATOR__'])
print(asciitree.draw_tree(translation_unit.cursor, node_children, print_node))

But the final output of this test is like the below :

TRANSLATION_UNIT adlist.c
 +--FUNCTION_DECL listCreate
     +--COMPOUND_STMT 
        +--DECL_STMT 
           +--STRUCT_DECL list
           +--VAR_DECL list
              +--TYPE_REF struct list

Obviously, the final result is wrong. there are much codes left no parsed. I have tried to traverse the translation unit but the result is just like the tree shows---many nodes were gone. Why will be that ? And is there any method to solve the problem? Thank you!

I guess that the reason is that Libclang is unable to parse malloc(). because neither stdlib has been included in this code nor has a user-defined definition provided for malloc.

Upvotes: 1

Views: 1286

Answers (1)

Andrew Walker
Andrew Walker

Reputation: 42490

The parse did not complete successfully, probably because you're missing some include paths.

You can confirm what the exact problem is by printing the diagnostic messages.

translation_unit = index.parse(sys.argv[1], args)
for diag in translation_unit.diagnostics:
    print diag

Upvotes: 1

Related Questions