Fix for NLPCRAFT-417 + WIP on NLPCRAFT-384
diff --git a/nlpcraft-examples/cargps/src/main/resources/cargps_model.yaml b/nlpcraft-examples/cargps/src/main/resources/cargps_model.yaml
index d8c6199..357fcf7 100644
--- a/nlpcraft-examples/cargps/src/main/resources/cargps_model.yaml
+++ b/nlpcraft-examples/cargps/src/main/resources/cargps_model.yaml
@@ -65,7 +65,7 @@
- id: "x:remove-waypoint"
description: "Remove 'waypoint' action."
synonyms:
- - "{skip|remove} {over|*} {last|latest|*} <WAYPOINT>"
+ - "{skip|remove} {over|_} {last|latest|_} <WAYPOINT>"
intents:
- "import('cargps_intents.idl')"
\ No newline at end of file
diff --git a/nlpcraft-examples/cargps/src/main/resources/samples/cargps_cancel_samples.txt b/nlpcraft-examples/cargps/src/main/resources/samples/cargps_cancel_samples.txt
index 80c6568..c6b132d 100644
--- a/nlpcraft-examples/cargps/src/main/resources/samples/cargps_cancel_samples.txt
+++ b/nlpcraft-examples/cargps/src/main/resources/samples/cargps_cancel_samples.txt
@@ -19,4 +19,10 @@
# Set of samples (corpus) for automatic unit and regression testing.
#
-Hey truck - stop the navigation!
\ No newline at end of file
+Hey truck - stop the navigation!
+Howdy, car, please cancel the routing now.
+Hi car - stop the route.
+Hi car - stop the navigation...
+Howdy truck - quit navigating.
+Hi car - finish off the driving.
+Hi car - cancel the journey.
\ No newline at end of file
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCIdlCompiler.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCIdlCompiler.scala
index 95928cd..b643a22 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCIdlCompiler.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCIdlCompiler.scala
@@ -624,8 +624,14 @@
line: Int, // 1, 2, ...
charPos: Int, // 1, 2, ...
msg: String,
- e: RecognitionException): Unit =
- throw new NCE(mkSyntaxError(msg, recog.getInputStream.getSourceName, line, charPos - 1, dsl, origin, mdl))
+ e: RecognitionException): Unit = {
+ val aMsg = if ((msg.contains("'\"") && msg.contains("\"'")) || msg.contains("''"))
+ s"${if (msg.last == '.') msg.substring(0, msg.length - 1) else msg} - try removing quotes."
+ else
+ msg
+
+ throw new NCE(mkSyntaxError(aMsg, recog.getInputStream.getSourceName, line, charPos - 1, dsl, origin, mdl))
+ }
}
/**
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/deploy/NCDeployManager.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/deploy/NCDeployManager.scala
index 8d89477..122b5dc 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/deploy/NCDeployManager.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/deploy/NCDeployManager.scala
@@ -156,6 +156,16 @@
for (makro <- macros.keys if !set.exists(_.contains(makro)))
logger.warn(s"Unused macro detected [mdlId=${mdl.getId}, macro=$makro]")
+
+ def isSuspicious(s: String): Boolean = //s.toCharArray.toSeq.intersect(SUSP_SYNS_CHARS).nonEmpty
+ SUSP_SYNS_CHARS.exists(susp => s.contains(susp))
+
+ for (makro <- macros)
+ if (isSuspicious(makro._1) || isSuspicious(makro._2))
+ logger.warn(s"Suspicious macro definition (use of ${SUSP_SYNS_CHARS.map(s => s"'$s'").mkString(", ")} chars) [" +
+ s"mdlId=${mdl.getId}, " +
+ s"macro=$makro" +
+ s"]")
}
/**
@@ -236,7 +246,7 @@
if (susp.nonEmpty)
logger.warn(
- s"Suspicious synonyms detected [" +
+ s"Suspicious synonyms detected (use of ${SUSP_SYNS_CHARS.map(s => s"'$s'").mkString(", ")} chars) [" +
s"mdlId=$mdlId, " +
s"elementId=$elmId, " +
s"synonyms=[${susp.mkString(", ")}]" +
@@ -1719,25 +1729,46 @@
if (intAnns.isEmpty && refAnns.isEmpty)
throw new NCE(s"@NCIntentSample or @NCIntentSampleRef annotations without corresponding @NCIntent or @NCIntentRef annotations: $mtdStr")
else {
- def read[T](arr: Array[T], annName: String, getValue: T => Seq[String]): Seq[Seq[String]] = {
- val seq = arr.toSeq.map(getValue).map(_.map(_.strip).filter(s => s.nonEmpty && s.head != '#'))
+ /**
+ *
+ * @param annArr
+ * @param annName
+ * @param getSamples
+ * @param getSource
+ * @tparam T
+ * @return
+ */
+ def read[T](
+ annArr: Array[T],
+ annName: String,
+ getSamples: T => Seq[String],
+ getSource: Option[T => String]): Seq[Seq[String]] = {
+ for (ann <- annArr.toSeq) yield {
+ val samples = getSamples(ann).map(_.strip).filter(s => s.nonEmpty && s.head != '#')
- if (seq.exists(_.isEmpty))
- logger.warn(s"$annName annotation has no samples: $mtdStr")
+ if (samples.isEmpty) {
+ getSource match {
+ case None => logger.warn(s"$annName annotation has no samples: $mtdStr")
+ case Some(f) => logger.warn(s"$annName annotation references '${f(ann)}' file that has no samples: $mtdStr")
+ }
- seq
- }
+ Seq.empty
+ }
+ else
+ samples
+ }
+ }.filter(_.nonEmpty)
val seqSeq =
read[NCIntentSample](
- smpAnns, "@NCIntentSample", _.value().toSeq
+ smpAnns, "@NCIntentSample", _.value().toSeq, None
) ++
read[NCIntentSampleRef](
- smpAnnsRef, "@NCIntentSampleRef", a => U.readAnySource(a.value())
+ smpAnnsRef, "@NCIntentSampleRef", a => U.readAnySource(a.value()), Some(_.value())
)
if (U.containsDups(seqSeq.flatMap(_.toSeq).toList))
- logger.warn(s"@NCIntentSample and @NCIntentSampleRef annotations have duplicates (safely ignoring): $mtdStr")
+ logger.warn(s"@NCIntentSample and @NCIntentSampleRef annotations have duplicates: $mtdStr")
val distinct = seqSeq.map(_.distinct).distinct