Valve's KV file format is as follows (in pseudo-EBNF):
<pair> ::= <text> <value>
<value> ::= <text> | <block>
<text> ::= "\"" <char>* "\""
<block> ::= "{" <pair>* "}"
The parsing starts on <pair>
state. Whitespace is allowed anywhere, but is only required between two consecutive <text>
tokens ("a""b"
is invalid, but "a" "b"
is valid, and so is "a"{}
).
And since I'm lazy, <char>
is any character, except "
, unless preceded by \
.
You can also see KV as JSON without commas and colons, and with only strings and objects as possible types.
Your task is to write a program or function that converts a input string (stdin, file or argument) in KV to a output string in JSON. You can output anywhere (stdout, file or return value), as long as it's a valid json string.
It isn't necessary to preserve whitespace in the output, as long as quoted text doesn't change.
Standard loopholes apply, of course.
Bonus
You get a -20 byte bonus if the output is pretty-printed, regardless of input. Pretty printed means indenting each level of blocks with 4 spaces, separating colons from values by 1 space and have one pair per line. Closing braces should stand on their own line.
Test cases
Input:
"foo" {
"bar" "baz"
"oof" {
"rab" "zab"
}
}
Output:
{
"foo": {
"bar": "baz",
"oof": {
"rab": "zab"
}
}
}
Input:
"obj" {
"emptyo" {}
"troll" "}{"
}
Output:
{
"obj": {
"emptyo": {},
"troll": "}{"
}
}
Input:
"newline" "
"
Output:
{
"newline": "\n"
}
Input:
"key
with_newline" {
"\"escaped\"quotes" "escaped_end\""
}
Output:
{
"key\nwith_newline": {
"\"escaped\"quotes": "escaped_end\""
}
}
text
to contain exactly one char, but all of your examples havetext
s with multiple chars. What should the spec say? 0 or more chars? 1 or more chars? \$\endgroup\$