This is an automated email from the ASF dual-hosted git repository.
aradzinski pushed a commit to branch NLPCRAFT-206
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git
The following commit(s) were added to refs/heads/NLPCRAFT-206 by this push:
new 14fb39a WIP.
14fb39a is described below
commit 14fb39a7d86ab6a7348ab2f734ac73340b124820
Author: Aaron Radzinski <[email protected]>
AuthorDate: Fri Mar 12 16:48:30 2021 -0800
WIP.
---
.../apache/nlpcraft/examples/alarm/AlarmModel.java | 8 ++
.../org/apache/nlpcraft/examples/alarm/intents.nc | 15 ++-
.../scala/org/apache/nlpcraft/model/NCIntent.java | 19 ++-
.../org/apache/nlpcraft/model/NCIntentRef.java | 21 +++-
.../org/apache/nlpcraft/model/NCIntentSample.java | 1 +
.../model/intent/compiler/NCDslCompiler.scala | 128 +++++++++++++--------
.../intent/compiler/NCDslCompilerGlobal.scala | 27 ++++-
.../probe/mgrs/deploy/NCDeployManager.scala | 8 +-
8 files changed, 167 insertions(+), 60 deletions(-)
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/examples/alarm/AlarmModel.java
b/nlpcraft/src/main/scala/org/apache/nlpcraft/examples/alarm/AlarmModel.java
index 2fcfb91..c741885 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/examples/alarm/AlarmModel.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/examples/alarm/AlarmModel.java
@@ -45,6 +45,14 @@ public class AlarmModel extends NCModelFileAdapter {
super("org/apache/nlpcraft/examples/alarm/alarm_model.json");
}
+ @NCIntent("intent=i11 term={true}")
+ @NCIntent("intent=i12 term={true}")
+ NCResult cb1(NCIntentMatch ctx) { return NCResult.text(""); }
+
+ @NCIntent("intent=i21 term={true}")
+ @NCIntent("intent=i22 term={true}")
+ NCResult cb2(NCIntentMatch ctx) { return NCResult.text(""); }
+
/**
* Callback on intent match.
*
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/examples/alarm/intents.nc
b/nlpcraft/src/main/scala/org/apache/nlpcraft/examples/alarm/intents.nc
index ccbfedb..875210a 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/examples/alarm/intents.nc
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/examples/alarm/intents.nc
@@ -15,11 +15,16 @@
* limitations under the License.
*/
- // Fragments.
- fragment=buzz term~{id() == 'x:alarm'}
- fragment=when term(nums)~{id() == 'nlpcraft:num' &&
meta_token('nlpcraft:num:unittype') == 'datetime' &&
meta_token('nlpcraft:num:isequalcondition') == true}[0,7]
+// Fragments.
+fragment=buzz term~{id() == 'x:alarm'}
+fragment=when
+ term(nums)~{
+ id() == 'nlpcraft:num' &&
+ meta_token('nlpcraft:num:unittype') == 'datetime' &&
+ meta_token('nlpcraft:num:isequalcondition') == true
+ }[0,7]
- // Intents
- intent=alarm
+// Intents
+intent=alarm
fragment(buzz)
fragment(when)
\ No newline at end of file
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/NCIntent.java
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/NCIntent.java
index a984275..898be67 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/NCIntent.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/NCIntent.java
@@ -38,7 +38,8 @@ import static java.lang.annotation.RetentionPolicy.*;
*/
@Documented
@Retention(value=RUNTIME)
-@Target(value=METHOD)
+@Target(value={METHOD, TYPE})
+@Repeatable(NCIntent.NCIntentList.class)
public @interface NCIntent {
/**
* Intent specification using intent DSL.
@@ -46,4 +47,20 @@ public @interface NCIntent {
* @return Intent specification using intent DSL.
*/
String value() default "";
+
+ /**
+ * Grouping annotation required for when more than one {@link NCIntent}
annotation is attached to the
+ * callback or class.
+ */
+ @Retention(RetentionPolicy.RUNTIME)
+ @Documented
+ @Target(value={METHOD, TYPE})
+ @interface NCIntentList {
+ /**
+ * Gets the list of all {@link NCIntent} annotations attached to the
callback or class.
+ *
+ * @return List of all {@link NCIntent} annotations attached to the
callback or class.
+ */
+ NCIntent[] value();
+ }
}
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/NCIntentRef.java
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/NCIntentRef.java
index 0ffd06c..cc0952a 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/NCIntentRef.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/NCIntentRef.java
@@ -17,9 +17,7 @@
package org.apache.nlpcraft.model;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
+import java.lang.annotation.*;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@@ -40,6 +38,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Documented
@Retention(value=RUNTIME)
@Target(value=METHOD)
+@Repeatable(NCIntentRef.NCIntentRefList.class)
public @interface NCIntentRef {
/**
* ID of the intent defined externally.
@@ -47,4 +46,20 @@ public @interface NCIntentRef {
* @return ID of the intent defined externally.
*/
String value() default "";
+
+ /**
+ * Grouping annotation required for when more than one {@link NCIntentRef}
annotation is attached to the
+ * callback.
+ */
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(value=METHOD)
+ @Documented
+ @interface NCIntentRefList {
+ /**
+ * Gets the list of all {@link NCIntentRef} annotations attached to
the callback.
+ *
+ * @return List of all {@link NCIntentRef} annotations attached to the
callback.
+ */
+ NCIntentRef[] value();
+ }
}
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/NCIntentSample.java
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/NCIntentSample.java
index 6f48bb0..4211f45 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/NCIntentSample.java
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/NCIntentSample.java
@@ -86,6 +86,7 @@ public @interface NCIntentSample {
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(value=METHOD)
+ @Documented
@interface NCIntentSampleList {
/**
* Gets the list of all {@link NCIntentSample} annotations attached to
the callback.
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslCompiler.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslCompiler.scala
index e668bd0..ec0f86e 100644
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslCompiler.scala
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslCompiler.scala
@@ -80,6 +80,19 @@ object NCDslCompiler extends LazyLogging {
// Current expression code, i.e. list of instructions.
private var instrs = mutable.Buffer.empty[Instr]
+
+ /**
+ *
+ * @return
+ */
+ def getCompiledIntents: Set[NCDslIntent] = intents.toSet
+
+ /**
+ *
+ * @return
+ */
+ def getCompiledSynonym: NCDslSynonym = synonym
+
/*
* Shared/common implementation.
*/
@@ -330,43 +343,50 @@ object NCDslCompiler extends LazyLogging {
override def exitImp(ctx: IDP.ImpContext): Unit = {
val x = U.trimQuotes(ctx.qstring().getText)
- var imports: Set[NCDslIntent] = null
- val file = new File(x)
+ if (Global.hasImport(x))
+ logger.warn(s"Ignoring already processed DSL import '$x' in:
$origin")
+ else {
+ Global.addImport(x)
- if (file.exists())
- imports = NCDslCompiler.compileIntents(
- U.readFile(file).mkString("\n"),
- mdl,
- x
- )
+ var imports: Set[NCDslIntent] = null
- if (imports == null) {
- val in = mdl.getClass.getClassLoader.getResourceAsStream(x)
+ val file = new File(x)
- if (in != null)
+ if (file.exists())
imports = NCDslCompiler.compileIntents(
- U.readStream(in).mkString("\n"),
+ U.readFile(file).mkString("\n"),
mdl,
x
)
- }
- if (imports == null) {
- try
- imports = NCDslCompiler.compileIntents(
- U.readStream(new URL(x).openStream()).mkString("\n"),
- mdl,
- x
- )
- catch {
- case _: Exception ⇒ throw newSyntaxError(s"Invalid or
unknown import location: $x")(ctx.qstring())
+ if (imports == null) {
+ val in = mdl.getClass.getClassLoader.getResourceAsStream(x)
+
+ if (in != null)
+ imports = NCDslCompiler.compileIntents(
+ U.readStream(in).mkString("\n"),
+ mdl,
+ x
+ )
+ }
+
+ if (imports == null) {
+ try
+ imports = NCDslCompiler.compileIntents(
+ U.readStream(new
URL(x).openStream()).mkString("\n"),
+ mdl,
+ x
+ )
+ catch {
+ case _: Exception ⇒ throw newSyntaxError(s"Invalid or
unknown import location: $x")(ctx.qstring())
+ }
}
- }
- require(imports != null)
+ require(imports != null)
- imports.foreach(addIntent(_)(ctx.qstring()))
+ imports.foreach(addIntent(_)(ctx.qstring()))
+ }
}
override def exitIntent(ctx: IDP.IntentContext): Unit = {
@@ -390,31 +410,21 @@ object NCDslCompiler extends LazyLogging {
terms.clear()
}
- /**
- *
- * @return
- */
- def getCompiledIntents: Set[NCDslIntent] = intents.toSet
-
- /**
- *
- * @return
- */
- def getCompiledSynonym: NCDslSynonym = synonym
-
override def syntaxError(errMsg: String, srcName: String, line: Int,
pos: Int): NCE =
- throw new NCE(mkSyntaxError(errMsg, srcName, line, pos, dsl, mdl))
+ throw new NCE(mkSyntaxError(errMsg, srcName, line, pos, dsl,
origin, mdl))
override def runtimeError(errMsg: String, srcName: String, line: Int,
pos: Int, cause: Exception = null): NCE =
- throw new NCE(mkRuntimeError(errMsg, srcName, line, pos, dsl,
mdl), cause)
+ throw new NCE(mkRuntimeError(errMsg, srcName, line, pos, dsl,
origin, mdl), cause)
}
/**
*
* @param msg
+ * @param srcName
* @param line
* @param charPos
- * @param dsl Original DSL text (input).
+ * @param dsl
+ * @param origin DSL origin.
* @param mdl
* @return
*/
@@ -424,16 +434,18 @@ object NCDslCompiler extends LazyLogging {
line: Int, // 1, 2, ...
charPos: Int, // 0, 1, 2, ...
dsl: String,
- mdl: NCModel): String = mkError("syntax", msg, srcName, line, charPos,
dsl, mdl)
+ origin: String,
+ mdl: NCModel): String = mkError("syntax", msg, srcName, line, charPos,
dsl, origin, mdl)
/**
*
* @param msg
- * @param dsl
- * @param mdl
* @param srcName
* @param line
* @param charPos
+ * @param dsl
+ * @param origin DSL origin.
+ * @param mdl
* @return
*/
private def mkRuntimeError(
@@ -442,8 +454,21 @@ object NCDslCompiler extends LazyLogging {
line: Int, // 1, 2, ...
charPos: Int, // 0, 1, 2, ...
dsl: String,
- mdl: NCModel): String = mkError("runtime", msg, srcName, line,
charPos, dsl, mdl)
+ origin: String,
+ mdl: NCModel): String = mkError("runtime", msg, srcName, line,
charPos, dsl, origin, mdl)
+ /**
+ *
+ * @param kind
+ * @param msg
+ * @param srcName
+ * @param line
+ * @param charPos
+ * @param dsl
+ * @param origin DSL origin.
+ * @param mdl
+ * @return
+ */
private def mkError(
kind: String,
msg: String,
@@ -451,6 +476,7 @@ object NCDslCompiler extends LazyLogging {
line: Int,
charPos: Int,
dsl: String,
+ origin: String,
mdl: NCModel): String = {
val dslLine = dsl.split("\n")(line - 1)
val dash = "-" * dslLine.length
@@ -463,7 +489,10 @@ object NCDslCompiler extends LazyLogging {
}
s"DSL $kind error in '$srcName' at line $line:${charPos + 1} -
$aMsg\n" +
- s" |-- ${c("Model ID:")} ${mdl.getId} $C<-$RST
$W${mdl.getOrigin}$RST\n" +
+ s" |-- ${c("Model ID:")} ${mdl.getId}\n" +
+ s" |-- ${c("Model origin:")} ${mdl.getOrigin}\n" +
+ s" |-- ${c("Intent origin:")} $origin\n" +
+ s" |-- $RST$W--------------$RST\n" +
s" |-- ${c("Line:")} $dslPtr\n" +
s" +-- ${c("Position:")} $posPtr"
}
@@ -473,8 +502,9 @@ object NCDslCompiler extends LazyLogging {
*
* @param dsl
* @param mdl
+ * @param origin DSL origin.
*/
- class CompilerErrorListener(dsl: String, mdl: NCModel) extends
BaseErrorListener {
+ class CompilerErrorListener(dsl: String, mdl: NCModel, origin: String)
extends BaseErrorListener {
/**
*
* @param recog
@@ -491,7 +521,7 @@ object NCDslCompiler extends LazyLogging {
charPos: Int, // 1, 2, ...
msg: String,
e: RecognitionException): Unit =
- throw new NCE(mkSyntaxError(msg,
recog.getInputStream.getSourceName, line, charPos - 1, dsl, mdl))
+ throw new NCE(mkSyntaxError(msg,
recog.getInputStream.getSourceName, line, charPos - 1, dsl, origin, mdl))
}
/**
@@ -573,8 +603,8 @@ object NCDslCompiler extends LazyLogging {
// Set custom error handlers.
lexer.removeErrorListeners()
parser.removeErrorListeners()
- lexer.addErrorListener(new CompilerErrorListener(dsl, mdl))
- parser.addErrorListener(new CompilerErrorListener(dsl, mdl))
+ lexer.addErrorListener(new CompilerErrorListener(dsl, mdl, origin))
+ parser.addErrorListener(new CompilerErrorListener(dsl, mdl, origin))
// State automata + it's parser.
new FiniteStateMachine(origin, dsl, mdl) → parser
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslCompilerGlobal.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslCompilerGlobal.scala
index b2dcfe8..4e2e9b9 100644
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslCompilerGlobal.scala
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/compiler/NCDslCompilerGlobal.scala
@@ -25,11 +25,23 @@ import scala.collection.mutable
*/
object NCDslCompilerGlobal {
private final val fragCache = TrieMap.empty[String /* Model ID. */ ,
mutable.Map[String, NCDslFragment]]
+ private final val importCache = mutable.HashSet.empty[String]
/**
*
*/
- def clearCache(): Unit = fragCache.clear()
+ def clearAllCaches(): Unit = {
+ fragCache.clear()
+ clearImportCache()
+ }
+
+ /**
+ *
+ */
+ private def clearImportCache(): Unit =
+ importCache.synchronized {
+ importCache.clear
+ }
/**
*
@@ -39,6 +51,19 @@ object NCDslCompilerGlobal {
/**
*
+ * @param imp
+ */
+ def addImport(imp: String): Unit = importCache.synchronized { importCache
+= imp }
+
+ /**
+ *
+ * @param imp
+ * @return
+ */
+ def hasImport(imp: String): Boolean = importCache.synchronized {
importCache.contains(imp) }
+
+ /**
+ *
* @param mdlId
* @param frag
*/
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 bed13a6..cbea98c 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
@@ -1082,6 +1082,7 @@ object NCDeployManager extends NCService with
DecorateAsScala {
if (mtd.getReturnType != CLS_QRY_RES)
throw new NCE(s"Unexpected result type for @NCIntent annotated
method [" +
s"mdlId=$mdlId, " +
+ s"intentId=${intent.id}, " +
s"type=${class2Str(mtd.getReturnType)}, " +
s"callback=${method2Str(mtd)}" +
s"]")
@@ -1106,6 +1107,7 @@ object NCDeployManager extends NCService with
DecorateAsScala {
if (tokParamAnns.length != tokParamTypes.length)
throw new NCE(s"Unexpected annotations count for @NCIntent
annotated method [" +
s"mdlId=$mdlId, " +
+ s"intentId=${intent.id}, " +
s"count=${tokParamAnns.size}, " +
s"callback=${method2Str(mtd)}" +
s"]")
@@ -1124,12 +1126,14 @@ object NCDeployManager extends NCService with
DecorateAsScala {
case 0 ⇒
throw new NCE(s"Missing @NCIntentTerm annotation for
[" +
s"mdlId=$mdlId, " +
+ s"intentId=${intent.id}, " +
s"arg=${mkArg()}" +
s"]")
case _ ⇒
throw new NCE(s"Too many @NCIntentTerm annotations for
[" +
s"mdlId=$mdlId, " +
+ s"intentId=${intent.id}, " +
s"arg=${mkArg()}" +
s"]")
}
@@ -1138,6 +1142,7 @@ object NCDeployManager extends NCService with
DecorateAsScala {
if (U.containsDups(termIds))
throw new NCE(s"Duplicate term IDs in @NCIntentTerm annotations ["
+
s"mdlId=$mdlId, " +
+ s"intentId=${intent.id}, " +
s"dups=${U.getDups(termIds).mkString(", ")}, " +
s"callback=${method2Str(mtd)}" +
s"]")
@@ -1153,7 +1158,8 @@ object NCDeployManager extends NCService with
DecorateAsScala {
// Report only the first one for simplicity & clarity.
throw new NCE(s"Unknown term ID in @NCIntentTerm annotation [" +
s"mdlId=$mdlId, " +
- s"id='${invalidIds.head}', " +
+ s"intentId=${intent.id}, " +
+ s"termId=${invalidIds.head}, " +
s"callback=${method2Str(mtd)}" +
s"]")
}