From e689a44687fe1b81dd03f7adff635e9733a6df8d Mon Sep 17 00:00:00 2001 From: octarine-noise Date: Mon, 26 Jul 2021 16:29:54 +0200 Subject: [PATCH] simpler parser, allow for negated conditions --- src/main/javacc/BlockConfig.jj | 47 +++++++++---------- .../mods/betterfoliage/config/BlockConfig.kt | 2 +- .../mods/betterfoliage/config/match/Match.kt | 5 ++ .../betterfoliage/config/match/ParseTree.kt | 4 ++ .../mods/betterfoliage/config/match/Rules.kt | 17 ++++--- .../resource/discovery/RuleBasedDiscovery.kt | 2 + 6 files changed, 44 insertions(+), 33 deletions(-) diff --git a/src/main/javacc/BlockConfig.jj b/src/main/javacc/BlockConfig.jj index 7e2524e..eef8248 100644 --- a/src/main/javacc/BlockConfig.jj +++ b/src/main/javacc/BlockConfig.jj @@ -31,34 +31,42 @@ TOKEN : { < parenStart : "(" > | < parenEnd : ")" > | < dot : "." > | - < comma : "," > + < comma : "," > | + < exclamation : "!" > } -void matchFile(List parent) : { - Token t; +List matchFile() : { + Token t; Node n; List rules = new LinkedList(); } { ( t = "match" { List nodes = new LinkedList(); } - (match(nodes))* + (n = match() { nodes.add(n); })* "end" - { parent.add(new Node.MatchAll(getSource(t), nodes)); } + { rules.add(new Node.MatchAll(getSource(t), nodes)); } )* + { return rules; } } -void match(List parent) : { - Token t; Token t2; MatchMethod mm; List values; Node.Value v; +Node match() : { + Token t; Token t2; MatchMethod mm; List values; Node.Value v; Node n; } { - "block." matchBlock(parent) + n = match() { return new Node.Negate(n); } + | + t = "block.class." mm = matchMethod() values = matchValueList() + { return new Node.MatchValueList(Node.MatchSource.BLOCK_CLASS, mm, getSource(t), values); } + | + t = "block.name." mm = matchMethod() values = matchValueList() + { return new Node.MatchValueList(Node.MatchSource.BLOCK_NAME, mm, getSource(t), values); } | t = "model." mm = matchMethod() values = matchValueList() - { parent.add(new Node.MatchValueList(Node.MatchSource.MODEL_LOCATION, mm, getSource(t), values)); } + { return new Node.MatchValueList(Node.MatchSource.MODEL_LOCATION, mm, getSource(t), values); } | t = "isParam" t2 = values = matchValueList() - { parent.add(new Node.MatchParam(t2.image, values, getSource(t))); } + { return new Node.MatchParam(t2.image, values, getSource(t)); } | t = "setParam" t2 = v = matchValue() - { parent.add(new Node.SetParam(t2.image, v, getSource(t))); } + { return new Node.SetParam(t2.image, v, getSource(t)); } } MatchMethod matchMethod() : {} { @@ -67,26 +75,13 @@ MatchMethod matchMethod() : {} { "contains" { return MatchMethod.CONTAINS; } } -void matchBlock(List parent) : { - Token t; MatchMethod mm; List values; -} { - t = "class." mm = matchMethod() values = matchValueList() - { parent.add(new Node.MatchValueList(Node.MatchSource.BLOCK_CLASS, mm, getSource(t), values)); } - | - t = "name." mm = matchMethod() values = matchValueList() - { parent.add(new Node.MatchValueList(Node.MatchSource.BLOCK_NAME, mm, getSource(t), values)); } -} - List matchValueList() : { List values = new LinkedList(); -} { - matchValueToList(values) ( matchValueToList(values))* { return values; } -} - -void matchValueToList(List values) : { Node.Value v; } { v = matchValue() { values.add(v); } + ( v = matchValue() { values.add(v); } )* + { return values; } } Node.Value matchValue() : { diff --git a/src/main/kotlin/mods/betterfoliage/config/BlockConfig.kt b/src/main/kotlin/mods/betterfoliage/config/BlockConfig.kt index 083e2bb..a8b39af 100644 --- a/src/main/kotlin/mods/betterfoliage/config/BlockConfig.kt +++ b/src/main/kotlin/mods/betterfoliage/config/BlockConfig.kt @@ -21,7 +21,7 @@ class BlockConfig : HasLogger() { val parser = BlockConfigParser(resource.inputStream) .apply { configFile = configLocation.stripStart("config/betterfoliage/").toString() } try { - mutableListOf().apply { parser.matchFile(this) } + parser.matchFile() } catch (e: ParseException) { parseError(e, configLocation) } catch (e: TokenMgrError) { diff --git a/src/main/kotlin/mods/betterfoliage/config/match/Match.kt b/src/main/kotlin/mods/betterfoliage/config/match/Match.kt index e1aae77..e804f3e 100644 --- a/src/main/kotlin/mods/betterfoliage/config/match/Match.kt +++ b/src/main/kotlin/mods/betterfoliage/config/match/Match.kt @@ -71,6 +71,11 @@ class MListAny(val list: List>) : MAnything { override val immutable get() = list.all { it.immutable } } +class MNegated(val inner: MAnything) : MAnything { + override val value get() = !inner.value + override val immutable get() = inner.immutable +} + /** * Value with metadata related to rule matching applied. * diff --git a/src/main/kotlin/mods/betterfoliage/config/match/ParseTree.kt b/src/main/kotlin/mods/betterfoliage/config/match/ParseTree.kt index 7f2dba6..182c78c 100644 --- a/src/main/kotlin/mods/betterfoliage/config/match/ParseTree.kt +++ b/src/main/kotlin/mods/betterfoliage/config/match/ParseTree.kt @@ -25,6 +25,10 @@ sealed class Node { override val configSource: ConfigSource, ) : Node() + class Negate(val node: Node) : Node() { + override val configSource get() = node.configSource + } + class SetParam(val name: String, val value: Value, override val configSource: ConfigSource) : Node() class MatchAll(override val configSource: ConfigSource, val list: List) : Node() diff --git a/src/main/kotlin/mods/betterfoliage/config/match/Rules.kt b/src/main/kotlin/mods/betterfoliage/config/match/Rules.kt index 1ecfdff..29980cf 100644 --- a/src/main/kotlin/mods/betterfoliage/config/match/Rules.kt +++ b/src/main/kotlin/mods/betterfoliage/config/match/Rules.kt @@ -17,18 +17,23 @@ object MatchRules { fun visitRoot(ctx: RuleProcessingContext, node: Node.MatchAll): MListAll { val results = mutableListOf>() for (rule in node.list) { - val result = when(rule) { - is Node.MatchValueList -> mMatchList(ctx, rule) - is Node.MatchParam -> mParam(ctx, rule) - is Node.SetParam -> mParamSet(ctx, rule) - else -> rule.error("match type not implemented: ${rule::class.java.name.quoted}").left - } + val result = mNode(ctx, rule) results.add(result) if (!result.value) break } return MListAll(results) } + fun mNode(ctx: RuleProcessingContext, node: Node): MAnything = when(node) { + is Node.MatchValueList -> mMatchList(ctx, node) + is Node.MatchParam -> mParam(ctx, node) + is Node.SetParam -> mParamSet(ctx, node) + is Node.Negate -> mNegate(ctx, node) + else -> node.error("match type not implemented: ${node::class.java.name.quoted}").left + } + + fun mNegate(ctx: RuleProcessingContext, node: Node.Negate) = MNegated(mNode(ctx, node.node)) + fun mMatchList(ctx: RuleProcessingContext, node: Node.MatchValueList) = node.values.map { value -> when (node.matchSource) { Node.MatchSource.BLOCK_CLASS -> mBlockClass(ctx, node, value) diff --git a/src/main/kotlin/mods/betterfoliage/resource/discovery/RuleBasedDiscovery.kt b/src/main/kotlin/mods/betterfoliage/resource/discovery/RuleBasedDiscovery.kt index 14182a2..b75196c 100644 --- a/src/main/kotlin/mods/betterfoliage/resource/discovery/RuleBasedDiscovery.kt +++ b/src/main/kotlin/mods/betterfoliage/resource/discovery/RuleBasedDiscovery.kt @@ -4,6 +4,7 @@ import mods.betterfoliage.BetterFoliage import mods.betterfoliage.config.match.MAnything import mods.betterfoliage.config.match.MListAll import mods.betterfoliage.config.match.MListAny +import mods.betterfoliage.config.match.MNegated import mods.betterfoliage.config.match.MValue import mods.betterfoliage.config.match.MatchRules import mods.betterfoliage.util.HasLogger @@ -89,6 +90,7 @@ class RuleBasedDiscovery : AbstractModelDiscovery() { } is MListAny -> if (match.value) match.list.first { it.value }.let { logResult(it) } else match.list.forEach { logResult(it) } + is MNegated -> logResult(match.inner) is MValue -> detailLogger.log(Level.INFO, "[${match.configSource}] ${match.description}") } }