简体   繁体   中英

How to parse custom file format to json in Python or to Python dictionary?

I have custom file format that I use for my program in Python. It stores logic gates in human readable form.

[output-0(
    or-0(
        and-0(
            not-0(
                input-0()),
            not-1(
                input-1())),
        and-2(
            input-0(),
            not-1(
                input-1())))),
output-1(
    or-1(
        and-1(
            not-0(
                input-0()),
            input-1()),
        and-2(
            input-0(),
            not-1(
                input-1()))))]

And I want to parse it to json, that looks like this:

[
    {
        "type": "output",
        "id": 0,
        "i": [
            {
                "type": "or",
                "id": 0,
                "i": [
                    {
                        "type": "and",
                        "id": 0,
                        "i": [
                            {
                                "type": "not",
                                "id": 0,
                                "i": [
                                    {
                                        "type": "input",
                                        "id": 0,
                                        "i": []
                                    }
                                ]
                            },
                            {
                                "type": "not",
                                "id": 1,
                                "i": [
                                    {
                                        "type": "input",
                                        "id": 1,
                                        "i": []
                                    }
                                ]
                            }
                        ]
                    },
                    {
                        "type": "and",
                        "id": 2,
                        "i": [
                            {
                                "type": "input",
                                "id": 0,
                                "i": []
                            },
                            {
                                "type": "not",
                                "id": 1,
                                "i": [
                                    {
                                        "type": "input",
                                        "id": 1,
                                        "i": []
                                    }
                                ]
                            }
                        ]
                    }
                ]
            }
        ]
    },
    {
        "type": "output",
        "id": 1,
        "i": [
            {
                "type": "or",
                "id": 1,
                "i": [
                    {
                        "type": "and",
                        "id": 1,
                        "i": [
                            {
                                "type": "not",
                                "id": 0,
                                "i": [
                                    {
                                        "type": "input",
                                        "id": 0,
                                        "i": []
                                    }
                                ]
                            },
                            {
                                "type": "input",
                                "id": 1,
                                "i": []
                            }
                        ]
                    },
                    {
                        "type": "and",
                        "id": 2,
                        "i": [
                            {
                                "type": "input",
                                "id": 0,
                                "i": []
                            },
                            {
                                "type": "not",
                                "id": 1,
                                "i": [
                                    {
                                        "type": "input",
                                        "id": 1,
                                        "i": []
                                    }
                                ]
                            }
                        ]
                    }
                ]
            }
        ]
    }
]

Or if it is possible to convert it to python dictionary directly without json. All gate types are: and, or, not, buffer, nand, nor, xor, output, input. Thanks for your help.

Define the grammar:

type := word
id   := number
func := type-id
call := func(args)
args := none | call {, call}*
root := [args]

Let's make ourselves a parser using pyparsing :

import json
import pyparsing as pp

def make_parser():
    LPAR, RPAR = map(pp.Suppress, "()")
    LBRA, RBRA = map(pp.Suppress, "[]")
    type_ = pp.Word(pp.alphas)
    id_ = pp.Word(pp.nums)
    func = type_ + "-" + id_
    call = pp.Forward()
    args = pp.Optional(call + pp.ZeroOrMore("," + call))
    call <<= func + pp.Group(LPAR + args + RPAR)
    many = args
    root = pp.Group(LBRA + many + RBRA)

    id_.setParseAction(parse_id)
    args.setParseAction(parse_args)
    call.setParseAction(parse_call)
    root.setParseAction(parse_root)

    return root

Define the actions that will convert the tokens to JSON format:

def parse_id(s, locs, tokens):
    opand, = tokens
    return int(opand)

def parse_call(s, locs, tokens):
    type_, _dash, id_, args = tokens
    return {"type": type_, "id": id_, "i": list(args)}

def parse_args(s, locs, tokens):
    return tokens[::2]

def parse_root(s, locs, tokens):
    root, = tokens
    return root

To run:

test = "[output-0()]"
parser = make_parser()
result = parser.parseString(test)[:]
print(json.dumps(result, indent=4))

Complete example:

import json
import pyparsing as pp

def parse_id(s, locs, tokens):
    opand, = tokens
    return int(opand)

def parse_call(s, locs, tokens):
    type_, _dash, id_, args = tokens
    return {"type": type_, "id": id_, "i": list(args)}

def parse_args(s, locs, tokens):
    return tokens[::2]

def parse_root(s, locs, tokens):
    root, = tokens
    return root

def make_parser():
    LPAR, RPAR = map(pp.Suppress, "()")
    LBRA, RBRA = map(pp.Suppress, "[]")
    type_ = pp.Word(pp.alphas)
    id_ = pp.Word(pp.nums)
    func = type_ + "-" + id_
    call = pp.Forward()
    args = pp.Optional(call + pp.ZeroOrMore("," + call))
    call <<= func + pp.Group(LPAR + args + RPAR)
    many = args
    root = pp.Group(LBRA + many + RBRA)

    id_.setParseAction(parse_id)
    args.setParseAction(parse_args)
    call.setParseAction(parse_call)
    root.setParseAction(parse_root)

    return root

def main():
    test = """[
        output-0(
            or-0(
                and-0(
                    not-0(
                        input-0()),
                    not-1(
                        input-1())),
                and-2(
                    input-0(),
                    not-1(
                        input-1())))),
        output-1(
            or-1(
                and-1(
                    not-0(
                        input-0()),
                    input-1()),
                and-2(
                    input-0(),
                    not-1(
                        input-1()))))
    ]"""

    parser = make_parser()
    result = parser.parseString(test)[:]
    print(json.dumps(result, indent=4))

main()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM