parsley.debugger.frontend.internal.consolepretty.scala Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2020 Parsley Contributors
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package parsley.debugger.frontend.internal
import scala.annotation.tailrec
import scala.collection.mutable
import parsley.debugger.{DebugTree, ParseAttempt}
private [debugger] object consolepretty {
// Utility class for aiding in the toString method for debug trees.
private [frontend] case class PrettyPrintHelper(acc: mutable.StringBuilder, indents: Vector[String]) {
// Indent a string with the given indenting delimiters.
def bury(str: String, withMark: Boolean = true): Unit = {
val pretty =
if (indents.isEmpty) str
else if (withMark) indents.init.mkString + "+-" + str
else indents.mkString + str
acc.append(pretty + "\n")
}
// Add a new indent delimiter to the current helper instance.
// The accumulator is shared between new instances.
def addIndent: PrettyPrintHelper = PrettyPrintHelper(acc, indents :+ "| ")
// Adds a two-blank-space indent instead for the last child of a node.
def addBlankIndent: PrettyPrintHelper = PrettyPrintHelper(acc, indents :+ " ")
}
implicit final class TreePrinter(val dt: DebugTree) extends AnyVal {
def pretty: String = {
val acc = new mutable.StringBuilder
prettyPrint(PrettyPrintHelper(acc, Vector.empty))
acc.init.toString
}
private [consolepretty] def prettyPrint(helper: PrettyPrintHelper): Unit = {
val uname =
if (dt.parserName != dt.internalName)
s"${dt.parserName} (${dt.internalName}${if (dt.childNumber.isDefined) s" (${dt.childNumber.get})" else ""})"
else
s"${dt.internalName}${if (dt.childNumber.isDefined) s" (${dt.childNumber.get})" else ""}"
val results = dt.parseResults.map(printParseAttempt).mkString
helper.bury(s"[ $uname ]: $results")
printChildren(helper, dt.nodeChildren.toList)
}
// Print a parse attempt in a human-readable way.
private [TreePrinter] def printParseAttempt(attempt: ParseAttempt): String = {
val status = if (attempt.success) s"Success - [ ${attempt.result.get} ]" else "Failure"
s"""(\"${attempt.rawInput}\" [${attempt.fromPos} -> ${attempt.toPos}], $status)"""
}
// Print all the children, remembering to add a blank indent for the last child.
@tailrec private def printChildren(helper: PrettyPrintHelper, children: List[(String, DebugTree)]): Unit = children match {
case (_, t) :: Nil =>
helper.bury("|", withMark = false)
t.prettyPrint(helper.addBlankIndent)
case (_, t) :: xs =>
helper.bury("|", withMark = false)
t.prettyPrint(helper.addIndent)
printChildren(helper, xs)
case Nil =>
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy