This is an automated email from the ASF dual-hosted git repository.
aradzinski pushed a commit to branch NLPCRAFT-281
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git
The following commit(s) were added to refs/heads/NLPCRAFT-281 by this push:
new da438d4 WIP.
da438d4 is described below
commit da438d47189c4b749fc8410b0fcdead1229bcc51
Author: Aaron Radzinski <[email protected]>
AuthorDate: Mon Mar 22 17:33:03 2021 -0700
WIP.
---
.../nlpcraft/model/intent/NCIdlContext.scala | 7 +-
...IdlTokenPredicate.scala => NCIdlFunction.scala} | 2 +-
.../nlpcraft/model/intent/NCIdlSynonym.scala | 4 +-
.../apache/nlpcraft/model/intent/NCIdlTerm.scala | 7 +-
.../model/intent/compiler/NCIdlCompiler.scala | 87 ++++++++++++++++------
.../model/intent/solver/NCIntentSolverEngine.scala | 4 +-
.../nlpcraft/probe/mgrs/NCProbeSynonymChunk.scala | 4 +-
7 files changed, 82 insertions(+), 33 deletions(-)
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/NCIdlContext.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/NCIdlContext.scala
index 1d09238..32fa895 100644
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/NCIdlContext.scala
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/NCIdlContext.scala
@@ -19,6 +19,9 @@ package org.apache.nlpcraft.model.intent
import org.apache.nlpcraft.common.ScalaMeta
import org.apache.nlpcraft.model.NCRequest
+import org.apache.nlpcraft.model.intent.compiler.NCIdlStackItem
+
+import scala.collection.mutable
/**
*
@@ -26,11 +29,13 @@ import org.apache.nlpcraft.model.NCRequest
* @param convMeta Conversation metadata.
* @param fragMeta Optional fragment (argument) metadata passed during intent
fragment reference.
* @param req Server request holder.
+ * @param vars Variable storage.
*/
case class NCIdlContext(
intentMeta: ScalaMeta = Map.empty[String, Object],
convMeta: ScalaMeta = Map.empty[String, Object],
fragMeta: ScalaMeta = Map.empty[String, Object],
- req: NCRequest
+ req: NCRequest,
+ vars: mutable.Map[String, NCIdlStackItem]
)
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/NCIdlTokenPredicate.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/NCIdlFunction.scala
similarity index 86%
rename from
nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/NCIdlTokenPredicate.scala
rename to
nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/NCIdlFunction.scala
index d585a8a..a876960 100644
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/NCIdlTokenPredicate.scala
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/NCIdlFunction.scala
@@ -22,4 +22,4 @@ import org.apache.nlpcraft.model.NCToken
/**
*
*/
-trait NCIdlTokenPredicate extends ((NCToken, NCIdlContext) ⇒ (Boolean /*
Predicate. */ , Int /* How many times a token was used. */ ))
+trait NCIdlFunction[T] extends ((NCToken, NCIdlContext) ⇒ (T , Int /* How many
times a token was used. */ ))
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/NCIdlSynonym.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/NCIdlSynonym.scala
index 4abe52a..c092801 100644
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/NCIdlSynonym.scala
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/NCIdlSynonym.scala
@@ -17,8 +17,6 @@
package org.apache.nlpcraft.model.intent
-import org.apache.nlpcraft.model.NCToken
-
/**
* DSl synonym.
*
@@ -28,7 +26,7 @@ import org.apache.nlpcraft.model.NCToken
case class NCIdlSynonym(
origin: String,
alias: Option[String],
- pred: NCIdlTokenPredicate,
+ pred: NCIdlFunction[Boolean],
) {
require(origin != null)
require(pred != null)
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/NCIdlTerm.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/NCIdlTerm.scala
index 5e24e8c..8d33c1a 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/NCIdlTerm.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/NCIdlTerm.scala
@@ -24,7 +24,8 @@ import org.apache.nlpcraft.common._
*
* @param idl
* @param id Optional ID of this term.
- * @param pred
+ * @param decls Term optional declarations.
+ * @param pred Term predicate.
* @param min
* @param max
* @param conv
@@ -33,7 +34,8 @@ import org.apache.nlpcraft.common._
case class NCIdlTerm(
idl: String,
id: Option[String],
- pred: NCIdlTokenPredicate,
+ decls: List[NCIdlFunction[Object]],
+ pred: NCIdlFunction[Boolean],
min: Int,
max: Int,
conv: Boolean,
@@ -51,6 +53,7 @@ case class NCIdlTerm(
NCIdlTerm(
idl,
id,
+ decls,
pred,
min,
max,
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 a49a71c..356288f 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
@@ -22,10 +22,10 @@ import org.antlr.v4.runtime.tree.ParseTreeWalker
import org.antlr.v4.runtime._
import org.antlr.v4.runtime.{ParserRuleContext ⇒ PRC}
import org.apache.nlpcraft.common._
-import org.apache.nlpcraft.model.intent.compiler.antlr4.{NCIdlBaseListener,
NCIdlLexer, NCIdlParser ⇒ IDP}
+import org.apache.nlpcraft.model.intent.compiler.antlr4.{NCIdlBaseListener,
NCIdlLexer, NCIdlParser, NCIdlParser ⇒ IDP}
import org.apache.nlpcraft.model.intent.compiler.{NCIdlCompilerGlobal ⇒ Global}
import org.apache.nlpcraft.model._
-import org.apache.nlpcraft.model.intent.{NCIdlContext, NCIdlIntent,
NCIdlSynonym, NCIdlTerm, NCIdlTokenPredicate}
+import org.apache.nlpcraft.model.intent.{NCIdlContext, NCIdlIntent,
NCIdlSynonym, NCIdlTerm, NCIdlFunction}
import java.io._
import java.net._
@@ -71,6 +71,7 @@ object NCIdlCompiler extends LazyLogging {
private val terms = ArrayBuffer.empty[NCIdlTerm]
// Currently term.
+ private var vars = mutable.HashMap.empty[String, NCIdlFunction[Object]]
private var termId: String = _
private var termConv: Boolean = _
private var min = 1
@@ -81,7 +82,7 @@ object NCIdlCompiler extends LazyLogging {
private var refMtdName: Option[String] = None
// List of instructions for the current expression.
- private var instrs = mutable.Buffer.empty[I]
+ private var expr = mutable.Buffer.empty[I]
/**
@@ -99,14 +100,14 @@ object NCIdlCompiler extends LazyLogging {
/*
* Shared/common implementation.
*/
- override def exitUnaryExpr(ctx: IDP.UnaryExprContext): Unit = instrs
+= parseUnaryExpr(ctx.MINUS(), ctx.NOT())(ctx)
- override def exitMultDivModExpr(ctx: IDP.MultDivModExprContext): Unit
= instrs += parseMultDivModExpr(ctx.MULT(), ctx.MOD(), ctx.DIV())(ctx)
- override def exitPlusMinusExpr(ctx: IDP.PlusMinusExprContext): Unit =
instrs += parsePlusMinusExpr(ctx.PLUS(), ctx.MINUS())(ctx)
- override def exitCompExpr(ctx: IDP.CompExprContext): Unit = instrs +=
parseCompExpr(ctx.LT(), ctx.GT(), ctx.LTEQ(), ctx.GTEQ())(ctx)
- override def exitAndOrExpr(ctx: IDP.AndOrExprContext): Unit = instrs
+= parseAndOrExpr(ctx.AND, ctx.OR())(ctx)
- override def exitEqNeqExpr(ctx: IDP.EqNeqExprContext): Unit = instrs
+= parseEqNeqExpr(ctx.EQ, ctx.NEQ())(ctx)
- override def exitCallExpr(ctx: IDP.CallExprContext): Unit = instrs +=
parseCallExpr(ctx.FUN_NAME())(ctx)
- override def exitAtom(ctx: IDP.AtomContext): Unit = instrs +=
parseAtom(ctx.getText)(ctx)
+ override def exitUnaryExpr(ctx: IDP.UnaryExprContext): Unit = expr +=
parseUnaryExpr(ctx.MINUS(), ctx.NOT())(ctx)
+ override def exitMultDivModExpr(ctx: IDP.MultDivModExprContext): Unit
= expr += parseMultDivModExpr(ctx.MULT(), ctx.MOD(), ctx.DIV())(ctx)
+ override def exitPlusMinusExpr(ctx: IDP.PlusMinusExprContext): Unit =
expr += parsePlusMinusExpr(ctx.PLUS(), ctx.MINUS())(ctx)
+ override def exitCompExpr(ctx: IDP.CompExprContext): Unit = expr +=
parseCompExpr(ctx.LT(), ctx.GT(), ctx.LTEQ(), ctx.GTEQ())(ctx)
+ override def exitAndOrExpr(ctx: IDP.AndOrExprContext): Unit = expr +=
parseAndOrExpr(ctx.AND, ctx.OR())(ctx)
+ override def exitEqNeqExpr(ctx: IDP.EqNeqExprContext): Unit = expr +=
parseEqNeqExpr(ctx.EQ, ctx.NEQ())(ctx)
+ override def exitCallExpr(ctx: IDP.CallExprContext): Unit = expr +=
parseCallExpr(ctx.FUN_NAME())(ctx)
+ override def exitAtom(ctx: IDP.AtomContext): Unit = expr +=
parseAtom(ctx.getText)(ctx)
override def exitTermEq(ctx: IDP.TermEqContext): Unit = termConv =
ctx.TILDA() != null
override def exitFragMeta(ctx: IDP.FragMetaContext): Unit = fragMeta =
U.jsonToScalaMap(ctx.jsonObj().getText)
override def exitMetaDecl(ctx: IDP.MetaDeclContext): Unit = intentMeta
= U.jsonToScalaMap(ctx.jsonObj().getText)
@@ -115,7 +116,7 @@ object NCIdlCompiler extends LazyLogging {
override def exitAlias(ctx: IDP.AliasContext): Unit = alias =
ctx.id().getText
override def enterCallExpr(ctx: IDP.CallExprContext): Unit =
- instrs += ((_, stack: NCIdlStack, _) ⇒
stack.push(stack.PLIST_MARKER))
+ expr += ((_, stack: NCIdlStack, _) ⇒
stack.push(stack.PLIST_MARKER))
/**
*
@@ -127,6 +128,34 @@ object NCIdlCompiler extends LazyLogging {
this.max = max
}
+ override def exitVarRef(ctx: NCIdlParser.VarRefContext): Unit = {
+
+ }
+
+ override def exitVarDecl(ctx: NCIdlParser.VarDeclContext): Unit = {
+ val varName = ctx.id().getText
+
+ if (vars.contains(varName))
+ throw newSyntaxError(s"Duplicate variable: $varName")(ctx)
+
+ vars += varName
+
+ val fun = exprToFunction[Object]("Variable declaration", _ ⇒ true,
x ⇒ x)(ctx)
+
+ val instr = (tok: NCToken, ctx: NCIdlContext) ⇒ {
+ val (res, tokUses) = fun(tok, ctx)
+
+ (null, 0)
+ }
+
+
+
+
+
+
+ expr.clear()
+ }
+
override def exitMinMaxShortcut(ctx: IDP.MinMaxShortcutContext): Unit
= {
if (ctx.PLUS() != null)
setMinMax(1, MINMAX_MAX)
@@ -178,9 +207,9 @@ object NCIdlCompiler extends LazyLogging {
override def exitSynonym(ctx: IDP.SynonymContext): Unit = {
implicit val evidence: PRC = ctx
- val pred = instrToPredicate("Synonym")
+ val pred = exprToFunction("Synonym", isBool, asBool)
val capture = alias
- val wrapper: NCIdlTokenPredicate = (tok: NCToken, ctx:
NCIdlContext) ⇒ {
+ val wrapper: NCIdlFunction[Boolean] = (tok: NCToken, ctx:
NCIdlContext) ⇒ {
val (res, tokUses) = pred(tok, ctx)
// Store predicate's alias, if any, in token metadata if this
token satisfies this predicate.
@@ -202,7 +231,7 @@ object NCIdlCompiler extends LazyLogging {
synonym = NCIdlSynonym(origin, Option(alias), wrapper)
alias = null
- instrs.clear()
+ expr.clear()
}
override def exitFragId(ctx: IDP.FragIdContext): Unit = {
@@ -254,7 +283,7 @@ object NCIdlCompiler extends LazyLogging {
if (max < 1)
throw newSyntaxError(s"Invalid intent term max quantifiers:
$max (must be max >= 1).")(ctx.minMax())
- val pred: NCIdlTokenPredicate = if (refMtdName.isDefined) { //
User-code defined term.
+ val pred: NCIdlFunction[Boolean] = if (refMtdName.isDefined) { //
User-code defined term.
// Closure copies.
val clsName = refClsName.orNull
val mtdName = refMtdName.orNull
@@ -289,7 +318,7 @@ object NCIdlCompiler extends LazyLogging {
}
}
else // IDL term.
- instrToPredicate("Intent term")(ctx.expr())
+ exprToFunction("Intent term", isBool, asBool)(ctx.expr())
// Add term.
terms += NCIdlTerm(
@@ -304,7 +333,8 @@ object NCIdlCompiler extends LazyLogging {
// Reset term vars.
setMinMax(1, 1)
termId = null
- instrs.clear()
+ expr.clear()
+ vars.clear()
refClsName = None
refMtdName = None
}
@@ -312,12 +342,23 @@ object NCIdlCompiler extends LazyLogging {
/**
*
* @param subj
+ * @param check
+ * @param cast
+ * @param ctx
+ * @tparam T
* @return
*/
- private def instrToPredicate(subj: String)(implicit ctx: PRC):
NCIdlTokenPredicate = {
+ private def exprToFunction[T](
+ subj: String,
+ check: Object ⇒ Boolean,
+ cast: Object ⇒ T
+ )
+ (
+ implicit ctx: PRC
+ ): NCIdlFunction[T] = {
val code = mutable.Buffer.empty[I]
- code ++= instrs
+ code ++= expr
(tok: NCToken, termCtx: NCIdlContext) ⇒ {
val stack = new S()
@@ -329,10 +370,10 @@ object NCIdlCompiler extends LazyLogging {
val x = stack.pop()()
val v = x.value
- if (!isBool(v))
- throw newRuntimeError(s"$subj did not return boolean
value: ${ctx.getText}")
+ if (!check(v))
+ throw newRuntimeError(s"$subj returned value of unexpected
type '$v' in: ${ctx.getText}")
- (asBool(v), x.tokUse)
+ (cast(v), x.tokUse)
}
}
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/solver/NCIntentSolverEngine.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/solver/NCIntentSolverEngine.scala
index 99f8576..6cd92b5 100644
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/solver/NCIntentSolverEngine.scala
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/solver/NCIntentSolverEngine.scala
@@ -26,6 +26,7 @@ import org.apache.nlpcraft.model.impl.NCTokenLogger
import org.apache.nlpcraft.model.{NCContext, NCDialogFlowItem, NCIntentMatch,
NCResult, NCToken}
import org.apache.nlpcraft.probe.mgrs.dialogflow.NCDialogFlowManager
import org.apache.nlpcraft.model.impl.NCTokenPimp._
+import org.apache.nlpcraft.model.intent.compiler.NCIdlStackItem
import org.apache.nlpcraft.model.intent.{NCIdlContext, NCIdlIntent, NCIdlTerm}
import java.util.function.Function
@@ -494,7 +495,8 @@ object NCIntentSolverEngine extends LazyLogging with
NCOpenCensusTrace {
val termCtx = NCIdlContext(
intentMeta = intent.meta,
convMeta = if (x.isEmpty) Map.empty[String, Object] else
x.asScala.toMap[String, Object],
- req = ctx.getRequest
+ req = ctx.getRequest,
+ vars = mutable.HashMap.empty[String, NCIdlStackItem]
)
// Check terms.
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCProbeSynonymChunk.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCProbeSynonymChunk.scala
index cefb16a..ebc1d8e 100644
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCProbeSynonymChunk.scala
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/probe/mgrs/NCProbeSynonymChunk.scala
@@ -17,7 +17,7 @@
package org.apache.nlpcraft.probe.mgrs
-import org.apache.nlpcraft.model.intent.NCIdlTokenPredicate
+import org.apache.nlpcraft.model.intent.NCIdlFunction
import org.apache.nlpcraft.probe.mgrs.NCProbeSynonymChunkKind._
import java.util.regex.Pattern
@@ -39,7 +39,7 @@ case class NCProbeSynonymChunk(
wordStem: String = null, // Only for kind == TEXT.
posTag: String = null,
regex: Pattern = null,
- idlPred: NCIdlTokenPredicate = null
+ idlPred: NCIdlFunction = null
) {
require(origText != null)
require(kind != null)