Spiffy up the json parser with pretty-printing marks

This commit is contained in:
John Doty 2024-09-10 12:06:29 -07:00
parent 667273369e
commit 5d88b459b9

View file

@ -1,6 +1,6 @@
import typing import typing
from parser.parser import Grammar, Re, Terminal, rule, opt from parser.parser import Grammar, Re, Terminal, rule, opt, group, newline, alt
import parser.runtime as runtime import parser.runtime as runtime
import parser.wadler as wadler import parser.wadler as wadler
@ -29,23 +29,29 @@ class JsonGrammar(Grammar):
@rule @rule
def object(self): def object(self):
return self.LCURLY + opt(self._object_pairs) + self.RCURLY return group(self.LCURLY + opt(self._object_pairs) + self.RCURLY)
@rule @rule
def _object_pairs(self): def _object_pairs(self):
return self.object_pair | (self._object_pairs + self.COMMA + self.object_pair) return alt(
self.object_pair + newline(),
self.object_pair + self.COMMA + newline() + self._object_pairs,
)
@rule @rule
def object_pair(self): def object_pair(self):
return self.STRING + self.COLON + self.value return group(self.STRING + self.COLON + self.value)
@rule @rule
def array(self): def array(self):
return self.LSQUARE + opt(self._array_items) + self.RSQUARE return group(self.LSQUARE + opt(self._array_items) + self.RSQUARE)
@rule @rule
def _array_items(self): def _array_items(self):
return self.value | (self._array_items + self.COMMA + self.value) return alt(
self.value + newline(),
self.value + self.COMMA + newline() + self._array_items,
)
BLANKS = Terminal(Re.set(" ", "\t", "\r", "\n").plus()) BLANKS = Terminal(Re.set(" ", "\t", "\r", "\n").plus())
LCURLY = Terminal("{") LCURLY = Terminal("{")
@ -89,7 +95,7 @@ JSON_PARSER = runtime.Parser(JSON_TABLE)
def flatten_document(doc: wadler.Document, src: str) -> list: def flatten_document(doc: wadler.Document, src: str) -> list:
match doc: match doc:
case wadler.NewLine(): case wadler.NewLine():
return ["\n"] return ["<newline>"]
case wadler.Indent(): case wadler.Indent():
return [f"<indent {doc.amount}>", flatten_document(doc.doc, src)] return [f"<indent {doc.amount}>", flatten_document(doc.doc, src)]
case wadler.Text(start, end): case wadler.Text(start, end):
@ -117,21 +123,28 @@ def test_basic_printer():
doc = flatten_document(printer.convert_tree_to_document(tree), text) doc = flatten_document(printer.convert_tree_to_document(tree), text)
assert doc == [ assert doc == [
"{", [
'"a"', "{",
":", ['"a"', ":", "true"],
"true", ",",
",", "<newline>",
'"b"', [
":", '"b"',
"[", ":",
"1", [
",", "[",
"2", "1",
",", ",",
"3", "<newline>",
"]", "2",
"}", ",",
"<newline>",
"3",
"<newline>",
"]",
],
],
"<newline>",
"}",
]
] ]
pass