This is an automated email from the ASF dual-hosted git repository.
aradzinski pushed a commit to branch NLPCRAFT-474
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git
The following commit(s) were added to refs/heads/NLPCRAFT-474 by this push:
new 67c22ef WIP
67c22ef is described below
commit 67c22eff8dc0cdacbb5e1967671db1dcec224b8a
Author: Aaron Radzinski <[email protected]>
AuthorDate: Mon Jan 24 17:59:22 2022 -0800
WIP
---
.../nlpcraft/internal/intent/NCIDLEntity.scala | 10 +--
.../intent/compiler/NCIDLCodeGenerator.scala | 78 ++++++----------------
.../internal/intent/compiler/antlr4/NCIDL.g4 | 17 +++--
3 files changed, 37 insertions(+), 68 deletions(-)
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/intent/NCIDLEntity.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/intent/NCIDLEntity.scala
index f779938..f10c577 100644
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/intent/NCIDLEntity.scala
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/intent/NCIDLEntity.scala
@@ -19,21 +19,15 @@ package org.apache.nlpcraft.internal.intent
import org.apache.nlpcraft.*
import scala.jdk.CollectionConverters.*
-import java.util
-//import java.util.{Collections, List, Set}
/**
*
* @param ent
* @param idx
*/
-class NCIDLEntity(ent: NCEntity, idx: Int) extends NCPropertyMapAdapter with
NCEntity:
+class NCIDLEntity(ent: NCEntity, idx: Int):
private lazy val txt = ent.getTokens.asScala.map(_.getText).mkString(" ")
- override def getTokens: util.List[NCToken] = ent.getTokens
- override def getRequestId: String = ent.getRequestId
- override def getGroups: util.Set[String] = ent.getGroups
- override def getId: String = ent.getId
-
+ def getImpl: NCEntity = ent
def getText: String = txt
def getIndex: Int = idx
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/intent/compiler/NCIDLCodeGenerator.scala
b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/intent/compiler/NCIDLCodeGenerator.scala
index fd53633..c8c455a 100644
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/intent/compiler/NCIDLCodeGenerator.scala
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/intent/compiler/NCIDLCodeGenerator.scala
@@ -38,7 +38,7 @@ import scala.jdk.CollectionConverters.SeqHasAsJava
trait NCIDLCodeGenerator:
type S = NCIDLStack
type ST = NCIDLStackType
- type SI = (NCToken, S, NCIDLContext) => Unit
+ type SI = (NCIDLEntity, S, NCIDLContext) => Unit
def syntaxError(errMsg: String, srcName: String, line: Int, pos: Int):
NCException
def runtimeError(errMsg: String, srcName: String, line: Int, pos: Int,
cause: Exception = null): NCException
@@ -160,6 +160,8 @@ trait NCIDLCodeGenerator:
newRuntimeError(s"Runtime error in IDL function: $fun()", cause)
def rtUnavailFunError(fun: String)(implicit ctx: PRC): NCException =
newRuntimeError(s"Function '$fun()' is unavailable in this IDL
context.")
+ def rtEmptyListError(fun: String)(implicit ctx: PRC): NCException =
+ newRuntimeError(s"Unexpected empty list in IDL function: $fun()")
/**
*
@@ -484,7 +486,7 @@ trait NCIDLCodeGenerator:
* @param ctx
* @return
*/
- def parseCallExpr(fun: String)(implicit ctx: PRC): SI = (ent, stack: S,
idlCtx) =>
+ def parseCallExpr(fun: String)(implicit ctx: PRC): SI = (ent: NCIDLEntity,
stack: S, idlCtx) =>
implicit val evidence: S = stack
def popMarker(argNum: Int): Unit = if pop1() != stack.PLIST_MARKER
then throw rtTooManyParamsError(argNum, fun)
@@ -643,7 +645,7 @@ trait NCIDLCodeGenerator:
val Z(v, n) = x()
val lst = toList(v).asInstanceOf[util.List[Object]]
try
- if lst.isEmpty then throw newRuntimeError(s"Unexpected
empty list in IDL function: $fun()")
+ if lst.isEmpty then throw rtEmptyListError(fun)
else Z(Collections.min(lst, null), n)
catch case e: Exception => throw rtListTypeError(fun, e)
})
@@ -654,7 +656,7 @@ trait NCIDLCodeGenerator:
val Z(v, n) = x()
val lst = toList(v).asInstanceOf[util.List[Object]]
try
- if lst.isEmpty then throw newRuntimeError(s"Unexpected
empty list in IDL function: $fun()")
+ if lst.isEmpty then throw rtEmptyListError(fun)
else
val seq: Seq[Double] = lst.asScala.map(p =>
JDouble.valueOf(p.toString).doubleValue()).toSeq
Z(seq.sum / seq.length, n)
@@ -667,7 +669,7 @@ trait NCIDLCodeGenerator:
val Z(v, n) = x()
val lst = toList(v).asInstanceOf[util.List[Object]]
try
- if lst.isEmpty then throw newRuntimeError(s"Unexpected
empty list in IDL function: $fun()")
+ if lst.isEmpty then throw rtEmptyListError(fun)
else
val seq: Seq[Double] = lst.asScala.map(p =>
JDouble.valueOf(p.toString).doubleValue()).toSeq
val mean = seq.sum / seq.length
@@ -718,7 +720,7 @@ trait NCIDLCodeGenerator:
val Z(v, n) = x()
val lst = toList(v).asInstanceOf[util.List[Object]]
try
- if lst.isEmpty then throw newRuntimeError(s"Unexpected
empty list in IDL function: $fun()")
+ if lst.isEmpty then throw rtEmptyListError(fun)
else Z(Collections.max(lst, null), n)
catch case e: Exception => throw rtListTypeError(fun, e)
})
@@ -893,7 +895,7 @@ trait NCIDLCodeGenerator:
try
fun match
// Metadata access.
- case "meta_ent" => ???
+ case "meta_ent" => z[ST](arg1, { x => val Z(v, _) = x();
Z(box(ent.getImpl.get[Object](toStr(v))), 0) })
case "meta_cfg" => z[ST](arg1, { x => val Z(v, _) = x();
Z(box(idlCtx.mdlCf.get[Object](toStr(v))), 0) })
case "meta_req" => z[ST](arg1, { x => val Z(v, _) = x();
Z(box(idlCtx.req.getRequestData.get(toStr(v))), 0) })
case "meta_intent" => z[ST](arg1, { x => val Z(v, _) = x();
Z(box(idlCtx.intentMeta.get(toStr(v)).orNull), 0) })
@@ -909,59 +911,23 @@ trait NCIDLCodeGenerator:
case "or_else" => doOrElse()
// Entity functions.
- case "ent_id" => arg1Tok() match { case x => stack.push(() =>
Z(toEntity(x().value).getId, 1)) }
+ case "ent_id" => arg1Tok() match { case x => stack.push(() =>
Z(toEntity(x().value).getImpl.getId, 1)) }
case "ent_index" => arg1Tok() match { case x => stack.push(()
=> Z(toEntity(x().value).getIndex, 1)) }
case "ent_text" => arg1Tok() match { case x => stack.push(()
=> Z(toEntity(x().value).getText, 1)) }
case "ent_count" => checkAvail(); z0(() =>
Z(idlCtx.entities.size, 0))
- case "ent_groups" => arg1Tok() match { case x => stack.push(()
=> Z(toEntity(x().value).getGroups, 1)) }
+ case "ent_groups" => arg1Tok() match { case x => stack.push(()
=> Z(toEntity(x().value).getImpl.getGroups, 1)) }
case "ent_all" => checkAvail(); z0(() =>
Z(idlCtx.entities.asJava, 0))
- case "ent_all_for_id" => checkAvail(); doForAll((ent, id) =>
ent.getId == id)
- case "ent_all_for_group" => checkAvail(); doForAll((ent, grp)
=> ent.getGroups.contains(grp))
-
-// case "tok_lemma" => arg1Tok() match { case x =>
stack.push(() => { Z(toToken(x().value).getLemma, 1) }) }
-// case "tok_stem" => arg1Tok() match { case x => stack.push(()
=> { Z(toToken(x().value).getStem, 1) }) }
-// case "tok_pos" => arg1Tok() match { case x => stack.push(()
=> { Z(toToken(x().value).getPos, 1) }) }
-// case "tok_txt" => arg1Tok() match { case x => stack.push(()
=> { Z(toToken(x().value).getOriginalText, 1) }) }
-// case "tok_norm_txt" => arg1Tok() match { case x =>
stack.push(() => { Z(toToken(x().value).getNormalizedText, 1) }) }
-// case "tok_req_id" => arg1Tok() match { case x =>
stack.push(() => { Z(toToken(x().value).getServerRequestId, 1) }) }
-// case "tok_sparsity" => arg1Tok() match { case x =>
stack.push(() => { Z(toToken(x().value).getSparsity, 1) }) }
-// case "tok_unid" => arg1Tok() match { case x => stack.push(()
=> { Z(toToken(x().value).getUnid, 1) }) }
-//
-// case "tok_index" => checkAvail(); arg1Tok() match { case x
=> stack.push(() => { Z(toToken(x().value).getIndex, 1) }) }
-// case "tok_is_last" => checkAvail(); arg1Tok() match { case x
=> stack.push(() => { Z(toToken(x().value).getIndex == idlCtx.entities.size -
1, 1) }) }
-// case "tok_is_first" => checkAvail(); arg1Tok() match { case
x => stack.push(() => { Z(toToken(x().value).getIndex == 0, 1) }) }
-// case "tok_is_before_id" => checkAvail(); doIsBefore((tok,
id) => ent.getId == id)
-// case "tok_is_before_group" => checkAvail(); doIsBefore((tok,
grpId) => ent.getGroups.contains(grpId))
-// case "tok_is_before_parent" => checkAvail();
doIsBefore((tok, id) => ent.getParentId == id)
-// case "tok_is_after_id" => checkAvail(); doIsAfter((tok, id)
=> ent.getId == id)
-// case "tok_is_after_group" => checkAvail(); doIsAfter((tok,
grpId) => ent.getGroups.contains(grpId))
-// case "tok_is_after_parent" => checkAvail(); doIsAfter((tok,
id) => ent.getParentId == id)
-// case "tok_is_between_ids" => checkAvail(); doIsBetween((tok,
id) => ent.getId == id)
-// case "tok_is_between_groups" => checkAvail();
doIsBetween((tok, grpId) => ent.getGroups.contains(grpId))
-// case "tok_is_between_parents" => checkAvail();
doIsBetween((tok, id) => ent.getParentId == id)
-//
-// case "tok_is_abstract" => arg1Tok() match { case x =>
stack.push(() => { Z(toToken(x().value).isAbstract, 1) }) }
-// case "tok_is_bracketed" => arg1Tok() match { case x =>
stack.push(() => { Z(toToken(x().value).isBracketed, 1) }) }
-// case "tok_is_direct" => arg1Tok() match { case x =>
stack.push(() => { Z(toToken(x().value).isDirect, 1) }) }
-// case "tok_is_permutated" => arg1Tok() match { case x =>
stack.push(() => { Z(!toToken(x().value).isDirect, 1) }) }
-// case "tok_is_english" => arg1Tok() match { case x =>
stack.push(() => { Z(toToken(x().value).isEnglish, 1) }) }
-// case "tok_is_freeword" => arg1Tok() match { case x =>
stack.push(() => { Z(toToken(x().value).isFreeWord, 1) }) }
-// case "tok_is_quoted" => arg1Tok() match { case x =>
stack.push(() => { Z(toToken(x().value).isQuoted, 1) }) }
-// case "tok_is_stopword" => arg1Tok() match { case x =>
stack.push(() => { Z(toToken(x().value).isStopWord, 1) }) }
-// case "tok_is_swear" => arg1Tok() match { case x =>
stack.push(() => { Z(toToken(x().value).isSwear, 1) }) }
-// case "tok_is_user" => arg1Tok() match { case x =>
stack.push(() => { Z(toToken(x().value).isUserDefined, 1) }) }
-// case "tok_is_wordnet" => arg1Tok() match { case x =>
stack.push(() => { Z(toToken(x().value).isWordnet, 1) }) }
-// case "tok_ancestors" => arg1Tok() match { case x =>
stack.push(() => { Z(toToken(x().value).getAncestors, 1) }) }
-// case "tok_parent" => arg1Tok() match { case x =>
stack.push(() => { Z(toToken(x().value).getParentId, 1) }) }
-// case "tok_value" => arg1Tok() match { case x =>
stack.push(() => { Z(toToken(x().value).getValue, 1) }) }
-// case "tok_aliases" => arg1Tok() match { case x =>
stack.push(() => { Z(box(toToken(x().value).getAliases), 1) }) }
-// case "tok_start_idx" => arg1Tok() match { case x =>
stack.push(() => { Z(toToken(x().value).getStartCharIndex, 1) }) }
-// case "tok_end_idx" => arg1Tok() match { case x =>
stack.push(() => { Z(toToken(x().value).getEndCharIndex, 1) }) }
-// case "tok_this" => z0(() => Z(tok, 1))
-// case "tok_has_part" => doHasPart()
-// case "tok_find_part" => doFindPart()
-// case "tok_find_parts" => doFindParts()
-//
+ case "ent_all_for_id" => checkAvail(); doForAll((ent, id) =>
ent.getImpl.getId == id)
+ case "ent_all_for_group" => checkAvail(); doForAll((ent, grp)
=> ent.getImpl.getGroups.contains(grp))
+ case "ent_this" => z0(() => Z(ent, 1))
+ case "ent_is_last" => checkAvail(); arg1Tok() match { case x
=> stack.push(() => { Z(toEntity(x().value).getIndex == idlCtx.entities.size -
1, 1) }) }
+ case "ent_is_first" => checkAvail(); arg1Tok() match { case x
=> stack.push(() => { Z(toEntity(x().value).getIndex == 0, 1) }) }
+ case "ent_is_before_id" => checkAvail(); doIsBefore((tok, id)
=> ent.getImpl.getId == id)
+ case "ent_is_before_group" => checkAvail(); doIsBefore((tok,
grpId) => ent.getImpl.getGroups.contains(grpId))
+ case "ent_is_after_id" => checkAvail(); doIsAfter((tok, id) =>
ent.getImpl.getId == id)
+ case "ent_is_after_group" => checkAvail(); doIsAfter((tok,
grpId) => ent.getImpl.getGroups.contains(grpId))
+ case "ent_is_between_ids" => checkAvail(); doIsBetween((tok,
id) => ent.getImpl.getId == id)
+ case "ent_is_between_groups" => checkAvail();
doIsBetween((tok, grpId) => ent.getImpl.getGroups.contains(grpId))
// Request data.
case "req_id" => z0(() => Z(idlCtx.req.getRequestId, 0))
diff --git
a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/intent/compiler/antlr4/NCIDL.g4
b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/intent/compiler/antlr4/NCIDL.g4
index e697ef4..35eb435 100644
---
a/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/intent/compiler/antlr4/NCIDL.g4
+++
b/nlpcraft/src/main/scala/org/apache/nlpcraft/internal/intent/compiler/antlr4/NCIDL.g4
@@ -3,13 +3,13 @@
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
+ * (the '
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
+ * distributed under the License is distributed on an '
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
@@ -152,6 +152,15 @@ FUN_NAME
| 'ent_all'
| 'ent_all_for_id'
| 'ent_all_for_group'
+ | 'ent_this'
+ | 'ent_is_last'
+ | 'ent_is_first'
+ | 'ent_is_before_id'
+ | 'ent_is_before_group'
+ | 'ent_is_after_id'
+ | 'ent_is_after_group'
+ | 'ent_is_between_ids'
+ | 'ent_is_between_groups'
| 'req_id'
| 'req_text'
| 'req_tstamp'
@@ -255,7 +264,7 @@ META : 'meta' ;
TERM : 'term' ;
FRAG: 'fragment'; // To resolve ambiguity with ANTLR4 keyword.
SQSTRING: SQUOTE ((~'\'') | ('\\''\''))* SQUOTE; // Allow for \' (escaped
single quote) in the string.
-DQSTRING: DQUOTE ((~'"') | ('\\''"'))* DQUOTE; // Allow for \" (escape double
quote) in the string.
+DQSTRING: DQUOTE ((~''
BOOL: 'true' | 'false';
NULL: 'null';
EQ: '==';
@@ -273,7 +282,7 @@ RPAR: ')';
LBRACE: '{';
RBRACE: '}';
SQUOTE: '\'';
-DQUOTE: '"';
+DQUOTE: ''
TILDA: '~';
LBR: '[';
RBR: ']';