in nlpcraft/src/main/scala/org/apache/nlpcraft/internal/intent/compiler/NCIDLCompiler.scala [270:422]
override def exitFrag(ctx: IDP.FragContext): Unit =
val frag = NCIDLFragment(fragId, terms.toList)
fragCache.get(frag.id) match
case Some(_) =>
if isMethodLevel then
logger.warn(s"Fragment '${frag.id}' was overridden just for the scope of: '${this.origin}'")
else
logger.warn(s"Fragment '${frag.id}' was overridden in origin: '${this.origin}'")
case None => // No-op.
fragCache += frag.id -> frag
terms.clear()
fragId = null
/**
*
* @param intent
* @param ctx
*/
private def addIntent(intent: NCIDLIntent)(implicit ctx: ParserRuleContext): Unit =
val intentId = intent.id
if intents.exists(_.id == intentId) then SE(s"Duplicate intent ID: $intentId")
intents += intent
override def exitIntent(ctx: IDP.IntentContext): Unit =
addIntent(
NCIDLIntent(
origin,
idl,
intentId,
intentOpts,
if intentMeta == null then Map.empty else intentMeta,
flowRegex,
terms.toList
)
)(ctx.intentId())
intentMeta = null
intentOpts = new NCIDLIntentOptions()
terms.clear()
override def exitImprt(ctx: IDP.ImprtContext): Unit =
val x = NCUtils.trimQuotes(ctx.qstring().getText)
if importCache.contains(x) then logger.warn(s"Ignoring already processed IDL import '$x' in: $origin")
else
importCache += x
var imports: Set[NCIDLIntent] = null
val file = new File(x)
// First, try absolute path.
if file.exists() then
val idl = NCUtils.readLines(file).mkString("\n")
imports = compile(idl, x)
// Second, try as a classloader resource.
if imports == null then
val in = cfg.getClass.getClassLoader.getResourceAsStream(x)
if in != null then
val idl = NCUtils.readLines(in).mkString("\n")
imports = compile(idl, x)
// Finally, try as URL resource.
if imports == null then
try
val idl = NCUtils.readLines(new URL(x).openStream()).mkString("\n")
imports = compile(idl, x)
catch case _: Exception => throw newRuntimeError(s"Invalid or unknown import location: $x")(ctx.qstring())
require(imports != null)
imports.foreach(addIntent(_)(ctx.qstring()))
override def syntaxError(errMsg: String, srcName: String, line: Int, pos: Int): NCException =
throw new NCException(mkSyntaxError(errMsg, srcName, line, pos, idl, origin, cfg))
override def runtimeError(errMsg: String, srcName: String, line: Int, pos: Int, cause: Exception = null): NCException =
throw new NCException(mkRuntimeError(errMsg, srcName, line, pos, idl, origin, cfg), cause)
/**
*
* @param msg
* @param srcName
* @param line
* @param charPos
* @param idl
* @param origin IDL origin.
* @param mdlCfg
*/
private def mkSyntaxError(
msg: String,
srcName: String,
line: Int, // 1, 2, ...
charPos: Int, // 0, 1, 2, ...
idl: String,
origin: String,
mdlCfg: NCModelConfig): String = mkError("syntax", msg, srcName, line, charPos, idl, origin, mdlCfg)
/**
*
* @param msg
* @param srcName
* @param line
* @param charPos
* @param idl
* @param origin IDL origin.
* @param mdlCfg
*/
private def mkRuntimeError(
msg: String,
srcName: String,
line: Int, // 1, 2, ...
charPos: Int, // 0, 1, 2, ...
idl: String,
origin: String,
mdlCfg: NCModelConfig): String = mkError("runtime", msg, srcName, line, charPos, idl, origin, mdlCfg)
/**
*
* @param kind
* @param msg
* @param srcName
* @param line
* @param charPos
* @param idl
* @param origin IDL origin.
* @param mdlCfg
*/
private def mkError(
kind: String,
msg: String,
srcName: String,
line: Int,
charPos: Int,
idl: String,
origin: String,
mdlCfg: NCModelConfig): String = {
val idlLine = idl.split("\n")(line - 1)
val hold = NCCompilerUtils.mkErrorHolder(idlLine, charPos)
val aMsg = NCUtils.decapitalize(msg) match
case s: String if s.last == '.' => s
case s: String => s"$s."
s"""IDL $kind error in '$srcName' at line $line - $aMsg
|-- Model ID: ${mdlCfg.getId}
|-- Model origin: ${mdlCfg.getOrigin}
|-- Intent origin: $origin
|--
|-- Line: ${hold.origStr}
+-- Error: ${hold.ptrStr}"""
}