Skip to content

Instantly share code, notes, and snippets.

@arbel03
Last active May 16, 2021 12:49
Show Gist options
  • Save arbel03/89ec4e95116ff11eea26a0f3450730ac to your computer and use it in GitHub Desktop.
Save arbel03/89ec4e95116ff11eea26a0f3450730ac to your computer and use it in GitHub Desktop.
Parse demangled names
import re
from collections import namedtuple
Class = namedtuple('Class', ['namespace', 'name', 'template_arguments'])
def parse_recursive(string):
template_start = string.find('<')
template_end = string.rfind('>')
class_part = string[:template_start] if template_start != -1 else string
*namespace, class_name = class_part.split('::')
namespace = '::'.join(namespace).strip()
template_arguments = None
if template_start != -1 and template_end != -1:
template_arguments = parse_template_recursive(string[template_start + 1:template_end])
return Class(namespace, class_name, template_arguments)
def partition(alist, indices):
for i, j in zip([-1]+indices, indices+[None]):
yield alist[i+1:j]
def parse_template_recursive(arguments_string):
count = 0
indexes = []
for index, ch in enumerate(arguments_string):
if ch == '<': count += 1
elif ch == '>': count -= 1
elif ch == ',' and count == 0: indexes.append(index)
arguments = partition(arguments_string, indexes)
arguments = map(str.strip, arguments)
arguments = map(parse_recursive, arguments)
return list(arguments)
test_string = "std::basic_string<char, std::char_traits<char>, std::allocator<char>>"
test_string2 = "SomeTemplate<1, SomeField<char, char>>"
assert parse_recursive(test_string).name == "basic_string"
assert parse_recursive(test_string).namespace == "std"
assert parse_recursive(test_string).template_arguments[0].name == "char"
assert parse_recursive(test_string).template_arguments[1].name == "char_traits"
assert parse_recursive(test_string).template_arguments[1].namespace == "std"
assert parse_recursive(test_string2).template_arguments[1].template_arguments[0].name == "char"
assert parse_recursive(test_string2).template_arguments[1].template_arguments[1].name == "char"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment