blob: 19d30e06c9a13871a3bd5100af48003c0cce1506 [file] [log] [blame]
#!/usr/bin/env python
from __future__ import print_function
from parcon import *
from collections import namedtuple
hexchars = '0123456789abcdefABCDEF'
Reg = namedtuple("Reg", ["num"])
Imm = namedtuple("Imm", ["value"])
MemRef = namedtuple("MemRef", ["reg", "offset"])
def keywords(vs):
return First(*[Keyword(SignificantLiteral(v)) for v in vs])
hexnum = SignificantLiteral('0x') + +CharIn(hexchars)
decnum = +Digit()
offset = (CharIn("+-") + Exact(hexnum | decnum))[flatten]["".join][lambda x: int(x, 0)]
imm = (-CharIn("+-") + Exact(hexnum | decnum))[flatten]["".join][lambda x: int(x, 0)][Imm]
reg = Literal('%') + Literal('r') + integer[int][Reg]
memref = (Literal('[') + reg + Optional(offset, 0) + Literal(']'))[lambda x: MemRef(*x)]
unary_alu_ops = ['neg', 'neg32', 'le16', 'le32', 'le64', 'be16', 'be32', 'be64']
binary_alu_ops = ['add', 'sub', 'mul', 'div', 'or', 'and', 'lsh', 'rsh',
'mod', 'xor', 'mov', 'arsh']
binary_alu_ops.extend([x + '32' for x in binary_alu_ops])
alu_instruction = \
(keywords(unary_alu_ops) + reg) | \
(keywords(binary_alu_ops) + reg + "," + (reg | imm))
mem_sizes = ['w', 'h', 'b', 'dw']
mem_store_reg_ops = ['stx' + s for s in mem_sizes]
mem_store_imm_ops = ['st' + s for s in mem_sizes]
mem_load_ops = ['ldx' + s for s in mem_sizes]
mem_instruction = \
(keywords(mem_store_reg_ops) + memref + "," + reg) | \
(keywords(mem_store_imm_ops) + memref + "," + imm) | \
(keywords(mem_load_ops) + reg + "," + memref) | \
(keywords(["lddw"]) + reg + "," + imm)
jmp_cmp_ops = ['jeq', 'jgt', 'jge', 'jlt', 'jle', 'jset', 'jne', 'jsgt', 'jsge', 'jslt', 'jsle']
jmp_instruction = \
(keywords(jmp_cmp_ops) + reg + "," + (reg | imm) + "," + offset) | \
(keywords(['ja']) + offset) | \
(keywords(['call']) + imm) | \
(keywords(['exit'])[lambda x: (x, )])
instruction = alu_instruction | mem_instruction | jmp_instruction
start = ZeroOrMore(instruction + Optional(Literal(';'))) + End()
def parse(source):
return start.parse_string(source)
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="Assembly parser", formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('file', type=argparse.FileType('r'), default='-')
args = parser.parse_args()
result = parse(args.file.read())
for inst in result:
print(repr(inst))