Package pygccxml :: Package declarations :: Module pattern_parser

Source Code for Module pygccxml.declarations.pattern_parser

  1  # Copyright 2004-2008 Roman Yakovenko. 
  2  # Distributed under the Boost Software License, Version 1.0. (See 
  3  # accompanying file LICENSE_1_0.txt or copy at 
  4  # http://www.boost.org/LICENSE_1_0.txt) 
  5   
  6  """implementation details""" 
  7   
  8  import types 
  9   
10 -class parser_t( object ):
11 """implementation details"""
12 - def __init__( self 13 , pattern_char_begin 14 , pattern_char_end 15 , pattern_char_separator ):
16 self.__begin = pattern_char_begin 17 self.__end = pattern_char_end 18 self.__separator = pattern_char_separator 19 #right now parser does not take into account next qualifiers, but it will 20 self.__text_qualifier = '"' 21 self.__char_qualifier = "'" 22 self.__escape = '\\'
23
24 - def has_pattern( self, decl_string ):
25 """implementation details""" 26 last_part = decl_string.split( '::' )[-1] 27 return -1 != decl_string.find( self.__begin ) and -1 != last_part.find( self.__end )
28
29 - def name( self, decl_string ):
30 """implementation details""" 31 assert isinstance( decl_string, types.StringTypes ) 32 if not self.has_pattern( decl_string ): 33 return decl_string 34 args_begin = decl_string.find( self.__begin ) 35 return decl_string[0: args_begin].strip()
36
37 - def __find_args_separator( self, decl_string, start_pos ):
38 """implementation details""" 39 bracket_depth = 0 40 for index, ch in enumerate( decl_string[start_pos:] ): 41 if ch not in ( self.__begin, self.__end, self.__separator ): 42 continue #I am interested only in < and > 43 elif self.__separator == ch: 44 if not bracket_depth: 45 return index + start_pos 46 elif self.__begin == ch: 47 bracket_depth += 1 48 elif not bracket_depth: 49 return index + start_pos 50 else: 51 bracket_depth -= 1 52 return -1
53
54 - def args( self, decl_string ):
55 """implementation details""" 56 args_begin = decl_string.find( self.__begin ) 57 args_end = decl_string.rfind( self.__end ) 58 if -1 in ( args_begin, args_end ) or args_begin == args_end: 59 raise RuntimeError( "%s doesn't valid template instantiation string" % decl_string ) 60 61 args_only = decl_string[args_begin + 1: args_end ] 62 args = [] 63 previous_found, found = 0, 0 64 while True: 65 found = self.__find_args_separator( args_only, previous_found) 66 if -1 == found: 67 args.append( args_only[ previous_found : ] ) 68 break 69 #elif decl_string[ found ] == self.__end: 70 # print args 71 # raise RuntimeError( "unmatched '%s' token has been found." % self.__end ) 72 else: 73 args.append( args_only[ previous_found : found ] ) 74 previous_found = found + 1 #skip found sep 75 return [ arg.strip() for arg in args ]
76 77 NOT_FOUND = ( -1, -1 ) 78 """implementation details""" 79
80 - def find_args(self, text, start=None ):
81 """implementation details""" 82 if start==None: 83 start = 0 84 first_occurance = text.find( self.__begin, start ) 85 if first_occurance == -1: 86 return self.NOT_FOUND 87 previous_found, found = first_occurance + 1, 0 88 while True: 89 found = self.__find_args_separator( text, previous_found) 90 if -1 == found: 91 return self.NOT_FOUND 92 elif text[ found ] == self.__end: 93 return ( first_occurance, found ) 94 else: 95 previous_found = found + 1 #skip found sep
96
97 - def split( self, decl_string ):
98 """implementation details""" 99 assert self.has_pattern( decl_string ) 100 return self.name( decl_string ), self.args( decl_string )
101
102 - def split_recursive( self, decl_string ):
103 """implementation details""" 104 assert self.has_pattern( decl_string ) 105 answer = [] 106 to_go = [ decl_string ] 107 while to_go: 108 name, args = self.split( to_go.pop() ) 109 answer.append( ( name, args ) ) 110 for arg in args: 111 if self.has_pattern( arg ): 112 to_go.append( arg ) 113 return answer
114
115 - def join( self, name, args, arg_separator=None ):
116 """implementation details""" 117 if None is arg_separator: 118 arg_separator = ', ' 119 args = filter( None, args) 120 args_str = '' 121 if not args: 122 args_str = ' ' 123 elif 1 == len( args ): 124 args_str = ' ' + args[0] + ' ' 125 else: 126 args_str = ' ' + arg_separator.join( args ) + ' ' 127 128 return ''.join( [ name, self.__begin, args_str, self.__end ] )
129
130 - def normalize( self, decl_string, arg_separator=None ):
131 """implementation details""" 132 if not self.has_pattern( decl_string ): 133 return decl_string 134 name, args = self.split( decl_string ) 135 for i, arg in enumerate( args ): 136 args[i] = self.normalize( arg ) 137 return self.join( name, args, arg_separator )
138