All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.tel.schich.parserkombinator.Tracing.kt Maven / Gradle / Ivy

package tel.schich.parserkombinator

import kotlin.jvm.JvmName

expect fun isTracingEnabled(): Boolean

private var suppressTraces = false
private var traceDepth = 0

@JvmName("forTraceChars")
fun forTrace(chars: Set): String =
    chars.joinToString(prefix = "{", separator = ", ", postfix = "}") { forTrace(it) }

@JvmName("forTraceStrings")
fun forTrace(strings: Set): String =
    strings.joinToString(prefix = "{", separator = ", ", postfix = "}") { forTrace(it, "\"") }

fun forTrace(c: Char): String = "'${forTrace("$c", "'")}'"

fun forTrace(c: String): String = "\"${forTrace(c, "\"")}\""

fun forTrace(s: CharSequence, quote: String) = forTrace(s).replace(quote, "\\$quote")

fun forTrace(s: CharSequence) = s.toString()
    .replace("\\", "\\\\")
    .replace("\n", "\\n")
    .replace("\r", "\\r")
    .replace("\t", "\\t")

fun  trace(msg: String, parser: Parser): Parser = trace(msg, shallow = false, parser)

fun  trace(msg: String, shallow: Boolean, parser: Parser): Parser {
    // disappear from parser call stacks
    if (!isTracingEnabled()) {
        return parser
    }
    return { input ->
        if (suppressTraces) {
            parser(input)
        } else {
            val depth = traceDepth
            traceDepth += 1
            val prefix = "|\t".repeat(depth) + ">"
            println("$prefix $msg")
            suppressTraces = shallow
            val result = parser(input)
            suppressTraces = false
            traceDepth -= 1
            when (result) {
                is ParserResult.Ok -> {
                    val len = input.length - result.rest.length
                    val content = input.string.substring(input.offset, input.offset + len)
                    println("$prefix ✓ (len=$len, content=\"${ forTrace(content, "\"")}\")")
                }
                is ParserResult.Error -> {
                    println("$prefix ! ${forTrace(result.message)}")
                }
            }
            result
        }
    }
}

@Suppress("NOTHING_TO_INLINE")
inline fun  Parser.traced(msg: String, shallow: Boolean = false): Parser = trace(msg, shallow, this)




© 2015 - 2024 Weber Informatics LLC | Privacy Policy