1 #!/usr/bin/env python 2 """ cdecl.py - parse c declarations 3 4 (c) 2002, 2003, 2004, 2005 Simon Burton <simon (at] arrowtheory.com> 5 Released under GNU LGPL license. 6 7 version 0.xx 8 9 """ 10 11 import sys 12 13 14 class Symbols(object): 15 def __init__(self,parent=None,verbose=False): 16 self.verbose = verbose 17 self.parent=parent # are we a nested namespace? 18 self.lookup = {} # identifiers 19 self.tags = {} # struct, union, enum tags 20 21 def __str__(self): 22 return "Symbols(%s,%s)"%(self.lookup,self.tags) 23 24 def __getitem__(self,key): 25 try: 26 item = self.lookup[key] 27 except KeyError: 28 item = None 29 #if self.parent is not None: 30 #item = self.parent[item] 31 ## self[key] = item # cache 32 #if self.verbose: print "%s.get('%s')='%s'"%(self,key,item) 33 return item 34 35 def __setitem__(self,key,val): 36 #if self.verbose: print "%s.set('%s','%s')"%(self,key,val) 37 assert val is not None 38 self.lookup[key] = val 39 40 def set_tag(self,key,val): 41 #if self.verbose: print "%s.set_tag(%s,%s)"%(self,key,val) 42 assert len(key) 43 self.tags[key] = val 44 45 def deep_get_tag(self,key): 46 try: 47 item = self.tags[key] 48 except KeyError: 49 item = None 50 if self.parent is not None: 51 item = self.parent.deep_get_tag(key) 52 #if self.verbose: print "%s.get_tag(%s)=%s"%(self,key,item) 53 return item 54 55 def get_tag(self,key): 56 try: 57 item = self.tags[key] 58 except KeyError: 59 item = None 60 #if self.verbose: print "%s.get_tag(%s)=%s"%(self,key,item) 61 return item 62 63 ################################################################### 64 # 65 ################################################################### 66 # 67 68 69 class ParseError(Exception): 70 def __init__(self,*e): 71 self.e = e 72 73 def __str__(self): 74 return "".join(map(str,self.e)) 75 76 77 class Parser(object): 78 def parse_error(self,lexer,reason="?",*blah): 79 sys.stderr.write( "%s.parse_error()\n"%self.deepstr() ) 80 sys.stderr.write( "at line %s: %s\n"%(lexer.lno+1,reason) ) 81 sys.stderr.write( lexer.err_string() ) 82 raise ParseError(reason,*blah) 83 84 def expected_error(self,lexer,*l): 85 self.parse_error( lexer, "expected %s, got '%s'"\ 86 %(" or ".join(map(repr,l)),lexer.tok)) 87 88 def consume(self,lexer,tok): 89 if lexer.tok != tok: 90 self.expected_error(lexer, tok) 91 lexer.get_token() 92 93 def parse_enter(self,lexer): 94 #return 95 self.start_lno=lexer.lno 96 self.file=lexer.so_file 97 98 def parse_leave(self,lexer): 99 #return 100 self.lines = lexer.lines[self.start_lno:max(lexer.lno,self.start_lno+1)] 101 102 ################################################################### 103 # 104 ################################################################### 105 # 106 107