eli.bendersky | 38165b7 | 2011-02-04 08:13:39 +0200 | [diff] [blame] | 1 | import sys
|
Eli Bendersky | 3921e8e | 2010-05-21 09:05:39 +0300 | [diff] [blame] | 2 | from pycparser.c_ast import *
|
| 3 | from pycparser.c_parser import CParser, Coord, ParseError
|
eli.bendersky | 38165b7 | 2011-02-04 08:13:39 +0200 | [diff] [blame] | 4 | from pycparser.c_lexer import CLexer
|
Eli Bendersky | 3921e8e | 2010-05-21 09:05:39 +0300 | [diff] [blame] | 5 |
|
| 6 |
|
| 7 | def 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.bendersky | 724b1cc | 2011-03-05 10:45:08 +0200 | [diff] [blame] | 49 | class NodeVisitor(object):
|
| 50 | def __init__(self): |
eli.bendersky | 3b52ac0 | 2011-03-18 06:32:23 +0200 | [diff] [blame] | 51 | self.current_parent = None
|
eli.bendersky | 724b1cc | 2011-03-05 10:45:08 +0200 | [diff] [blame] | 52 |
|
| 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.bendersky | 3b52ac0 | 2011-03-18 06:32:23 +0200 | [diff] [blame] | 59 |
|
| 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.bendersky | 724b1cc | 2011-03-05 10:45:08 +0200 | [diff] [blame] | 66 | 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.bendersky | 3b52ac0 | 2011-03-18 06:32:23 +0200 | [diff] [blame] | 70 | oldparent = self.current_parent
|
| 71 | self.current_parent = node
|
eli.bendersky | 724b1cc | 2011-03-05 10:45:08 +0200 | [diff] [blame] | 72 | for c in node.children():
|
| 73 | self.visit(c)
|
eli.bendersky | 3b52ac0 | 2011-03-18 06:32:23 +0200 | [diff] [blame] | 74 | self.current_parent = oldparent
|
eli.bendersky | 724b1cc | 2011-03-05 10:45:08 +0200 | [diff] [blame] | 75 |
|
Eli Bendersky | 3921e8e | 2010-05-21 09:05:39 +0300 | [diff] [blame] | 76 |
|
eli.bendersky | 0e0a71f | 2010-10-09 08:32:00 +0200 | [diff] [blame] | 77 | if __name__ == "__main__":
|
| 78 | source_code = """
|
eli.bendersky | 1bd6c17 | 2011-07-16 06:43:20 +0300 | [diff] [blame] | 79 | typedef long int POINT;
|
eli.bendersky | 6b01179 | 2011-06-22 17:50:56 +0300 | [diff] [blame] | 80 | typedef int HWND;
|
| 81 | typedef int UINT;
|
| 82 | typedef int ULONG_PTR;
|
| 83 | typedef int DWORD;
|
eli.bendersky | 51da62f | 2011-07-09 07:30:55 +0300 | [diff] [blame] | 84 | struct _MIDL_STUB_MESSAGE MIDL_STUB_MESSAGE,*PMIDL_STUB_MESSAGE;
|
eli.bendersky | 6b01179 | 2011-06-22 17:50:56 +0300 | [diff] [blame] | 85 | typedef struct tagMOUSEHOOKSTRUCT {
|
| 86 | POINT pt;
|
| 87 | HWND hwnd;
|
| 88 | UINT wHitTestCode;
|
| 89 | ULONG_PTR dwExtraInfo;
|
| 90 | } MOUSEHOOKSTRUCT, *LPMOUSEHOOKSTRUCT, *PMOUSEHOOKSTRUCT;
|
| 91 |
|
| 92 | typedef struct tagMOUSEHOOKSTRUCTEX
|
| 93 | {
|
| 94 | MOUSEHOOKSTRUCT;
|
| 95 | DWORD mouseData;
|
eli.bendersky | b537f8a | 2011-06-22 19:16:01 +0300 | [diff] [blame] | 96 | } MOUSEHOOKSTRUCTEX, *LPMOUSEHOOKSTRUCTEX, *PMOUSEHOOKSTRUCTEX;
|
| 97 | """
|
eli.bendersky | 38165b7 | 2011-02-04 08:13:39 +0200 | [diff] [blame] | 98 |
|
| 99 | #--------------- Lexing
|
eli.bendersky | 38165b7 | 2011-02-04 08:13:39 +0200 | [diff] [blame] | 100 | #~ def errfoo(msg, a, b): |
| 101 | #~ printme(msg)
|
| 102 | #~ sys.exit()
|
| 103 | #~ clex = CLexer(errfoo, lambda t: False)
|
| 104 | #~ clex.build()
|
| 105 | #~ clex.input(source_code)
|
| 106 |
|
| 107 | #~ while 1:
|
| 108 | #~ tok = clex.token()
|
| 109 | #~ if not tok: break
|
| 110 |
|
| 111 | #~ printme([tok.value, tok.type, tok.lineno, clex.filename, tok.lexpos])
|
| 112 |
|
| 113 | #--------------- Parsing
|
eli.bendersky | 0e0a71f | 2010-10-09 08:32:00 +0200 | [diff] [blame] | 114 | parser = CParser()
|
eli.bendersky | 724b1cc | 2011-03-05 10:45:08 +0200 | [diff] [blame] | 115 | ast = parser.parse(source_code, filename='zz')
|
eli.bendersky | 8e6c586 | 2011-05-20 12:35:08 +0300 | [diff] [blame] | 116 | ast.show(showcoord=False)
|
eli.bendersky | 6b01179 | 2011-06-22 17:50:56 +0300 | [diff] [blame] | 117 | #~ nv=NodeVisitor()
|
| 118 | #~ nv.visit(ast)
|
eli.bendersky | 724b1cc | 2011-03-05 10:45:08 +0200 | [diff] [blame] | 119 |
|
Eli Bendersky | 3921e8e | 2010-05-21 09:05:39 +0300 | [diff] [blame] | 120 |
|