You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nlpcraft.apache.org by ar...@apache.org on 2021/03/09 17:43:49 UTC
[incubator-nlpcraft] 01/02: WIP.
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
commit 67255ef6c46eea3a6791fed18c3b5f6c333d769a
Author: Aaron Radzinski <ar...@apache.org>
AuthorDate: Mon Mar 8 16:42:01 2021 -0800
WIP.
---
.../intent/impl/NCIntentDslBaselCompiler.scala | 171 +++++-----------
.../model/intent/impl/NCIntentDslCompiler.scala | 224 ++++++++++++++-------
.../probe/mgrs/deploy/NCDeployManager.scala | 6 +-
.../dsl/compiler/NCIntentDslCompilerSpec.scala | 6 +-
4 files changed, 209 insertions(+), 198 deletions(-)
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentDslBaselCompiler.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentDslBaselCompiler.scala
index 0011b26..f31286e 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentDslBaselCompiler.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentDslBaselCompiler.scala
@@ -419,20 +419,6 @@ trait NCIntentDslBaselCompiler {
pop1()
}
- /*
- * String operations.
- */
- def doTrim(): Unit = get1Str() match { case (s, f) ⇒ pushAny(s.trim, f) }
- def doUppercase(): Unit = get1Str() match { case (s, f) ⇒ pushAny(s.toUpperCase, f) }
- def doLowercase(): Unit = get1Str() match { case (s, f) ⇒ pushAny(s.toLowerCase, f) }
- def doIsAlpha(): Unit = get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlpha(asString(s)), f) }
- def doIsNum(): Unit = get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isNumeric(asString(s)), f) }
- def doIsAlphaNum(): Unit = get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlphanumeric(asString(s)), f) }
- def doIsWhitespace(): Unit = get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isWhitespace(asString(s)), f) }
- def doIsAlphaSpace(): Unit = get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlphaSpace(asString(s)), f) }
- def doIsAlphaNumSpace(): Unit = get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlphanumericSpace(asString(s)), f) }
- def doIsNumSpace(): Unit = get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isNumericSpace(asString(s)), f) }
-
def doSplit(): Unit = {
ensureStack(2)
@@ -502,15 +488,6 @@ trait NCIntentDslBaselCompiler {
/*
* Metadata operations.
*/
- def doTokenMeta(): Unit = get1Str() match { case (s, _) ⇒ pushAny(tok.meta(s), true) }
- def doModelMeta(): Unit = get1Str() match { case (s, _) ⇒ pushAny(tok.getModel.meta(s), false) }
- def doReqMeta(): Unit = get1Str() match { case (s, _) ⇒ pushAny(termCtx.reqMeta.get(s).orNull, false) }
- def doSysMeta(): Unit = get1Str() match { case (s, _) ⇒ pushAny(U.sysEnv(s).orNull, false) }
- def doUserMeta(): Unit = get1Str() match { case (s, _) ⇒ pushAny(termCtx.usrMeta.get(s).orNull, false) }
- def doConvMeta(): Unit = get1Str() match { case (s, _) ⇒ pushAny(termCtx.convMeta.get(s).orNull, false) }
- def doCompMeta(): Unit = get1Str() match { case (s, _) ⇒ pushAny(termCtx.compMeta.get(s).orNull, false) }
- def doIntentMeta(): Unit = get1Str() match { case (s, _) ⇒ pushAny(termCtx.intentMeta.get(s).orNull, false) }
- def doFragMeta(): Unit = get1Str() match { case (s, _) ⇒ pushAny(termCtx.fragMeta.get(s).orNull, false) }
def doPartMeta(): Unit = {
ensureStack(2)
@@ -537,44 +514,6 @@ trait NCIntentDslBaselCompiler {
case (a: JDouble, f) ⇒ pushDouble(a * a, f)
case x ⇒ throw rtParamTypeError(fun, x, "numeric")
}
- def doCeil(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.ceil(a), f) }
- def doFloor(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.floor(a), f) }
- def doSignum(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.signum(a), f) }
- def doAcos(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.acos(a), f) }
- def doAsin(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.asin(a), f) }
- def doSin(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.sin(a), f) }
- def doCos(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.cos(a), f) }
- def doRint(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.rint(a), f) }
- def doRound(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushLong(Math.round(a), f) }
- def doSqrt(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.sqrt(a), f) }
- def doCbrt(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.cbrt(a), f) }
- def doAtan(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.atan(a), f) }
- def doTan(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.tan(a), f) }
- def doCosh(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.cosh(a), f) }
- def doSinh(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.sinh(a), f) }
- def doTanh(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.tanh(a), f) }
- def doLog(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.log(a), f) }
- def doLog1p(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.log1p(a), f) }
- def doLog10(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.log10(a), f) }
- def doDegrees(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.toDegrees(a), f) }
- def doRadians(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.toRadians(a), f) }
- def doExp(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.exp(a), f) }
- def doExpm1(): Unit = get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.expm1(a), f) }
- def doRandom(): Unit = pushDouble(Math.random, false)
- def doPi(): Unit = pushDouble(Math.PI, false)
- def doEuler(): Unit = pushDouble(Math.E, false)
- def doPow(): Unit = get2Doubles() match { case (a1: JDouble, a2: JDouble, f) ⇒ pushDouble(Math.pow(a1, a2), f) }
- def doHypot(): Unit = get2Doubles() match { case (a1: JDouble, a2: JDouble, f) ⇒ pushDouble(Math.hypot(a1, a2), f) }
- def doAtan2(): Unit = get2Doubles() match { case (a1: JDouble, a2: JDouble, f) ⇒ pushDouble(Math.atan2(a1, a2), f) }
-
- /*
- * Date-time operations.
- */
- def doYear(): Unit = pushLong(LocalDate.now.getYear,false)
- def doMonth(): Unit = pushLong(LocalDate.now.getMonthValue,false)
- def doDayOfMonth(): Unit = pushLong(LocalDate.now.getDayOfMonth,false)
- def doDayOfWeek(): Unit = pushLong(LocalDate.now.getDayOfWeek.getValue,false)
- def doDayOfYear(): Unit = pushLong(LocalDate.now.getDayOfYear,false)
def doJson(): Unit = get1Str() match { case (s, f) ⇒ pushAny(U.jsonToJavaMap(asString(s)), f) }
def doIf(): Unit = {
@@ -638,16 +577,16 @@ trait NCIntentDslBaselCompiler {
fun match {
// Metadata access.
- case "meta_token" ⇒ doTokenMeta()
case "meta_part" ⇒ doPartMeta()
- case "meta_model" ⇒ doModelMeta()
- case "meta_intent" ⇒ doIntentMeta()
- case "meta_req" ⇒ doReqMeta()
- case "meta_user" ⇒ doUserMeta()
- case "meta_company" ⇒ doCompMeta()
- case "meta_sys" ⇒ doSysMeta()
- case "meta_conv" ⇒ doConvMeta()
- case "meta_frag" ⇒ doFragMeta()
+ case "meta_token" ⇒ get1Str() match { case (s, _) ⇒ pushAny(tok.meta(s), true) }
+ case "meta_model" ⇒ get1Str() match { case (s, _) ⇒ pushAny(tok.getModel.meta(s), false) }
+ case "meta_intent" ⇒ get1Str() match { case (s, _) ⇒ pushAny(termCtx.intentMeta.get(s).orNull, false) }
+ case "meta_req" ⇒ get1Str() match { case (s, _) ⇒ pushAny(termCtx.reqMeta.get(s).orNull, false) }
+ case "meta_user" ⇒ get1Str() match { case (s, _) ⇒ pushAny(termCtx.usrMeta.get(s).orNull, false) }
+ case "meta_company" ⇒ get1Str() match { case (s, _) ⇒ pushAny(termCtx.compMeta.get(s).orNull, false) }
+ case "meta_sys" ⇒ get1Str() match { case (s, _) ⇒ pushAny(U.sysEnv(s).orNull, false) }
+ case "meta_conv" ⇒ get1Str() match { case (s, _) ⇒ pushAny(termCtx.convMeta.get(s).orNull, false) }
+ case "meta_frag" ⇒ get1Str() match { case (s, _) ⇒ pushAny(termCtx.fragMeta.get(s).orNull, false) }
// Converts JSON to map.
case "json" ⇒ doJson()
@@ -694,17 +633,17 @@ trait NCIntentDslBaselCompiler {
case "comp_postcode" ⇒
// String functions.
- case "trim" ⇒ doTrim()
- case "strip" ⇒ doTrim()
- case "uppercase" ⇒ doUppercase()
- case "lowercase" ⇒ doLowercase()
- case "is_alpha" ⇒ doIsAlpha()
- case "is_alphanum" ⇒ doIsAlphaNum()
- case "is_whitespace" ⇒ doIsWhitespace()
- case "is_num" ⇒ doIsNum()
- case "is_numspace" ⇒ doIsNumSpace()
- case "is_alphaspace" ⇒ doIsAlphaSpace()
- case "is_alphanumspace" ⇒ doIsAlphaNumSpace()
+ case "trim" ⇒ get1Str() match { case (s, f) ⇒ pushAny(s.trim, f) }
+ case "strip" ⇒ get1Str() match { case (s, f) ⇒ pushAny(s.trim, f) }
+ case "uppercase" ⇒ get1Str() match { case (s, f) ⇒ pushAny(s.toUpperCase, f) }
+ case "lowercase" ⇒ get1Str() match { case (s, f) ⇒ pushAny(s.toLowerCase, f) }
+ case "is_alpha" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlpha(asString(s)), f) }
+ case "is_alphanum" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlphanumeric(asString(s)), f) }
+ case "is_whitespace" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isWhitespace(asString(s)), f) }
+ case "is_num" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isNumeric(asString(s)), f) }
+ case "is_numspace" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isNumericSpace(asString(s)), f) }
+ case "is_alphaspace" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlphaSpace(asString(s)), f) }
+ case "is_alphanumspace" ⇒ get1Str() match { case (s, f) ⇒ pushBool(StringUtils.isAlphanumericSpace(asString(s)), f) }
case "substring" ⇒
case "charAt" ⇒
case "regex" ⇒
@@ -715,35 +654,35 @@ trait NCIntentDslBaselCompiler {
// Math functions.
case "abs" ⇒ doAbs()
- case "ceil" ⇒ doCeil()
- case "floor" ⇒ doFloor()
- case "rint" ⇒ doRint()
- case "round" ⇒ doRound()
- case "signum" ⇒ doSignum()
- case "sqrt" ⇒ doSqrt()
- case "cbrt" ⇒ doCbrt()
- case "pi" ⇒ doPi()
- case "euler" ⇒ doEuler()
- case "acos" ⇒ doAcos()
- case "asin" ⇒ doAsin()
- case "atan" ⇒ doAtan()
- case "cos" ⇒ doCos()
- case "sin" ⇒ doSin()
- case "tan" ⇒ doTan()
- case "cosh" ⇒ doCosh()
- case "sinh" ⇒ doSinh()
- case "tanh" ⇒ doTanh()
- case "atn2" ⇒ doAtan2()
- case "degrees" ⇒ doDegrees()
- case "radians" ⇒ doRadians()
- case "exp" ⇒ doExp()
- case "expm1" ⇒ doExpm1()
- case "hypot" ⇒ doHypot()
- case "log" ⇒ doLog()
- case "log10" ⇒ doLog10()
- case "log1p" ⇒ doLog1p()
- case "pow" ⇒ doPow()
- case "rand" ⇒ doRandom()
+ case "ceil" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.ceil(a), f) }
+ case "floor" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.floor(a), f) }
+ case "rint" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.rint(a), f) }
+ case "round" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushLong(Math.round(a), f) }
+ case "signum" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.signum(a), f) }
+ case "sqrt" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.sqrt(a), f) }
+ case "cbrt" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.cbrt(a), f) }
+ case "pi" ⇒ pushDouble(Math.PI, false)
+ case "euler" ⇒ pushDouble(Math.E, false)
+ case "acos" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.acos(a), f) }
+ case "asin" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.asin(a), f) }
+ case "atan" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.atan(a), f) }
+ case "cos" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.cos(a), f) }
+ case "sin" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.sin(a), f) }
+ case "tan" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.tan(a), f) }
+ case "cosh" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.cosh(a), f) }
+ case "sinh" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.sinh(a), f) }
+ case "tanh" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.tanh(a), f) }
+ case "atn2" ⇒ get2Doubles() match { case (a1: JDouble, a2: JDouble, f) ⇒ pushDouble(Math.atan2(a1, a2), f) }
+ case "degrees" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.toDegrees(a), f) }
+ case "radians" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.toRadians(a), f) }
+ case "exp" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.exp(a), f) }
+ case "expm1" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.expm1(a), f) }
+ case "hypot" ⇒ get2Doubles() match { case (a1: JDouble, a2: JDouble, f) ⇒ pushDouble(Math.hypot(a1, a2), f) }
+ case "log" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.log(a), f) }
+ case "log10" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.log10(a), f) }
+ case "log1p" ⇒ get1Double() match { case (a: JDouble, f) ⇒ pushDouble(Math.log1p(a), f) }
+ case "pow" ⇒ get2Doubles() match { case (a1: JDouble, a2: JDouble, f) ⇒ pushDouble(Math.pow(a1, a2), f) }
+ case "rand" ⇒ pushDouble(Math.random, false)
case "square" ⇒ doSquare()
// Collection functions.
@@ -777,18 +716,18 @@ trait NCIntentDslBaselCompiler {
case "sum" ⇒
// Date-time functions.
- case "year" ⇒ doYear() // 2021.
- case "month" ⇒ doMonth() // 1 ... 12.
- case "day_of_month" ⇒ doDayOfMonth() // 1 ... 31.
- case "day_of_week" ⇒ doDayOfWeek()
- case "day_of_year" ⇒ doDayOfYear()
+ case "year" ⇒ pushLong(LocalDate.now.getYear,false) // 2021.
+ case "month" ⇒ pushLong(LocalDate.now.getMonthValue,false) // 1 ... 12.
+ case "day_of_month" ⇒ pushLong(LocalDate.now.getDayOfMonth,false) // 1 ... 31.
+ case "day_of_week" ⇒ pushLong(LocalDate.now.getDayOfWeek.getValue,false)
+ case "day_of_year" ⇒ pushLong(LocalDate.now.getDayOfYear,false)
case "hour" ⇒
case "minute" ⇒
case "second" ⇒
case "week_of_month" ⇒
case "week_of_year" ⇒
case "quarter" ⇒
- case "now" ⇒ // Epoc time.
+ case "now" ⇒ pushLong(System.currentTimeMillis(),false) // Epoc time.
case _ ⇒ throw rtUnknownFunError(fun) // Assertion.
}
diff --git a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentDslCompiler.scala b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentDslCompiler.scala
index 1fdbd57..691af29 100644
--- a/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentDslCompiler.scala
+++ b/nlpcraft/src/main/scala/org/apache/nlpcraft/model/intent/impl/NCIntentDslCompiler.scala
@@ -34,8 +34,9 @@ import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer
object NCIntentDslCompiler extends LazyLogging {
- // Compiler cache.
- private val cache = new mutable.HashMap[String, Set[NCDslIntent]]
+ // Compiler caches.
+ private val intentCache = new mutable.HashMap[String, Set[NCDslIntent]]
+ private val synCache = new mutable.HashMap[String, NCDslSynonym]
/**
*
@@ -76,12 +77,19 @@ object NCIntentDslCompiler extends LazyLogging {
* Shared/common implementation.
*/
override def exitUnaryExpr(ctx: IDP.UnaryExprContext): Unit = termInstrs += parseUnaryExpr(ctx.MINUS(), ctx.NOT())(ctx)
+
override def exitMultExpr(ctx: IDP.MultExprContext): Unit = termInstrs += parseMultExpr(ctx.MULT(), ctx.MOD(), ctx.DIV())(ctx)
+
override def exitPlusExpr(ctx: IDP.PlusExprContext): Unit = termInstrs += parsePlusExpr(ctx.PLUS(), ctx.MINUS())(ctx)
+
override def exitCompExpr(ctx: IDP.CompExprContext): Unit = termInstrs += parseCompExpr(ctx.LT(), ctx.GT(), ctx.LTEQ(), ctx.GTEQ())(ctx)
+
override def exitLogExpr(ctx: IDP.LogExprContext): Unit = termInstrs += parseLogExpr(ctx.AND, ctx.OR())(ctx)
+
override def exitEqExpr(ctx: IDP.EqExprContext): Unit = termInstrs += parseEqExpr(ctx.EQ, ctx.NEQ())(ctx)
+
override def exitCallExpr(ctx: IDP.CallExprContext): Unit = termInstrs += parseCallExpr(ctx.FUN_NAME())(ctx)
+
override def exitAtom(ctx: IDP.AtomContext): Unit = termInstrs += parseAtom(ctx.getText)(ctx)
/**
@@ -104,11 +112,11 @@ object NCIntentDslCompiler extends LazyLogging {
else
assert(false)
}
-
+
override def exitMinMaxRange(ctx: IDP.MinMaxRangeContext): Unit = {
val minStr = ctx.getChild(1).getText.trim
val maxStr = ctx.getChild(3).getText.trim
-
+
try
setMinMax(java.lang.Integer.parseInt(minStr), java.lang.Integer.parseInt(maxStr))
catch {
@@ -126,28 +134,31 @@ object NCIntentDslCompiler extends LazyLogging {
override def exitTermId(ctx: IDP.TermIdContext): Unit = {
termId = ctx.id().getText
-
+
if (terms.exists(t ⇒ t.id === termId))
- throw newSyntaxError(s"Duplicate term ID: $termId")(ctx.id())
+ throw newSyntaxError(s"Duplicate intent term ID: $termId")(ctx.id())
}
-
+
override def exitIntentId(ctx: IDP.IntentIdContext): Unit = {
intentId = ctx.id().getText
-
+
if (intents.exists(i ⇒ i.id != null && i.id == intentId))
throw newSyntaxError(s"Duplicate intent ID: $intentId")(ctx.id())
}
-
+
override def exitFragId(ctx: IDP.FragIdContext): Unit = {
fragId = ctx.id().getText
-
+
if (FragCache.get(mdlId, fragId).isDefined)
throw newSyntaxError(s"Duplicate fragment ID: $fragId")(ctx.id())
}
- override def exitTermEq(ctx: IDP.TermEqContext): Unit = termConv = ctx.TILDA() != null
+ 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)
+
override def exitOrderedDecl(ctx: IDP.OrderedDeclContext): Unit = ordered = ctx.BOOL().getText == "true"
override def exitFragRef(ctx: IDP.FragRefContext): Unit = {
@@ -158,7 +169,7 @@ object NCIntentDslCompiler extends LazyLogging {
val meta = if (fragMeta == null) Map.empty[String, Any] else fragMeta
for (fragTerm ← frag.terms)
- if (terms.exists(t ⇒ t.id === fragTerm.id))
+ if (terms.exists(t ⇒ t.id === fragTerm.id))
throw newSyntaxError(s"Duplicate term ID '${fragTerm.id.get}' in fragment '$id'.")(ctx.id())
else
terms += fragTerm.cloneWithFragMeta(meta)
@@ -261,7 +272,7 @@ object NCIntentDslCompiler extends LazyLogging {
val stack = new mutable.ArrayStack[NCDslTermRetVal]()
// Execute all instructions.
- instrs.foreach(_(tok, stack, termCtx))
+ instrs.foreach(_ (tok, stack, termCtx))
// Pop final result from stack.
val x = stack.pop()
@@ -273,7 +284,7 @@ object NCIntentDslCompiler extends LazyLogging {
}
}
-
+
// Add term.
terms += NCDslTerm(
Option(termId),
@@ -296,7 +307,7 @@ object NCIntentDslCompiler extends LazyLogging {
terms.clear()
}
-
+
override def exitIntent(ctx: IDP.IntentContext): Unit = {
intents += NCDslIntent(
dsl,
@@ -319,10 +330,17 @@ object NCIntentDslCompiler extends LazyLogging {
*
* @return
*/
- def getBuiltIntents: Set[NCDslIntent] = intents.toSet
-
+ def getCompiledIntents: Set[NCDslIntent] = intents.toSet
+
+ /**
+ *
+ * @return
+ */
+ def getCompiledSynonym: NCDslSynonym = ???
+
override def syntaxError(errMsg: String, srcName: String, line: Int, pos: Int): NCE =
throw new NCE(mkSyntaxError(errMsg, srcName, line, pos, dsl, mdlId))
+
override def runtimeError(errMsg: String, srcName: String, line: Int, pos: Int, cause: Exception = null): NCE =
throw new NCE(mkRuntimeError(errMsg, srcName, line, pos, dsl, mdlId), cause)
}
@@ -345,15 +363,15 @@ object NCIntentDslCompiler extends LazyLogging {
mdlId: String): String = mkError("syntax", msg, srcName, line, charPos, dsl, mdlId)
/**
- *
- * @param msg
- * @param dsl
- * @param mdlId
- * @param srcName
- * @param line
- * @param charPos
- * @return
- */
+ *
+ * @param msg
+ * @param dsl
+ * @param mdlId
+ * @param srcName
+ * @param line
+ * @param charPos
+ * @return
+ */
private def mkRuntimeError(
msg: String,
srcName: String,
@@ -379,13 +397,13 @@ object NCIntentDslCompiler extends LazyLogging {
case s: String if s.last == '.' ⇒ s
case s: String ⇒ s + '.'
}
-
- s"Intent DSL $kind error in '$srcName' at line $line:${charPos + 1} - $aMsg\n" +
- s" |-- ${c("Model:")} $mdlId\n" +
- s" |-- ${c("Line:")} $dslPtr\n" +
- s" +-- ${c("Position:")} $posPtr"
+
+ s"DSL $kind error in '$srcName' at line $line:${charPos + 1} - $aMsg\n" +
+ s" |-- ${c("Model:")} $mdlId\n" +
+ s" |-- ${c("Line:")} $dslPtr\n" +
+ s" +-- ${c("Position:")} $posPtr"
}
-
+
/**
* Custom error handler.
*
@@ -411,15 +429,15 @@ object NCIntentDslCompiler extends LazyLogging {
e: RecognitionException): Unit =
throw new NCE(mkSyntaxError(msg, recog.getInputStream.getSourceName, line, charPos - 1, dsl, mdlId))
}
-
+
/**
- *
- * @param dsl
- * @param mdlId
- * @param srcName
- * @return
- */
- private def antlr4(
+ *
+ * @param dsl
+ * @param mdlId
+ * @param srcName
+ * @return
+ */
+ private def parseIntents(
dsl: String,
mdlId: String,
srcName: String
@@ -427,61 +445,115 @@ object NCIntentDslCompiler extends LazyLogging {
require(dsl != null)
require(mdlId != null)
require(srcName != null)
-
- val aDsl = dsl.strip()
-
- val intents: Set[NCDslIntent] = cache.getOrElseUpdate(aDsl, {
- // ANTLR4 armature.
- val lexer = new NCIntentDslLexer(CharStreams.fromString(aDsl, srcName))
- val tokens = new CommonTokenStream(lexer)
- val parser = new IDP(tokens)
-
- // Set custom error handlers.
- lexer.removeErrorListeners()
- parser.removeErrorListeners()
- lexer.addErrorListener(new CompilerErrorListener(aDsl, mdlId))
- parser.addErrorListener(new CompilerErrorListener(aDsl, mdlId))
-
- // State automata.
- val fsm = new FiniteStateMachine(aDsl, mdlId)
-
+
+ val x = dsl.strip()
+
+ val intents: Set[NCDslIntent] = intentCache.getOrElseUpdate(x, {
+ val (fsm, parser) = antlr4Armature(x, mdlId)
+
// Parse the input DSL and walk built AST.
(new ParseTreeWalker).walk(fsm, parser.dsl())
-
- // Return the built intent.
- fsm.getBuiltIntents
+
+ // Return the compiled intents.
+ fsm.getCompiledIntents
})
-
+
intents
}
-
+
/**
- * Compiles inline (supplied) fragments and/or intents from given file. Note that fragments are
- * accumulated in a static map keyed by model ID. Only intents are returned, if any.
- *
- * @param filePath *.nc DSL file to compile.
- * @param mdlId ID of the model *.nc file belongs to.
- * @return
- */
+ *
+ * @param dsl
+ * @param mdlId
+ * @return
+ */
+ private def parseSynonym(
+ dsl: String,
+ mdlId: String
+ ): NCDslSynonym = {
+ require(dsl != null)
+ require(mdlId != null)
+
+ val x = dsl.strip()
+
+ val syn: NCDslSynonym = synCache.getOrElseUpdate(x, {
+ val (fsm, parser) = antlr4Armature(x, mdlId)
+
+ // Parse the input DSL and walk built AST.
+ (new ParseTreeWalker).walk(fsm, parser.synonym())
+
+ // Return the compiled synonym.
+ fsm.getCompiledSynonym
+ })
+
+ syn
+ }
+
+ /**
+ *
+ * @param dsl
+ * @param mdlId
+ * @param srcName
+ * @return
+ */
+ private def antlr4Armature(
+ dsl: String,
+ mdlId: String,
+ srcName: String = "<inline>"
+ ): (FiniteStateMachine, IDP) = {
+ val lexer = new NCIntentDslLexer(CharStreams.fromString(dsl, srcName))
+ val tokens = new CommonTokenStream(lexer)
+ val parser = new IDP(tokens)
+
+ // Set custom error handlers.
+ lexer.removeErrorListeners()
+ parser.removeErrorListeners()
+ lexer.addErrorListener(new CompilerErrorListener(dsl, mdlId))
+ parser.addErrorListener(new CompilerErrorListener(dsl, mdlId))
+
+ // State automata + it's parser.
+ new FiniteStateMachine(dsl, mdlId) → parser
+ }
+
+ /**
+ * Compiles inline (supplied) fragments and/or intents from given file. Note that fragments are
+ * accumulated in a static map keyed by model ID. Only intents are returned, if any.
+ *
+ * @param filePath *.nc intent DSL file to compile.
+ * @param mdlId ID of the model *.nc file belongs to.
+ * @return
+ */
@throws[NCE]
- def compileIntent(
+ def compileIntents(
filePath: Path,
mdlId: String
- ): Set[NCDslIntent] = antlr4(U.readFile(filePath.toFile).mkString("\n"), mdlId, filePath.getFileName.toString)
-
+ ): Set[NCDslIntent] = parseIntents(U.readFile(filePath.toFile).mkString("\n"), mdlId, filePath.getFileName.toString)
+
/**
* Compiles inline (supplied) fragments and/or intents. Note that fragments are accumulated in a static
* map keyed by model ID. Only intents are returned, if any.
*
- * @param dsl DSL to compile.
+ * @param dsl Intent DSL to compile.
* @param mdlId ID of the model DSL belongs to.
* @param srcName Optional source name.
* @return
*/
@throws[NCE]
- def compileIntent(
+ def compileIntents(
dsl: String,
mdlId: String,
srcName: String = "<inline>"
- ): Set[NCDslIntent] = antlr4(dsl, mdlId, srcName)
+ ): Set[NCDslIntent] = parseIntents(dsl, mdlId, srcName)
+
+ /**
+ *
+ * @param dsl Synonym DSL to compile.
+ * @param mdlId ID of the model DSL belongs to.
+ * @return
+ */
+ @throws[NCE]
+ def compileSynonym(
+ dsl: String,
+ mdlId: String
+ ): NCDslSynonym = parseSynonym(dsl, mdlId)
}
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 f470529..e63aceb 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
@@ -1473,7 +1473,7 @@ object NCDeployManager extends NCService with DecorateAsScala {
val mStr = method2Str(m)
// Process inline intent declarations by @NCIntent annotation.
- for (ann ← m.getAnnotationsByType(CLS_INTENT); intent ← NCIntentDslCompiler.compileIntent(ann.value(), mdl.getId, mStr))
+ for (ann ← m.getAnnotationsByType(CLS_INTENT); intent ← NCIntentDslCompiler.compileIntents(ann.value(), mdl.getId, mStr))
intents += (intent → prepareCallback(m, mdl, intent))
// Process intent references from @NCIntentRef annotation.
@@ -1485,7 +1485,7 @@ object NCDeployManager extends NCService with DecorateAsScala {
val compiledIntents = adapter
.getIntents
.asScala
- .flatMap(NCIntentDslCompiler.compileIntent(_, mdl.getId, mStr))
+ .flatMap(NCIntentDslCompiler.compileIntents(_, mdl.getId, mStr))
U.getDups(compiledIntents.toSeq.map(_.id)) match {
case ids if ids.nonEmpty ⇒
@@ -1554,7 +1554,7 @@ object NCDeployManager extends NCService with DecorateAsScala {
val distinct = seqSeq.map(_.distinct).distinct
for (ann ← intAnns) {
- for (intent ← NCIntentDslCompiler.compileIntent(ann.value(), mdlId, mStr))
+ for (intent ← NCIntentDslCompiler.compileIntents(ann.value(), mdlId, mStr))
samples += (intent.id → distinct)
}
for (ann ← refAnns)
diff --git a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/dsl/compiler/NCIntentDslCompilerSpec.scala b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/dsl/compiler/NCIntentDslCompilerSpec.scala
index a7b2d95..685ea43 100644
--- a/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/dsl/compiler/NCIntentDslCompilerSpec.scala
+++ b/nlpcraft/src/test/scala/org/apache/nlpcraft/model/intent/dsl/compiler/NCIntentDslCompilerSpec.scala
@@ -35,7 +35,7 @@ class NCIntentDslCompilerSpec {
*/
private def checkCompileOk(dsl: String): Unit =
try {
- NCIntentDslCompiler.compileIntent(dsl, MODEL_ID)
+ NCIntentDslCompiler.compileIntents(dsl, MODEL_ID)
assert(true)
}
@@ -49,7 +49,7 @@ class NCIntentDslCompilerSpec {
*/
private def checkPathCompileOk(path: Path): Unit =
try {
- NCIntentDslCompiler.compileIntent(path, MODEL_ID)
+ NCIntentDslCompiler.compileIntents(path, MODEL_ID)
assert(true)
}
@@ -63,7 +63,7 @@ class NCIntentDslCompilerSpec {
*/
private def checkCompileError(txt: String): Unit =
try {
- NCIntentDslCompiler.compileIntent(txt, MODEL_ID)
+ NCIntentDslCompiler.compileIntents(txt, MODEL_ID)
assert(false)
} catch {