[Solved] Convert Valve data structure to JSON [closed]


Happily, the atoms used by the format are similar enough to Python that we can use the tokenize and ast modules for an ad-hoc parser.

It will probably break horribly on broken input, but works for your example data 🙂

import tokenize
import token
import ast
import io
import json


def parse_valve_format(data):
    dest = {}
    stack = [dest]
    for tok in tokenize.tokenize(io.BytesIO(data.encode()).readline):
        if tok.type == token.STRING:
            ts = ast.literal_eval(tok.string)
            if isinstance(stack[-1], str):
                # already a string on the stack?
                # this has to be a key-value setting
                key = stack.pop(-1)
                stack[-1][key] = ts
            else:
                # otherwise assume we'll find a } soon
                stack.append(ts)
        elif tok.type == token.OP and tok.string == "{":
            obj = {}
            key = stack.pop(-1)
            stack[-1][key] = obj
            stack.append(obj)
        elif tok.type == token.OP and tok.string == "}":
            assert isinstance(stack[-1], dict), "stray }"
            stack.pop(-1)
    return dest


result_dict = parse_valve_format(
    """
"items"
{
    "first"
    {
        "a"     "1"
        "b"     "2"
        "c"     "3"
        "d"     "4"
        "e"     "5"
    }
    "second"
    {
        "f"     "6"
        "g"     "7"
        "h"     "8"
        "i"     "9"
        "j"     "10"
    }
}
"""
)

print(json.dumps(result_dict, indent=2))

output:

{
  "items": {
    "first": {
      "a": "1",
      "b": "2",
      "c": "3",
      "d": "4",
      "e": "5"
    },
    "second": {
      "f": "6",
      "g": "7",
      "h": "8",
      "i": "9",
      "j": "10"
    }
  }
}

solved Convert Valve data structure to JSON [closed]