From 61f18041fbdbb671205df781f4f35f6a2b715a9f Mon Sep 17 00:00:00 2001 From: olabusayoT <50379531+olabusayoT@users.noreply.github.com> Date: Thu, 21 Mar 2024 16:22:03 -0400 Subject: [PATCH] !fixup Enable dfdl:extraEscapedCharcaters to take an expression - implement Ev val and class for extraEscapedCharacters similar to escapeCharacter and escapeEscapeCharacter - add optimization to DynamicEscapeSchemeCombinatorElement adding isConstant to checks - fix bug in hasDynamicEscapeScheme by adding consideration for escapeSchemeUnparseEv - add optionExtraEscapedCharsEv to localElementPropertyReferencedElements - add tests for literal and expression examples - refactor extraEscaoedCgarCooked to evalAndConvertExtraEscapedCharacters to more closely match other Evs - add test for escapeBlocks and literal and expressioned extraEscapeChars DAFFODIL-2876 --- .../core/dsom/RuntimePropertyMixins.scala | 11 ++- .../grammar/ElementBaseGrammarMixin.scala | 2 +- .../DelimiterAndEscapeRelated.scala | 10 +-- .../runtime1/processors/EvEscapeSchemes.scala | 18 +++-- .../section07/escapeScheme/escapeScheme.tdml | 67 +++++++++++++++++++ .../escapeScheme/TestEscapeScheme.scala | 2 + 6 files changed, 97 insertions(+), 13 deletions(-) diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/RuntimePropertyMixins.scala b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/RuntimePropertyMixins.scala index 82ad4a720e..e04bca9c51 100644 --- a/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/RuntimePropertyMixins.scala +++ b/daffodil-core/src/main/scala/org/apache/daffodil/core/dsom/RuntimePropertyMixins.scala @@ -637,7 +637,16 @@ trait ElementRuntimeValuedPropertiesMixin f(es.optionEscapeEscapeCharacterEv.get) else ReferencedElementInfos.None - ee ++ propExprElts(es.optionEscapeCharacterRaw, es.escapeCharacterEv, f) + val extraEscapeChars = + if (es.optionExtraEscapedCharactersEv.isDefined) + f(es.optionExtraEscapedCharactersEv.get) + else + ReferencedElementInfos.None + ee ++ extraEscapeChars ++ propExprElts( + es.optionEscapeCharacterRaw, + es.escapeCharacterEv, + f, + ) } else { ReferencedElementInfos.None } diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ElementBaseGrammarMixin.scala b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ElementBaseGrammarMixin.scala index f34f1e1bd9..f94daf1536 100644 --- a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ElementBaseGrammarMixin.scala +++ b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/ElementBaseGrammarMixin.scala @@ -1409,7 +1409,7 @@ trait ElementBaseGrammarMixin } private lazy val hasDynamicEscapeScheme = - this.optionEscapeScheme.isDefined && !this.optionEscapeScheme.get.escapeSchemeParseEv.isConstant + this.optionEscapeScheme.isDefined && (!this.optionEscapeScheme.get.escapeSchemeParseEv.isConstant || !this.optionEscapeScheme.get.escapeSchemeUnparseEv.isConstant) private def withEscapeScheme(body: Gram) = { if (hasDynamicEscapeScheme) DynamicEscapeSchemeCombinatorElement(this, body) diff --git a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/DelimiterAndEscapeRelated.scala b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/DelimiterAndEscapeRelated.scala index 88036ff308..6c0fe81edf 100644 --- a/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/DelimiterAndEscapeRelated.scala +++ b/daffodil-core/src/main/scala/org/apache/daffodil/core/grammar/primitives/DelimiterAndEscapeRelated.scala @@ -120,18 +120,20 @@ case class DynamicEscapeSchemeCombinatorElement(e: ElementBase, body: Gram) val schemeParseOpt = e.optionEscapeScheme.map { _.escapeSchemeParseEv } val schemeUnparseOpt = e.optionEscapeScheme.map { _.escapeSchemeUnparseEv } - Assert.invariant(schemeParseOpt.isDefined && !schemeParseOpt.get.isConstant) - Assert.invariant(schemeUnparseOpt.isDefined && !schemeUnparseOpt.get.isConstant) + val schemeParseIsConstant = schemeParseOpt.map(_.isConstant).getOrElse(true) + val schemeUnparseIsConstant = schemeUnparseOpt.map(_.isConstant).getOrElse(true) + + Assert.invariant(!schemeParseIsConstant || !schemeUnparseIsConstant) lazy val parser: DaffodilParser = { val p = body.parser - if (p.isEmpty) p + if (p.isEmpty || schemeParseIsConstant) p else new DynamicEscapeSchemeParser(schemeParseOpt.get, e.termRuntimeData, p) } override lazy val unparser: DaffodilUnparser = { val u = body.unparser - if (u.isEmpty) u + if (u.isEmpty || schemeUnparseIsConstant) u else new DynamicEscapeSchemeUnparser(schemeUnparseOpt.get, e.termRuntimeData, u) } } diff --git a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/EvEscapeSchemes.scala b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/EvEscapeSchemes.scala index 2d8ded33b8..a4bdb885b3 100644 --- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/EvEscapeSchemes.scala +++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/processors/EvEscapeSchemes.scala @@ -85,11 +85,12 @@ abstract class EscapeSchemeUnparseEv(ci: DPathCompileInfo) def extraEscapedChars: Maybe[ExtraEscapedCharsEv] - def extraEscapedCharsCooked(state: State) = { + def evalAndConvertExtraEscapedCharacters(state: ParseOrUnparseState): Seq[Char] = { if (extraEscapedChars.isDefined) { - extraEscapedChars.get + val extEscChar = extraEscapedChars.get .evaluate(state) - .map { _.charAt(0) } + .map(_.charAt(0)) + extEscChar } else { Seq() } @@ -118,15 +119,17 @@ class EscapeSchemeCharUnparseEv( ci: DPathCompileInfo, ) extends EscapeSchemeUnparseEv(ci) { - override val runtimeDependencies = Vector(escapeChar) ++ optEscapeEscapeChar.toList + override val runtimeDependencies = + Vector(escapeChar) ++ optEscapeEscapeChar.toList ++ extraEscapedChars.toList def compute(state: ParseOrUnparseState) = { val escChar = escapeChar.evaluate(state).charAt(0) val optEscEscChar = evalAndConvertEEC(state) + val extEscChars = evalAndConvertExtraEscapedCharacters(state) new EscapeSchemeCharUnparserHelper( escChar, optEscEscChar, - extraEscapedCharsCooked(state), + extEscChars, ci, ) } @@ -159,18 +162,19 @@ class EscapeSchemeBlockUnparseEv( ci: DPathCompileInfo, ) extends EscapeSchemeUnparseEv(ci) { - override val runtimeDependencies = optEscapeEscapeChar.toList + override val runtimeDependencies = optEscapeEscapeChar.toList ++ extraEscapedChars.toList val bs = EscapeBlockStartCooker.convertConstant(blockStart, ci, forUnparse = true) val be = EscapeBlockEndCooker.convertConstant(blockEnd, ci, forUnparse = true) def compute(state: ParseOrUnparseState) = { val optEscEscChar = evalAndConvertEEC(state) + val extEscChars = evalAndConvertExtraEscapedCharacters(state) new EscapeSchemeBlockUnparserHelper( optEscEscChar, bs, be, - extraEscapedCharsCooked(state), + extEscChars, generateEscapeBlock, ci, ) diff --git a/daffodil-test/src/test/resources/org/apache/daffodil/section07/escapeScheme/escapeScheme.tdml b/daffodil-test/src/test/resources/org/apache/daffodil/section07/escapeScheme/escapeScheme.tdml index 9257577960..54c7bf6b9e 100644 --- a/daffodil-test/src/test/resources/org/apache/daffodil/section07/escapeScheme/escapeScheme.tdml +++ b/daffodil-test/src/test/resources/org/apache/daffodil/section07/escapeScheme/escapeScheme.tdml @@ -680,6 +680,18 @@ escapeEscapeCharacter=")" extraEscapedCharacters="" generateEscapeBlock="whenNeeded"/> + + + + + + + + @@ -688,6 +700,27 @@ + + + + + + + + + + + + + + + + + + + + + ? *,1,(Column Number? Two*),3,4,5 + + + + ? * + 1 + Column Number? Two* + 3 + 4 + 5 + + + + + + + ? *,1,(Column Number? Two*),3,4,5 + + + + ? * + 1 + Column Number? Two* + 3 + 4 + 5 + + + + +