Starting to look at pretty-printing with the idea of auto-indentation

I wonder if it will work?
This commit is contained in:
John Doty 2024-09-06 16:23:14 -07:00
parent d7dfd556ec
commit 00b4cd4702
2 changed files with 57 additions and 14 deletions

View file

@ -1,5 +1,20 @@
# This is an example grammar. # This is an example grammar.
from parser import alt, Assoc, Grammar, rule, seq, Rule, Terminal, Re, highlight, mark, opt from parser import (
Assoc,
Grammar,
Re,
Rule,
Terminal,
alt,
group,
highlight,
indent,
mark,
newline,
opt,
rule,
seq,
)
class FineGrammar(Grammar): class FineGrammar(Grammar):
@ -36,7 +51,10 @@ class FineGrammar(Grammar):
@rule @rule
def _file_statement_list(self) -> Rule: def _file_statement_list(self) -> Rule:
return self._file_statement | (self._file_statement_list + self._file_statement) return alt(
self._file_statement,
self._file_statement_list + newline() + self._file_statement,
)
@rule @rule
def _file_statement(self) -> Rule: def _file_statement(self) -> Rule:
@ -51,10 +69,19 @@ class FineGrammar(Grammar):
@rule("ClassDeclaration") @rule("ClassDeclaration")
def class_declaration(self) -> Rule: def class_declaration(self) -> Rule:
return seq( return seq(
self.CLASS, group(
mark(self.IDENTIFIER, field="name", highlight=highlight.entity.name.type), group(
self.LCURLY, self.CLASS,
mark(opt(self.class_body), field="body"), newline(),
mark(self.IDENTIFIER, field="name", highlight=highlight.entity.name.type),
),
self.LCURLY,
),
indent(
newline(),
mark(opt(self.class_body), field="body"),
),
newline(),
self.RCURLY, self.RCURLY,
) )
@ -117,13 +144,17 @@ class FineGrammar(Grammar):
@rule("ParamList") @rule("ParamList")
def function_parameters(self) -> Rule: def function_parameters(self) -> Rule:
return seq( return group(
self.LPAREN, self.LPAREN,
opt( indent(
self._first_parameter newline(),
| seq(self._first_parameter, self.COMMA) opt(
| seq(self._first_parameter, self.COMMA, self._parameter_list) self._first_parameter
| seq(self._first_parameter, self.COMMA)
| group(self._first_parameter, self.COMMA, newline(), self._parameter_list)
),
), ),
newline(),
self.RPAREN, self.RPAREN,
) )
@ -133,7 +164,7 @@ class FineGrammar(Grammar):
@rule @rule
def _parameter_list(self) -> Rule: def _parameter_list(self) -> Rule:
return self.parameter | seq(self.parameter, self.COMMA, self._parameter_list) return self.parameter | seq(self.parameter, self.COMMA, newline(), self._parameter_list)
@rule("Parameter") @rule("Parameter")
def parameter(self) -> Rule: def parameter(self) -> Rule:
@ -144,7 +175,7 @@ class FineGrammar(Grammar):
def block(self) -> Rule: def block(self) -> Rule:
return alt( return alt(
seq(self.LCURLY, self.RCURLY), seq(self.LCURLY, self.RCURLY),
seq(self.LCURLY, self.block_body, self.RCURLY), group(self.LCURLY, indent(newline(), self.block_body), newline(), self.RCURLY),
) )
@rule("BlockBody") @rule("BlockBody")
@ -152,7 +183,7 @@ class FineGrammar(Grammar):
return alt( return alt(
self.expression, self.expression,
self._statement_list, self._statement_list,
seq(self._statement_list, self.expression), seq(self._statement_list, newline(), self.expression),
) )
@rule @rule

View file

@ -1785,6 +1785,18 @@ def mark(rule: Rule, **kwargs) -> Rule:
return MetadataRule(rule, kwargs) return MetadataRule(rule, kwargs)
def group(*rules: Rule) -> Rule:
return seq(*rules)
def indent(*rules: Rule) -> Rule:
return seq(*rules)
def newline() -> Rule:
return Nothing
@typing.overload @typing.overload
def rule(f: typing.Callable, /) -> Rule: ... def rule(f: typing.Callable, /) -> Rule: ...