blob: 205b5cce5f271848b741344078ca46a2b9ab4c7c [file] [log] [blame]
eli.bendersky38165b72011-02-04 08:13:39 +02001import sys
Eli Bendersky3921e8e2010-05-21 09:05:39 +03002from pycparser.c_ast import *
3from pycparser.c_parser import CParser, Coord, ParseError
eli.bendersky38165b72011-02-04 08:13:39 +02004from pycparser.c_lexer import CLexer
Eli Bendersky3921e8e2010-05-21 09:05:39 +03005
6
7def expand_decl(decl):
8 """ Converts the declaration into a nested list.
9 """
10 typ = type(decl)
11
12 if typ == TypeDecl:
13 return ['TypeDecl', expand_decl(decl.type)]
14 elif typ == IdentifierType:
15 return ['IdentifierType', decl.names]
16 elif typ == ID:
17 return ['ID', decl.name]
18 elif typ in [Struct, Union]:
19 decls = [expand_decl(d) for d in decl.decls or []]
20 return [typ.__name__, decl.name, decls]
21 else:
22 nested = expand_decl(decl.type)
23
24 if typ == Decl:
25 if decl.quals:
26 return ['Decl', decl.quals, decl.name, nested]
27 else:
28 return ['Decl', decl.name, nested]
29 elif typ == Typename: # for function parameters
30 if decl.quals:
31 return ['Typename', decl.quals, nested]
32 else:
33 return ['Typename', nested]
34 elif typ == ArrayDecl:
35 dimval = decl.dim.value if decl.dim else ''
36 return ['ArrayDecl', dimval, nested]
37 elif typ == PtrDecl:
38 return ['PtrDecl', nested]
39 elif typ == Typedef:
40 return ['Typedef', decl.name, nested]
41 elif typ == FuncDecl:
42 if decl.args:
43 params = [expand_decl(param) for param in decl.args.params]
44 else:
45 params = []
46 return ['FuncDecl', params, nested]
47
48#-----------------------------------------------------------------
eli.bendersky724b1cc2011-03-05 10:45:08 +020049class NodeVisitor(object):
50 def __init__(self):
eli.bendersky3b52ac02011-03-18 06:32:23 +020051 self.current_parent = None
eli.bendersky724b1cc2011-03-05 10:45:08 +020052
53 def visit(self, node):
54 """ Visit a node.
55 """
56 method = 'visit_' + node.__class__.__name__
57 visitor = getattr(self, method, self.generic_visit)
58 return visitor(node)
eli.bendersky3b52ac02011-03-18 06:32:23 +020059
60 def visit_FuncCall(self, node):
61 print("Visiting FuncCall")
62 print(node.show())
63 print('---- parent ----')
64 print(self.current_parent.show())
65
eli.bendersky724b1cc2011-03-05 10:45:08 +020066 def generic_visit(self, node):
67 """ Called if no explicit visitor function exists for a
68 node. Implements preorder visiting of the node.
69 """
eli.bendersky3b52ac02011-03-18 06:32:23 +020070 oldparent = self.current_parent
71 self.current_parent = node
eli.bendersky724b1cc2011-03-05 10:45:08 +020072 for c in node.children():
73 self.visit(c)
eli.bendersky3b52ac02011-03-18 06:32:23 +020074 self.current_parent = oldparent
eli.bendersky724b1cc2011-03-05 10:45:08 +020075
Eli Bendersky3921e8e2010-05-21 09:05:39 +030076
eli.bendersky0e0a71f2010-10-09 08:32:00 +020077if __name__ == "__main__":
78 source_code = """
eli.bendersky724b1cc2011-03-05 10:45:08 +020079 typedef int Node, Hash;
Eli Bendersky3921e8e2010-05-21 09:05:39 +030080
eli.bendersky724b1cc2011-03-05 10:45:08 +020081 void HashPrint(Hash* hash, void (*PrintFunc)(char*, char*))
eli.bendersky75092b32011-02-04 09:03:28 +020082 {
eli.bendersky724b1cc2011-03-05 10:45:08 +020083 unsigned int i;
84
85 if (hash == NULL || hash->heads == NULL)
86 return;
87
88 for (i = 0; i < hash->table_size; ++i)
89 {
90 Node* temp = hash->heads[i];
91
92 while (temp != NULL)
93 {
94 temp = temp->next;
95 PrintFunc(temp->entry->key, temp->entry->value);
96 }
97 }
98 }
99"""
eli.bendersky38165b72011-02-04 08:13:39 +0200100
101 #--------------- Lexing
eli.bendersky38165b72011-02-04 08:13:39 +0200102 #~ def errfoo(msg, a, b):
103 #~ printme(msg)
104 #~ sys.exit()
105 #~ clex = CLexer(errfoo, lambda t: False)
106 #~ clex.build()
107 #~ clex.input(source_code)
108
109 #~ while 1:
110 #~ tok = clex.token()
111 #~ if not tok: break
112
113 #~ printme([tok.value, tok.type, tok.lineno, clex.filename, tok.lexpos])
114
115 #--------------- Parsing
eli.bendersky0e0a71f2010-10-09 08:32:00 +0200116 parser = CParser()
eli.bendersky724b1cc2011-03-05 10:45:08 +0200117 ast = parser.parse(source_code, filename='zz')
118 ast.show(showcoord=True)
119 nv=NodeVisitor()
120 nv.visit(ast)
121
Eli Bendersky3921e8e2010-05-21 09:05:39 +0300122