directives may also have register parameters

This commit is contained in:
Julian Hammer
2019-10-11 13:09:12 +02:00
parent b16204111f
commit 0627309a7e
2 changed files with 30 additions and 29 deletions

View File

@@ -184,7 +184,7 @@ def inspect(args):
# Read file
code = args.file.read()
# Parse file
parser = _create_parser(arch)
parser = get_asm_parser(arch)
parsed_code = parser.parse_file(code)
# Reduce to marked kernel and add semantics
@@ -219,7 +219,7 @@ def run(args, output_file=sys.stdout):
# ---------------------------------------------------
def _create_parser(arch) -> BaseParser:
def get_asm_parser(arch) -> BaseParser:
isa = MachineModel.get_isa_for_arch(arch)
if isa == 'x86':
return ParserX86ATT()

View File

@@ -10,6 +10,10 @@ class ParserX86ATT(BaseParser):
super().__init__()
def construct_parser(self):
decimal_number = pp.Combine(
pp.Optional(pp.Literal('-')) + pp.Word(pp.nums)
).setResultsName('value')
hex_number = pp.Combine(pp.Literal('0x') + pp.Word(pp.hexnums)).setResultsName('value')
# Comment
symbol_comment = '#'
self.comment = pp.Literal(symbol_comment) + pp.Group(
@@ -27,31 +31,6 @@ class ParserX86ATT(BaseParser):
self.label = pp.Group(
identifier.setResultsName('name') + pp.Literal(':') + pp.Optional(self.comment)
).setResultsName(self.LABEL_ID)
# Directive
decimal_number = pp.Combine(
pp.Optional(pp.Literal('-')) + pp.Word(pp.nums)
).setResultsName('value')
hex_number = pp.Combine(pp.Literal('0x') + pp.Word(pp.hexnums)).setResultsName('value')
directive_option = pp.Combine(
pp.Word('#@.', exact=1) + pp.Word(pp.printables, excludeChars=',')
)
directive_parameter = (
pp.quotedString | directive_option | identifier | hex_number | decimal_number
)
commaSeparatedList = pp.delimitedList(pp.Optional(directive_parameter), delim=',')
self.directive = pp.Group(
pp.Literal('.')
+ pp.Word(pp.alphanums + '_').setResultsName('name')
+ commaSeparatedList.setResultsName('parameters')
+ pp.Optional(self.comment)
).setResultsName(self.DIRECTIVE_ID)
##############################
# Instructions
# Mnemonic
mnemonic = pp.ZeroOrMore(pp.Literal('data16') | pp.Literal('data32')) + pp.Word(
pp.alphanums
).setResultsName('mnemonic')
# Register: pp.Regex('^%[0-9a-zA-Z]+,?')
register = pp.Group(
pp.Literal('%')
@@ -83,6 +62,27 @@ class ParserX86ATT(BaseParser):
+ pp.Optional(scale.setResultsName('scale'))
+ pp.Literal(')')
).setResultsName(self.MEMORY_ID)
# Directive
directive_option = pp.Combine(
pp.Word('#@.', exact=1) + pp.Word(pp.printables, excludeChars=',')
)
directive_parameter = (
pp.quotedString | directive_option | identifier | hex_number | decimal_number | register
)
commaSeparatedList = pp.delimitedList(pp.Optional(directive_parameter), delim=',')
self.directive = pp.Group(
pp.Literal('.')
+ pp.Word(pp.alphanums + '_').setResultsName('name')
+ commaSeparatedList.setResultsName('parameters')
+ pp.Optional(self.comment)
).setResultsName(self.DIRECTIVE_ID)
# Instructions
# Mnemonic
mnemonic = pp.ZeroOrMore(pp.Literal('data16') | pp.Literal('data32')) + pp.Word(
pp.alphanums
).setResultsName('mnemonic')
# Combine to instruction form
operand_first = pp.Group(register ^ immediate ^ memory ^ identifier)
operand_rest = pp.Group(register ^ immediate ^ memory)
@@ -182,8 +182,9 @@ class ParserX86ATT(BaseParser):
if result is None:
try:
result = self.parse_instruction(line)
except pp.ParseException:
raise ValueError('Could not parse line {}: {!r}'.format(line_number, line))
except pp.ParseException as e:
raise ValueError('Could not parse instruction on line {}: {!r}'.format(
line_number, line))
instruction_form[self.INSTRUCTION_ID] = result[self.INSTRUCTION_ID]
instruction_form[self.OPERANDS_ID] = result[self.OPERANDS_ID]
instruction_form[self.COMMENT_ID] = result[self.COMMENT_ID]