Skip to content

Instantly share code, notes, and snippets.

@bcho
Created March 21, 2016 04:40
Show Gist options
  • Save bcho/95574231004362f17b1e to your computer and use it in GitHub Desktop.
Save bcho/95574231004362f17b1e to your computer and use it in GitHub Desktop.
trick
# coding: utf-8
import re
LEVEL_PATTERN = re.compile(r'''
([\|\-` ]*) # match level
(.*) # match remains
''', re.X)
LOCATION_PATTERN = re.compile(r'''
.*
<
([\w\.\/]+) # `line` or `yyy/xxx.h`
:
(\d+:\d+) # 47:1
,
\s
col
:
(\d+) # 15
>
.*
''', re.X)
class Location(object):
"""Represents node location."""
def __init__(self, filename, line, col):
self.filename = filename
self.line = line
self.col = col
def __repr__(self):
return self.__str__()
def __str__(self):
return '<{r.filename}:{r.line}, col:{r.col}>'.format(r=self)
@classmethod
def parse_from_line(cls, line):
matched = LOCATION_PATTERN.match(line)
if not matched:
return
return cls(*matched.groups())
class Node(object):
"""Represents an AST node."""
def __init__(self, level, node_type, address, location, raw):
self.level = level
self.node_type = node_type
self.address = address
self.location = location
self.raw = raw
self.children = []
def add_child_node(self, child):
self.children.append(child)
def __repr__(self):
return self.__str__()
def __str__(self):
return '<Node: {0} {1}>'.format(
self.node_type,
self.location if self.location else '<invalid sloc>'
)
@classmethod
def parse_from_line(cls, line):
level_parsed = LEVEL_PATTERN.match(line.strip())
if not level_parsed:
return
level, remains = level_parsed.groups()
node_level = len(level.replace(' ', ''))
tokens = remains.split(' ')
if len(tokens) < 2:
# TODO log this case
return
node_type, address = tokens[0], tokens[1]
location = Location.parse_from_line(remains)
return cls(node_level, node_type, address, location, line)
@classmethod
def parse_from_lines(cls, lines):
root, parent = None, None
for line in lines:
node = Node.parse_from_line(line)
if not node:
continue
if not root:
root = node
if not parent:
parent = node
if node.level > parent.level:
parent.add_child_node(node)
else:
parent = node
return root
def build():
with open('crypt2.ast') as f:
return Node.parse_from_lines(f.readlines())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment