Created
March 21, 2016 04:40
-
-
Save bcho/95574231004362f17b1e to your computer and use it in GitHub Desktop.
trick
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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