From: Lanius Trolling Date: Mon, 7 Nov 2022 22:32:52 +0000 (-0500) Subject: Fix parser X-Git-Url: https://gitweb.starshipfights.net/?a=commitdiff_plain;h=5e1732b9d3a2c485444bb89adfa90d9626b1dff1;p=factbooks Fix parser --- diff --git a/src/main/kotlin/info/mechyrdia/lore/parser.kt b/src/main/kotlin/info/mechyrdia/lore/parser.kt index f8bce69..8737a05 100644 --- a/src/main/kotlin/info/mechyrdia/lore/parser.kt +++ b/src/main/kotlin/info/mechyrdia/lore/parser.kt @@ -1,7 +1,6 @@ package info.mechyrdia.lore data class TextParserScope( - var buffer: String = "", val write: Appendable, val tags: TextParserTags, val ctx: TContext @@ -9,27 +8,24 @@ data class TextParserScope( sealed class TextParserState( val scope: TextParserScope, - val insideTags: List, String?>>, + val insideTags: List>, val insideDirectTags: List ) { abstract fun processCharacter(char: Char): TextParserState abstract fun processEndOfText() protected fun appendText(text: String) { - scope.buffer += censorText(text) - } - - protected fun appendTextRaw(text: String) { - scope.buffer += text - } - - protected fun flushBuffer() { scope.write.append( - insideTags.foldRight(scope.buffer) { (tag, param), t -> - tag.process(param, t, scope.ctx) + insideTags.foldRight(censorText(text)) { (tag, param), t -> + (scope.tags[tag] as? TextParserTagType.Indirect) + ?.process(param, t, scope.ctx) + ?: "[$tag${param?.let { "=$it" } ?: ""}]$t[/$tag]" } ) - scope.buffer = "" + } + + protected fun appendTextRaw(text: String) { + scope.write.append(text) } class Initial(scope: TextParserScope) : TextParserState(scope, listOf(), listOf()) { @@ -45,7 +41,7 @@ sealed class TextParserState( } } - class PlainText(scope: TextParserScope, val text: String, insideTags: List, String?>>, insideDirectTags: List) : TextParserState(scope, insideTags, insideDirectTags) { + class PlainText(scope: TextParserScope, val text: String, insideTags: List>, insideDirectTags: List) : TextParserState(scope, insideTags, insideDirectTags) { override fun processCharacter(char: Char): TextParserState { return if (char == '[') { appendText(text) @@ -66,11 +62,10 @@ sealed class TextParserState( override fun processEndOfText() { appendText(text) - flushBuffer() } } - class NoFormatText(scope: TextParserScope, val text: String, insideTags: List, String?>>, insideDirectTags: List) : TextParserState(scope, insideTags, insideDirectTags) { + class NoFormatText(scope: TextParserScope, val text: String, insideTags: List>, insideDirectTags: List) : TextParserState(scope, insideTags, insideDirectTags) { override fun processCharacter(char: Char): TextParserState { val newText = text + char return if (newText.endsWith("[/$NO_FORMAT_TAG]")) { @@ -86,11 +81,10 @@ sealed class TextParserState( override fun processEndOfText() { appendText(text) - flushBuffer() } } - class OpenTag(scope: TextParserScope, val tag: String, insideTags: List, String?>>, insideDirectTags: List) : TextParserState(scope, insideTags, insideDirectTags) { + class OpenTag(scope: TextParserScope, val tag: String, insideTags: List>, insideDirectTags: List) : TextParserState(scope, insideTags, insideDirectTags) { override fun processCharacter(char: Char): TextParserState { return if (char == ']') { if (tag.equals(NO_FORMAT_TAG, ignoreCase = true)) @@ -99,19 +93,10 @@ sealed class TextParserState( (scope.tags[tag] as? TextParserTagType.Direct)?.begin(null, scope.ctx)?.let { appendTextRaw(it) } - flushBuffer() PlainText(scope, "", insideTags, insideDirectTags + tag) - } else if (scope.tags[tag] is TextParserTagType.Indirect) { - val tagType = scope.tags[tag] as TextParserTagType.Indirect - flushBuffer() - - PlainText(scope, "", insideTags + (tagType to null), insideDirectTags) - } else { - appendText("[$tag]") - - PlainText(scope, "", insideTags, insideDirectTags) - } + } else + PlainText(scope, "", insideTags + (tag to null), insideDirectTags) } else if (char == '/' && tag == "") CloseTag(scope, tag, insideTags, insideDirectTags) else if (char == '=' && tag != "") @@ -122,51 +107,37 @@ sealed class TextParserState( override fun processEndOfText() { appendText("[$tag") - flushBuffer() } } - class TagParam(scope: TextParserScope, val tag: String, val param: String, insideTags: List, String?>>, insideDirectTags: List) : TextParserState(scope, insideTags, insideDirectTags) { + class TagParam(scope: TextParserScope, val tag: String, val param: String, insideTags: List>, insideDirectTags: List) : TextParserState(scope, insideTags, insideDirectTags) { override fun processCharacter(char: Char): TextParserState { return if (char == ']') { - when (val tagType = scope.tags[tag]) { - is TextParserTagType.Direct -> { - appendTextRaw(tagType.begin(param, scope.ctx)) - flushBuffer() - - PlainText(scope, "", insideTags, insideDirectTags + tag) - } + val tagType = scope.tags[tag] + if (tagType is TextParserTagType.Direct) { + appendTextRaw(tagType.begin(param, scope.ctx)) - is TextParserTagType.Indirect -> { - flushBuffer() - PlainText(scope, "", insideTags + (tagType to param), insideDirectTags) - } - else -> { - appendText("[$tag=$param]") - - PlainText(scope, "", insideTags, insideDirectTags) - } - } + PlainText(scope, "", insideTags, insideDirectTags + tag) + } else + PlainText(scope, "", insideTags + (tag to param), insideDirectTags) } else TagParam(scope, tag, param + char, insideTags, insideDirectTags) } override fun processEndOfText() { appendText("[$tag=$param") - flushBuffer() } } - class CloseTag(scope: TextParserScope, val tag: String, insideTags: List, String?>>, insideDirectTags: List) : TextParserState(scope, insideTags, insideDirectTags) { + class CloseTag(scope: TextParserScope, val tag: String, insideTags: List>, insideDirectTags: List) : TextParserState(scope, insideTags, insideDirectTags) { override fun processCharacter(char: Char): TextParserState { return if (char == ']') { val tagType = scope.tags[tag] if (tagType is TextParserTagType.Direct && insideDirectTags.last().equals(tag, ignoreCase = true)) { appendTextRaw(tagType.end(scope.ctx)) - flushBuffer() + PlainText(scope, "", insideTags, insideDirectTags.dropLast(1)) - } else if (insideTags.isNotEmpty() && insideTags.last().first == scope.tags[tag]) { - flushBuffer() + } else if (insideTags.isNotEmpty() && insideTags.last().first.equals(tag, ignoreCase = true)) { PlainText(scope, "", insideTags.dropLast(1), insideDirectTags) } else { appendText("[/$tag]") @@ -177,7 +148,6 @@ sealed class TextParserState( override fun processEndOfText() { appendText("[/$tag") - flushBuffer() } } @@ -200,7 +170,7 @@ sealed class TextParserState( val builder = StringBuilder() try { val fixedText = text.replace("\r\n", "\n").replace('\r', '\n') - fixedText.fold>(Initial(TextParserScope("", builder, tags, context))) { state, char -> state.processCharacter(char) }.processEndOfText() + fixedText.fold>(Initial(TextParserScope(builder, tags, context))) { state, char -> state.processCharacter(char) }.processEndOfText() } catch (ex: Exception) { return ParseOutcome("

$builder

Internal Error!

${ex.stackTraceToString()}
", false) }