102 lines
3.3 KiB
Python
102 lines
3.3 KiB
Python
import logging
|
|
|
|
from ScEpTIC import tools
|
|
from ScEpTIC.exceptions import ParsingException
|
|
|
|
|
|
def parse_attributes_groups_section(text, log_section_content = False):
|
|
"""
|
|
Parse and return the attributes groups section, using parse_attributes_group.
|
|
attributes #0 = { alwaysinline alignstack=4 ...}
|
|
"""
|
|
|
|
logging.debug('Calling parse_attributes_groups_section({}, {})'.format(text, log_section_content))
|
|
|
|
attributes_groups = {}
|
|
|
|
for line in text:
|
|
attributes_group = parse_attributes_group(line)
|
|
attributes_groups[attributes_group['name']] = attributes_group
|
|
|
|
if logging.getLogger().isEnabledFor(logging.INFO):
|
|
log_str = 'Parsed attributes groups section. {} attributes groups found'.format(len(attributes_groups))
|
|
|
|
if log_section_content:
|
|
log_str += ':\n{}'.format(tools.fancy_dict_to_str(attributes_groups))
|
|
else:
|
|
log_str += '.\n{}'.format(tools.fancy_dict_keys_to_str(attributes_groups))
|
|
|
|
logging.info(log_str)
|
|
|
|
return attributes_groups
|
|
|
|
|
|
def parse_attributes_group(text):
|
|
"""
|
|
Parses a line containing a list of attributes and returns the id of the attributes group and the attributes themselves.
|
|
Valued attributes will be represented as a list ['attribute_name', 'attribute_value']
|
|
"""
|
|
|
|
logging.debug('Calling parse_attributes({})'.format(text))
|
|
|
|
# an attributes definition must be with attributes #int = { ... }
|
|
if not is_attributes_group(text):
|
|
raise ParsingException('LLVM IR Syntax error. attributes #id = {...} expected.'+' {}...{} given'.format(tools.list_join(text[0:5], ' '), text[-1]))
|
|
|
|
# name is on position 2
|
|
name = '#'+text[2]
|
|
|
|
# remove attribute #name = { ... } and keep only inside part
|
|
text = text[5:-1]
|
|
attributes = []
|
|
|
|
i = 0
|
|
|
|
while i < len(text):
|
|
val = text[i]
|
|
|
|
# if is a string
|
|
if val == '"':
|
|
# get position of closing "
|
|
closing = text.index('"', i+1)
|
|
|
|
# retrieve value inside " ... "
|
|
val = tools.list_join(text[i+1:closing])
|
|
|
|
# update index to be parsed
|
|
i = closing + 1
|
|
|
|
# if is a key=value
|
|
if text[i] == '=':
|
|
i += 1
|
|
# "key" = "value"
|
|
if text[i] == '"':
|
|
closing = text.index('"', i+1)
|
|
val = {val: tools.list_join(text[i+1:closing])}
|
|
i = closing + 1
|
|
else:
|
|
val = {val: text[i]}
|
|
i += 1
|
|
else:
|
|
i += 1
|
|
|
|
attributes.append(val)
|
|
|
|
attributes = {'name': name, 'attributes': attributes}
|
|
|
|
if logging.getLogger().isEnabledFor(logging.DEBUG):
|
|
log_vals = " {}".format(attributes)
|
|
logging.debug('Parsed attribute {}:\n{}'.format(name, tools.instert_new_line_every(log_vals, new_line_padding = ' ')))
|
|
|
|
return attributes
|
|
|
|
|
|
def is_attributes_group(text):
|
|
"""
|
|
Return if the line represents an attributes group.
|
|
"""
|
|
|
|
logging.debug('Calling is_attributes_group({})'.format(text))
|
|
|
|
return isinstance(text, list) and len(text) > 5 and text[0] == 'attributes' and text[1] == '#' and text[3] == '=' and text[4] == '{' and text[-1] == '}'
|