This is an automated email from the ASF dual-hosted git repository.
aradzinski pushed a commit to branch NLPCRAFT-247
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git
The following commit(s) were added to refs/heads/NLPCRAFT-247 by this push:
new 2dd25ac WIP.
2dd25ac is described below
commit 2dd25acb69e6633a7961e14dd864a3fa925e9966
Author: Aaron Radzinski <[email protected]>
AuthorDate: Mon Feb 22 17:08:39 2021 -0800
WIP.
---
.../nlpcraft/common/makro/NCMacroCompiler.scala | 30 ++++++++++----------
.../common/makro/NCMacroCompilerSpec.scala | 32 ++++++++++++++++++++--
2 files changed, 44 insertions(+), 18 deletions(-)
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/common/makro/NCMacroCompiler.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/common/makro/NCMacroCompiler.scala
index 16a43a6..ac07f74 100644
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/common/makro/NCMacroCompiler.scala
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/common/makro/NCMacroCompiler.scala
@@ -59,11 +59,7 @@ object NCMacroCompiler extends LazyLogging {
* @param s
* @return
*/
- private def add(optS: String, s: String): String =
- if (optS.isEmpty)
- s
- else
- optS + " " + s
+ private def concat(optS: String, s: String): String = if
(optS.isEmpty) s else optS + " " + s
/**
*
@@ -77,26 +73,29 @@ object NCMacroCompiler extends LazyLogging {
override def enterExpr(ctx: NCMacroDslParser.ExprContext): Unit = {
val buf = mutable.Buffer.empty[String]
+ // NOTE: do not allow expression's buffer to be empty.
+ // Add harmless empty string.
buf += ""
stack.push(StackItem(buf, false))
}
- override def enterGroup(ctx: P.GroupContext): Unit =
+ override def enterGroup(ctx: P.GroupContext): Unit = {
+ // NOTE: group cannot be empty based on the BNF grammar.
stack.push(StackItem(mutable.Buffer.empty[String], true))
+ }
override def exitExpr(ctx: NCMacroDslParser.ExprContext): Unit = {
if (stack.size > 1) {
val expr = stack.pop()
+ val prn = stack.top
require(expr.buffer.nonEmpty)
- val prn = stack.top
-
if (prn.isGroup)
prn.buffer ++= expr.buffer
else
- prn.buffer = for (z ← expr.buffer; i ← prn.buffer.indices)
yield add(prn.buffer(i), z)
+ prn.buffer = for (z ← expr.buffer; i ← prn.buffer.indices)
yield concat(prn.buffer(i), z)
}
}
@@ -108,7 +107,7 @@ object NCMacroCompiler extends LazyLogging {
val prn = stack.top
prn.buffer = prn.buffer.flatMap {
- s ⇒ (for (z ← grp.buffer; i ← min to max) yield add(s, s"$z "
* i).trim).toSet
+ s ⇒ (for (z ← grp.buffer; i ← min to max) yield concat(s, s"$z
" * i).trim).toSet
}
// Reset min max.
@@ -119,11 +118,10 @@ object NCMacroCompiler extends LazyLogging {
override def exitSyn(ctx: P.SynContext): Unit = {
val syn = if (ctx.TXT() != null) ctx.TXT().getText else
ctx.INT().getText
val buf = stack.top.buffer
-
- if (buf.isEmpty)
- buf += syn
- else
- for (i ← buf.indices) buf.update(i, add(buf(i), syn))
+
+ require(buf.nonEmpty)
+
+ for (i ← buf.indices) buf.update(i, concat(buf(i), syn))
}
override def exitList(ctx: P.ListContext): Unit =
@@ -150,7 +148,7 @@ object NCMacroCompiler extends LazyLogging {
}
if (min < 0 || max < 0 || min > max || max == 0)
- throw error(s"Min/max quantifiers should satisfy 'max >= min,
min >= 0, max > 0': [$min, $max]")
+ throw error(s"[min,max] quantifiers should satisfy 'max >=
min, min >= 0, max > 0': [$min, $max]")
}
/**
diff --git
a/nlpcraft/src/test/scala/org/apache/nlpcraft/common/makro/NCMacroCompilerSpec.scala
b/nlpcraft/src/test/scala/org/apache/nlpcraft/common/makro/NCMacroCompilerSpec.scala
index 3f0880e..123a18d 100644
---
a/nlpcraft/src/test/scala/org/apache/nlpcraft/common/makro/NCMacroCompilerSpec.scala
+++
b/nlpcraft/src/test/scala/org/apache/nlpcraft/common/makro/NCMacroCompilerSpec.scala
@@ -19,6 +19,7 @@ package org.apache.nlpcraft.common.makro
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
+import org.apache.nlpcraft.common._
/**
* Unit tests for the macro compiler.
@@ -38,26 +39,53 @@ class NCMacroCompilerSpec {
assertTrue(res == z)
}
+
+ /**
+ *
+ * @param txt
+ */
+ private def checkError(txt: String): Unit = {
+ try {
+ NCMacroCompiler.compile(txt)
+
+ assert(false)
+ } catch {
+ case e: NCE ⇒
+ println(e.getMessage)
+ assert(true)
+ }
+ }
@Test
- def testCompiler(): Unit = {
+ def testOkCompiler(): Unit = {
checkEq("A", Seq("A"))
checkEq(" A ", Seq("A"))
checkEq("A B", Seq("A B"))
checkEq("A B", Seq("A B"))
checkEq("{A}", Seq("A"))
+ checkEq("{{{A}}[1,1]}[1,1]", Seq("A"))
checkEq("XX {A}", Seq("XX A"))
checkEq("{A}[0,2]", Seq("", "A", "A A"))
checkEq("{A } [0 ,2]", Seq("", "A", "A A"))
checkEq("{A }", Seq("A"))
checkEq(" { A }", Seq("A"))
checkEq("{A}{B}", Seq("A B"))
+ checkEq("{A}[0,1]{ { {B}}}", Seq("B", "A B"))
+ checkEq("{A}[0,1]{ { {xx B}}}", Seq("xx B", "A xx B"))
checkEq(" { A }{B}", Seq("A B"))
checkEq(" { A } {B}", Seq("A B"))
- checkEq("A {B | C}", Seq("A B", "A C"))
+ checkEq("A {B | C | _}", Seq("A", "A B", "A C"))
checkEq("{A}[2,2]", Seq("A A"))
checkEq("{A}[1,2]", Seq("A", "A A"))
checkEq("{A}[1,2] {B}[2,2]", Seq("A B B", "A A B B"))
+ checkEq("yy {xx A|_}[1,2] zz", Seq("yy zz", "yy xx A zz", "yy xx A xx
A zz"))
+ checkEq("yy {xx A|_}[0,2] zz", Seq("yy zz", "yy xx A zz", "yy xx A xx
A zz"))
checkEq("A {B| xxx {C|E}} D", Seq("A B D", "A xxx C D", "A xxx E D"))
}
+
+ @Test
+ def testFailCompiler(): Unit = {
+ checkError("{A")
+ checkError("{A}[2,1]")
+ }
}