aboutsummaryrefslogtreecommitdiffstats
path: root/format_ldr.py
blob: 7b4bb1f9146acba142b9de810da320db15ce9c62 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
from lark import Lark, Transformer, Token, Tree
from script_format import ScriptFormat

class LdrXfrm(Transformer):
    """ transform the parse tree into a more easily consumable form """
    def rst(self, items):
        return ('reset')
    def NONL(self, items):
        return ''.join([i for i in items.value])
    def rem(self, items):
        return ('rem', items[0])
    def swmatch(self, items):
        return ('swmatch', items)
    def cmd(self, items):
        return ('cmd', {'req': items[0], 'rsp': items[1]})

    def todigit(self, item):
        """ convert from Token/Tree to raw hex-digit """
        if isinstance(item, Token):
            return item.value
        elif isinstance(item, Tree):
            return item.data
    def hex_item(self, items):
        """ return one byte as two-digit HEX string """
        return "%s%s" % (items[0].value, items[1].value)
    def hexstr(self, items):
        """ return list of two-digit HEX strings """
        return ('hexstr', ''.join(list(items)))
    def swpattern(self, items):
        """ return list of four HEX nibbles (or 'x' as wildcard) """
        arr = [self.todigit(x) for x in items]
        return ''.join(arr)

class ScriptFormatLDR(ScriptFormat):
    # parser for the LDR file format as generated by Simulity Profile Editor
    ldr_parser = Lark(r"""
        script: statement*
        ?statement: cmd | rst | rem | NEWLINE

        BSLASH: "\\\n"
        %ignore BSLASH

        NONL: /[^\n]/+
        rem: "REM" NONL? NEWLINE

        ALNUM: DIGIT | LETTER | "_"
        key: "[" ALNUM+ "]"

        cmd: "CMD" hexstr [swmatch] NEWLINE
        cmd_item: hexstr | key
        hexstr: hex_item+
        hex_item: HEXDIGIT HEXDIGIT

        swmatch: "(" swpattern ("," swpattern)* ")"
        swpattern: hex_or_x hex_or_x hex_or_x hex_or_x
        ?hex_or_x: HEXDIGIT | "X" -> x | "x" -> x

        rst: "RST" NEWLINE

        %import common.ESCAPED_STRING -> STRING
        %import common.WS_INLINE
        %import common.HEXDIGIT
        %import common.DIGIT
        %import common.LETTER
        %import common.NEWLINE
        %ignore WS_INLINE

        """, start='script')

    def parse_xform(self, text):
        tree = self.ldr_parser.parse(text)
        #print(tree.pretty())
        p = LdrXfrm().transform(tree)
        return p