1

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.

1
  • Define a grammar, then plug that into PyParsing or Lark or something. Commented May 5, 2020 at 9:16

1 Answer 1

2

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()
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.