Commits

Matt Williams committed 1da8f53

About a 1.6x speed-up for small files and about a 1.2x speed-up for large files.

Comments (0)

Files changed (1)

doxylink/sphinxcontrib/doxylink/parsing.py

 from string import capitalize
 
 #Qualifier to go in front of type in the argument list (unsigned const int foo)
-qualifier = OneOrMore(Literal('const') ^ Literal('unsigned') ^ Literal('typename'))
+qualifier = OneOrMore(Literal('const') | Literal('unsigned') | Literal('typename'))
 
 def turn_parseresults_to_list(s, loc, toks):
 	return ParseResults(normalise_templates(s, loc, toks[0].asList()))
 number = Word('-.' + nums)
 
 #The name of the argument. We will ignore this but it must be matched anyway.
-input_name = OneOrMore(Word(alphanums + '_') ^ angle_bracket_pair ^ parentheses_pair ^ square_bracket_pair)
+input_name = OneOrMore(Word(alphanums + '_') | angle_bracket_pair | parentheses_pair | square_bracket_pair)
 
 #Grab the '&', '*' or '**' type bit in (const QString & foo, int ** bar)
 pointer_or_reference = oneOf('* &')
 
 #The '=QString()' or '=false' bit in (int foo = 4, bool bar = false)
-default_value = Literal('=') + OneOrMore(angle_bracket_pair ^ parentheses_pair ^ square_bracket_pair ^ input_type ^ number ^ Word('|&^') ^ quotedString)
+default_value = Literal('=') + OneOrMore(number | quotedString | input_type | parentheses_pair | angle_bracket_pair | square_bracket_pair | Word('|&^'))
 
 #A combination building up the interesting bit -- the argument type, e.g. 'const QString &', 'int' or 'char*'
 argument_type = Optional(qualifier, default='').setResultsName("qualifier") + \
 argument = Group(argument_type.setResultsName('argument_type') + Optional(input_name) + Optional(default_value))
 
 #List of arguments in parentheses with an optional 'const' on the end
-arglist = Literal('(') + Optional(delimitedList(argument).setResultsName('arg_list')) + Optional(Literal(',') + Literal('...')).setResultsName('var_args') + Literal(')') + Optional(Literal('const'), default='').setResultsName('const_function')
+arglist = Literal('(') + delimitedList(argument).setResultsName('arg_list') + Optional(Literal(',') + Literal('...')).setResultsName('var_args') + Literal(')')
 
 def normalise(symbol):
 	"""
 	
 	try:
 		bracket_location = symbol.index('(')
-		#Split the input string into everything before the openning bracket and everything else
+		#Split the input string into everything before the opening bracket and everything else
 		function_name = symbol[:bracket_location]
 		arglist_input_string = symbol[bracket_location:]
 	except ValueError:
 		#If there's no brackets, then there's no function signature. This means the passed in symbol is just a type name
 		return symbol, ''
 	
+	#This is a very common signature so we'll make a special case for it. It requires no parsing anyway
+	if arglist_input_string.startswith('()'):
+		if arglist_input_string == '()' or arglist_input_string == '()=0':
+			return function_name, arglist_input_string
+		elif arglist_input_string == '() const ' or arglist_input_string == '() const' or arglist_input_string == '() const =0':
+			return function_name, '() const'
+	
+	#By now we're left with something like "(blah, blah)", "(blah, blah) const" or "(blah, blah) const =0"
+	try:
+		closing_bracket_location = arglist_input_string.rindex(')')
+		arglist_suffix = arglist_input_string[closing_bracket_location+1:]
+		arglist_input_string = arglist_input_string[:closing_bracket_location+1]
+	except ValueError:
+		#This shouldn't happen.
+		print 'Could not find closing bracket'
+		raise
+	
 	try:
 		result = arglist.parseString(arglist_input_string)
-	except ParseException, pe:
+	except ParseException as pe:
 		print symbol
 		print pe
 		raise
 		normalised_arg_list_string = ''.join(['(', ', '.join(normalised_arg_list), ')'])
 		
 		#Add a const onto the end
-		if result.const_function:
-			normalised_arg_list_string += ' ' + result.const_function
+		if 'const' in arglist_suffix:
+			normalised_arg_list_string += ' const'
 		
 		return function_name, normalised_arg_list_string