public ParserConfig(bool strict, bool utf8, bool forceCase, ConcatMode concat, ILogger logger) { this.strict = strict; this.utf8 = utf8; this.forceCase = forceCase; this.logger = logger; this.concat = concat; }
/// <summary> /// This method reads through SPECTRAL index matrices to check for signs that something might be wrong with the data. /// Currently, it reads through the ACI matrix to check where the spectral row sums are close to zero. These should never be LTE zero. /// This test is not particularly realistic but might occur. /// Other tests can be inserted in the future. /// </summary> /// <param name="spectralIndices">Dictionary of the currently calculated spectral indices.</param> /// <param name="gapRendering">how to render the gap in image terms.</param> /// <returns>a list of erroneous segments.</returns> public static List <GapsAndJoins> DataIntegrityCheckSpectralIndices( Dictionary <string, double[, ]> spectralIndices, ConcatMode gapRendering) { int errorStart; double tolerance = 0.00001; // get row sums of the ACI matrix var rowSums = MatrixTools.SumRows(spectralIndices["ACI"]); // init list of errors var gaps = new List <GapsAndJoins>(); bool allOk = true; if (rowSums[0] < tolerance) { allOk = false; errorStart = 0; gaps.Add(new GapsAndJoins()); gaps[gaps.Count - 1].GapDescription = gapDescriptionInvalidValue; gaps[gaps.Count - 1].StartPosition = errorStart; gaps[gaps.Count - 1].GapRendering = gapRendering; } int arrayLength = rowSums.Length; for (int i = 1; i < arrayLength; i++) { if (rowSums[i] < tolerance) { if (allOk) { errorStart = i; gaps.Add(new GapsAndJoins()); gaps[gaps.Count - 1].GapDescription = gapDescriptionInvalidValue; gaps[gaps.Count - 1].StartPosition = errorStart; gaps[gaps.Count - 1].GapRendering = gapRendering; } allOk = false; } else if (!allOk) { allOk = true; gaps[gaps.Count - 1].EndPosition = i - 1; } } // end of loop // do final clean up if (!allOk) { gaps[gaps.Count - 1].EndPosition = arrayLength - 1; } return(gaps); }
public Parser(ParserConfig config, TopicManager topicManager) { if (config == null) { config = ParserConfig.Default; } this.topicManager = topicManager ?? throw new ArgumentNullException(nameof(topicManager), "Topicmanager instance must be not null"); strict = config.strict; utf8 = config.utf8; forceCase = config.forceCase; concat = config.concat; logger = config.logger ?? new EmptyLogger(); }
/// <summary> /// Does several data integrity checks. /// </summary> /// <param name="summaryIndices">a dictionary of summary indices.</param> /// <param name="gapRendering">describes how recording gaps are to be rendered.</param> /// <returns>a list of erroneous segments.</returns> public static List <GapsAndJoins> DataIntegrityCheck(IEnumerable <SummaryIndexValues> summaryIndices, ConcatMode gapRendering) { // Integrity check 1: look for whether a recording minute exists var errors = DataIntegrityCheckRecordingGaps(summaryIndices, gapRendering); // Integrity check 2: look for whether there is join between two recording files errors.AddRange(DataIntegrityCheckForFileJoins(summaryIndices, gapRendering)); // Integrity check 3: reads the ZeroSignal array to make sure there was actually a signal to analyse. errors.AddRange(DataIntegrityCheckForZeroSignal(summaryIndices)); // Integrity check 4. This error check not done for time being - a bit unrealistic // errors.AddRange(DataIntegrityCheckIndexValues(summaryIndices)); return(errors); }
/// <summary> /// This method reads through a SUMMARY index array to check for file joins. /// </summary> /// <param name="summaryIndices">array of summary indices.</param> /// <param name="gapRendering">how to render the gap in image terms.</param> /// <returns>a list of erroneous segments.</returns> public static List <GapsAndJoins> DataIntegrityCheckForFileJoins(IEnumerable <SummaryIndexValues> summaryIndices, ConcatMode gapRendering) { // init list of gaps and joins var joins = new List <GapsAndJoins>(); string previousFileName = summaryIndices.First <SummaryIndexValues>().FileName; // now loop through the rows/vectors of indices int index = 0; foreach (var row in summaryIndices) { if (row.FileName != previousFileName) { var fileJoin = new GapsAndJoins { StartPosition = index, GapDescription = gapDescriptionFileJoin, GapRendering = gapRendering, EndPosition = index, // this renders to one pixel width. }; joins.Add(fileJoin); previousFileName = row.FileName; } index++; } return(joins); }
/// <summary> /// This method reads through a SUMMARY index array looking for gaps in the recording. /// I initilly tried to detect these when the RankOrder index takes consecutive zero values. /// However this does not work with recordings sampled one minute in N minutes. /// So reverted to detecting the mising data flag which is when row.FileName == missingRow. /// If this occurs a gap event is flagged. /// </summary> /// <param name="summaryIndices">array of summary indices.</param> /// <param name="gapRendering">how to render the gap in image terms.</param> /// <returns>a list of erroneous segments.</returns> public static List <GapsAndJoins> DataIntegrityCheckRecordingGaps(IEnumerable <SummaryIndexValues> summaryIndices, ConcatMode gapRendering) { // init list of gaps and joins var gaps = new List <GapsAndJoins>(); // initialise starting conditions for loop string missingRow = IndexMatrices.MissingRowString; //int previousRank = -1; GapsAndJoins gap = null; bool isGap = false; int index = 0; // now loop through the rows/vectors of indices foreach (var row in summaryIndices) { //if (!isGap && (row.RankOrder == previousRank + 1)) //{ // //everything OK // //continue; //} // if in gap and zeros continue then still in gap //if (isGap && (row.RankOrder == 0 && previousRank == 0)) //{ // //still in gap // //continue; //} //if (!isGap && (row.RankOrder == 0 && previousRank == 0)) if (!isGap && (row.FileName == missingRow)) { // create gap instance isGap = true; gap = new GapsAndJoins { StartPosition = index, GapDescription = gapDescriptionMissingData, GapRendering = gapRendering, }; } //if (isGap && (row.RankOrder == 1 && previousRank == 0)) if (isGap && (row.FileName != missingRow)) { // come to end of a gap isGap = false; gap.EndPosition = index - 1; gaps.Add(gap); } //previousRank = row.RankOrder; index++; } // reached end of array // if still have gap at end of the array, need to terminate it. if (isGap) { //gaps[gaps.Count - 1].EndPosition = index - 1; gap.EndPosition = summaryIndices.Count() - 1; gaps.Add(gap); } return(gaps); }
/// <summary> /// Does three data integrity checks. /// </summary> /// <param name="spectralIndices">a dictionary of spectral indices.</param> /// <param name="gapRendering">how to render the gap in image terms.</param> /// <returns>a list of erroneous segments.</returns> public static List <GapsAndJoins> DataIntegrityCheck(Dictionary <string, double[, ]> spectralIndices, ConcatMode gapRendering) { var errors = DataIntegrityCheckSpectralIndices(spectralIndices, gapRendering); return(errors); }
public void SampledDataConcatModeTests(ConcatMode gapRendering, int[] expectedWidths) { const string ark01 = "Ark01"; var arguments = new ConcatenateIndexFiles.Arguments { InputDataDirectories = new[] { newZealandArk01IndicesDirectory }, OutputDirectory = this.TestOutputDirectory, DirectoryFilter = "*.wav", FileStemName = ark01, StartDate = null, EndDate = null, IndexPropertiesConfig = PathHelper.ResolveConfigFile("IndexPropertiesConfig.yml").FullName, FalseColourSpectrogramConfig = PathHelper.ResolveConfigFile("SpectrogramFalseColourConfig.yml").FullName, ColorMap1 = null, ColorMap2 = null, ConcatenateEverythingYouCanLayYourHandsOn = false, GapRendering = gapRendering, TimeSpanOffsetHint = TimeSpan.FromHours(12), DrawImages = true, }; ConcatenateIndexFiles.Execute(arguments); var dateStrings = new[] { "20161209", "20161210", "20161211" }.Zip(expectedWidths, ValueTuple.Create); foreach (var(dateString, expectedWidth) in dateStrings) { var prefix = Path.Combine(this.TestOutputDirectory.FullName, ark01, dateString, ark01 + "_" + dateString + "__"); Assert.That.PathExists(prefix + "Towsey.Acoustic.Indices.csv"); Assert.That.PathNotExists(prefix + "SummaryIndex.csv"); var imagePath = prefix + "2Maps.png"; Assert.That.FileExists(imagePath); var actualImage = Image.Load <Rgb24>(imagePath); Assert.That.ImageIsSize(expectedWidth, 632, actualImage); // target region for each image: 40, 254, 20,20 switch (gapRendering) { case ConcatMode.TimedGaps: // for timed gap, first column has content, other 19 don't and should be gray (missing data) Assert.That.ImageRegionIsColor( new Rectangle(40 + 1, 254, 20 - 1, 20), Color.LightGray, actualImage, 0.001); break; case ConcatMode.NoGaps: // There should basically be no pattern here var histogram = ImageTools.GetColorHistogramNormalized( actualImage, new Rectangle(40, 254, 20, 20)); // should not have empty space var hasGray = histogram.TryGetValue(Color.LightGray, out var grayPercentage); Assert.IsTrue(!hasGray || grayPercentage < 0.01); // the rest of the values should be well distributed (not a perfect test) Assert.That.ImageColorsWellDistributed( actualImage, allowedError: 0.1, colorHistogram: histogram); break; case ConcatMode.EchoGaps: // The first column should be repeated 19 times Assert.That.ImageRegionIsRepeatedHorizontally( new Rectangle(40, 254, 1, 20), 19, 1, actualImage); break; default: throw new ArgumentOutOfRangeException(nameof(gapRendering), gapRendering, null); } } }
/// <summary> /// This method reads through a SUMMARY index array to check for file joins. /// </summary> /// <param name="summaryIndices">array of summary indices</param> /// <param name="gapRendering">how to render the gap in image terms</param> /// <returns>a list of erroneous segments</returns> public static List <GapsAndJoins> DataIntegrityCheckForFileJoins(IEnumerable <SummaryIndexValues> summaryIndices, ConcatMode gapRendering) { // init list of gaps and joins var gaps = new List <GapsAndJoins>(); bool isValidBlock = true; string previousFileName = null; GapsAndJoins gap = null; // now loop through the rows/vectors of indices int index = 0; foreach (var row in summaryIndices) { if (previousFileName == null) { previousFileName = row.FileName; } if (row.FileName != previousFileName) { if (isValidBlock) { isValidBlock = false; gap = new GapsAndJoins { StartPosition = index, GapDescription = gapDescriptionFileJoin, GapRendering = gapRendering, }; } else { // come to end of a bad patch isValidBlock = true; gap.EndPosition = index - 1; gaps.Add(gap); } } previousFileName = row.FileName; index++; } // if not OK at end of the array, need to terminate the gap. if (!isValidBlock) { gaps[gaps.Count - 1].EndPosition = gaps[gaps.Count - 1].EndPosition; } return(gaps); }
/// <summary> /// This method reads through a SUMMARY index array to make sure there was actually a signal to analyse. /// If this occurs an gap/join event is flagged. /// </summary> /// <param name="summaryIndices">array of summary indices</param> /// <param name="gapRendering">how to render the gap in image terms</param> /// <returns>a list of erroneous segments</returns> public static List <GapsAndJoins> DataIntegrityCheckForNoRecording(IEnumerable <SummaryIndexValues> summaryIndices, ConcatMode gapRendering) { // init list of gaps and joins var gaps = new List <GapsAndJoins>(); bool isValidBlock = true; GapsAndJoins gap = null; // now loop through the rows/vectors of indices int index = 0; foreach (var row in summaryIndices) { // if this row is missing signal if (row.FileName == IndexMatrices.MissingRowString) { if (isValidBlock) { isValidBlock = false; gap = new GapsAndJoins { StartPosition = index, GapDescription = gapDescriptionMissingData, GapRendering = gapRendering, }; } } else if (!isValidBlock && row.FileName != IndexMatrices.MissingRowString) { // come to end of a bad patch isValidBlock = true; gap.EndPosition = index - 1; gaps.Add(gap); } index++; } // if not OK at end of the array, need to terminate the gap. if (!isValidBlock) { gaps[gaps.Count - 1].EndPosition = index - 1; } return(gaps); }
public static string LongName(this ConcatMode value) { return(I18n.Get("ConcatMode." + Enum.GetName(typeof(ConcatMode), value) + ".LongName")); }
public Root parse(string filename, string[] code) { logger.Debug($"Parsing {filename}"); if (logger.IsTraceEnable) { foreach (var line in code) { logger.Trace(line); } } var startTime = DateTime.Now.Ticks; var ast = new Root(); // Track some state variables for this parsing round. string topic = "random"; // Default topic = random int lineno = 0; bool inComment = false; // In a multi-line comment bool inObject = false; // In an object string objectName = null; // Name of the current object string objectLanguage = null; // Programming language of the object ICollection <string> objectBuffer = null; // Buffer for the current object string onTrigger = null; // Trigger we're on //Trigger currentTriggerObject = null; // Trigger we're on string previous = null; // The a %Previous trigger // File scoped parser options. IDictionary <string, string> local_options = new Dictionary <string, string>(); local_options.AddOrUpdate("concat", "none"); //local_options.Add("concat", "space"); //local_options.Add("concat", "newline"); // The given "code" is an array of lines, so jump right in. for (int i = 0; i < code.Length; i++) { lineno++; // Increment the line counter. string line = code[i] ?? ""; logger.Debug("Original Line: " + line); // Trim the line of whitespaces. line = Util.Strip(line); if (line.Length == 0) { continue; //Skip blank line } // Are we inside an object? if (inObject) { if (line.StartsWith("<object") || line.StartsWith("< object")) { // End of the object. Did we have a handler? if (!string.IsNullOrWhiteSpace(objectName)) { var macro = new ObjectMacro { Code = objectBuffer, Language = objectLanguage, Name = objectName, }; ast.addObject(macro); } objectName = null; objectLanguage = null; objectBuffer = null; inObject = false; } else { // Collect the code. objectBuffer.Add(line); } continue; } // Look for comments. if (line.StartsWith("/*")) { // Beginning a multi-line comment. if (line.IndexOf("*/") > -1) { // It ends on the same line. continue; } inComment = true; } else if (line.StartsWith("//")) { // A single line comment. continue; } else if (line.IndexOf("*/") > -1) { // End a multi-line comment. inComment = false; continue; } if (inComment) //else if? { continue; } // Skip any blank lines and weird lines. if (line.Length < 2) { logger.Warn($"Weird single-character line '#" + line + "' found (in topic #" + topic + ")"); continue; } // Separate the command from the rest of the line. string cmd = line.Substring(0, 1); line = Util.Strip(line.Substring(1)); logger.Debug("\tCmd: " + cmd); // Ignore in-line comments if there's a space before and after the "//". if (line.IndexOf(" // ") > -1) { string[] split = line.Split(new[] { " // " }, StringSplitOptions.None); line = split[0]; //remove space between comment and code line = line.TrimEnd(' '); } // In the event of a +Trigger, if we are force-lowercasing it, then do so // In the event of a +Trigger, if we are force-lowercasing it, then do so // now before the syntax check. if (forceCase && cmd == CMD_TRIGGER) { line = line.ToLower(); } //Run a syntax check on this line try { checkSyntax(cmd, line); } catch (ParserException pex) { if (strict) { throw pex; } else { logger.Warn($"Syntax logger.error(: {pex.Message} at {filename} line {lineno} near {cmd} {line}"); } } // Reset the %Previous if this is a new +Trigger. if (cmd.Equals(CMD_TRIGGER)) { previous = ""; } // Do a look-ahead to see ^Continue and %Previous. if (cmd != CMD_CONTINUE) { for (int j = (i + 1); j < code.Length; j++) { // Peek ahead. string peek = Util.Strip(code[j]); // Skip blank. if (peek.Length == 0) //peek.Length < 2? { continue; } // Get the command. string peekCmd = peek.Substring(0, 1); peek = Util.Strip(peek.Substring(1)); // Only continue if the lookahead line has any data. if (peek.Length > 0) { // The lookahead command has to be a % or a ^ if (!peekCmd.Equals(CMD_CONTINUE) && !peekCmd.Equals(CMD_PREVIOUS)) { break; } // If the current command is a +, see if the following is a %. if (cmd.Equals(CMD_TRIGGER)) { if (peekCmd.Equals(CMD_PREVIOUS)) { // It has a %Previous! previous = peek; break; } else { previous = ""; } } // If the current command is a ! and the next command(s) are // ^, we'll tack each extension on as a "line break". if (cmd.Equals(CMD_DEFINE)) { if (peekCmd.Equals(CMD_CONTINUE)) { line += "<crlf>" + peek; } } // If the current command is not a ^ and the line after is // not a %, but the line after IS a ^, then tack it onto the // end of the current line. if (!cmd.Equals(CMD_CONTINUE) && !cmd.Equals(CMD_PREVIOUS) && !cmd.Equals(CMD_DEFINE)) { if (peekCmd.Equals(CMD_CONTINUE)) { // Concatenation character? ConcatMode concatMode = null; if (local_options.ContainsKey("concat")) { concatMode = ConcatMode.FromName(local_options["concat"]); } if (concatMode == null) { concatMode = concat ?? Config.DEFAULT_CONCAT; } line += concatMode.ConcatChar + peek; } else { break; //?warn } } } } } // Start handling command types. //TODO: change to switch-case if (cmd.Equals(CMD_DEFINE)) { logger.Debug("\t! DEFINE"); //string[] halves = line.split("\\s*=\\s*", 2); string[] halves = new Regex("\\s*=\\s*").Split(line, 2); //string[] left = whatis[0].split("\\s+", 2); string[] left = new Regex("\\s+").Split(halves[0], 2); string value = ""; string kind = ""; //global, var, sub, ... string name = ""; bool delete = false; if (halves.Length == 2) { value = halves[1].Trim(); } if (left.Length >= 1) { kind = left[0]; if (left.Length >= 2) { left = Util.CopyOfRange(left, 1, left.Length); //name = left[1].Trim().ToLower(); name = Util.Join(left, " ").Trim(); } } // Remove line breaks unless this is an array. if (!kind.Equals("array")) { value = value.Replace("<crlf>", ""); } // Version is the only type that doesn't have a var. if (kind.Equals("version")) { logger.Debug("\tUsing RiveScript version " + value); // Convert the value into a double, catch exceptions. double version = 0; try { version = double.Parse(value ?? "", new NumberFormatInfo { CurrencyDecimalSeparator = "." }); } catch (FormatException) { logger.Warn("RiveScript version \"" + value + "\" not a valid floating number", filename, lineno); continue; } if (version > RS_VERSION) { throw new ParserException($"We can't parse RiveScript v {value} documents at {filename} line {lineno}. Only support {RS_VERSION}."); } continue; } else { // All the other types require a variable and value. if (name.Equals("")) { logger.Warn("Missing a " + kind + " variable name", filename, lineno); continue; } if (value.Equals("")) { logger.Warn("Missing a " + kind + " value", filename, lineno); continue; } if (value.Equals(Constants.UNDEF_TAG)) { // Deleting its value. delete = true; } } // Handle the variable set types. //TODO: change to switch-case if (kind.Equals("local")) { // Local file scoped parser options logger.Debug("\tSet local parser option " + name + " = " + value); local_options.AddOrUpdate(name, value); } else if (kind.Equals("global")) { // Is it a special global? (debug or depth or etc). logger.Debug("\tSet global " + name + " = " + value); ast.begin.addGlobals(name, value); } else if (kind.Equals("var")) { // Set a bot variable. logger.Debug("\tSet bot variable " + name + " = " + value); ast.begin.addVar(name, value); } else if (kind.Equals("array")) { // Set an array. logger.Debug("\tSet array " + name); // Deleting it? if (delete) { ast.begin.removeArray(name); continue; } // Did the array have multiple lines? //string[] parts = value.split("<crlf>"); //WARN: string[] parts = value.Split("<crlf>"); ICollection <string> items = new List <string>(); for (int a = 0; a < parts.Length; a++) { // Split at pipes or spaces? string[] pieces; if (parts[a].IndexOf("|") > -1) { //pieces = parts[a].split("\\|"); pieces = new Regex("\\|").Split(parts[a]); } else { pieces = new Regex("\\s+").Split(parts[a]); } // Add the pieces to the final array. for (int b = 0; b < pieces.Length; b++) { items.Add(pieces[b]); } } // Store this array. ast.begin.addArray(name, items); } else if (kind.Equals("sub")) { // Set a substitution. logger.Debug("\tSubstitution " + name + " => " + value); ast.begin.addSub(name, value); } else if (kind.Equals("person")) { // Set a person substitution. logger.Debug("\tPerson substitution " + name + " => " + value); ast.begin.addPerson(name, value); } else { logger.Warn("Unknown definition type \"" + kind + "\"", filename, lineno); continue; } } else if (cmd.Equals(CMD_LABEL)) { // > LABEL logger.Debug("\t> LABEL"); //string[] label = line.split("\\s+"); string[] label = line.SplitRegex("\\s+"); string type = ""; string name = ""; if (label.Length >= 1) { type = label[0].Trim().ToLower(); } if (label.Length >= 2) { name = label[1].Trim(); } // Handle the label types. if (type.Equals("begin")) { // The BEGIN statement. logger.Debug("\tFound the BEGIN Statement."); // A BEGIN is just a special topic. type = "topic"; name = "__begin__"; } if (type.Equals("topic")) { if (forceCase) { name = name.ToLower(); } // Starting a new topic. logger.Debug("\tSet topic to " + name); onTrigger = ""; //currentTriggerObject = null; topic = name; // Does this topic include or inherit another one? if (label.Length >= 3) { int mode_includes = 1; int mode_inherits = 2; int mode = 0; for (int a = 2; a < label.Length; a++) { if (label[a].ToLowerInvariant().Equals("includes")) { mode = mode_includes; } else if (label[a].ToLowerInvariant().Equals("inherits")) { mode = mode_inherits; } else if (mode > 0) { // This topic is either inherited or included. if (mode == mode_includes) { topicManager.topic(topic).includes(label[a]); } else if (mode == mode_inherits) { topicManager.topic(topic).inherits(label[a]); } } } } } if (type.Equals("object")) { // If a field was provided, it should be the programming language. string language = ""; if (label.Length >= 3) { language = label[2].ToLower(); } // Only try to parse a language we support. onTrigger = ""; if (language.Length == 0) { logger.Warn("Trying to parse unknown programming language (assuming it's CSharp)", filename, lineno); language = Constants.CSharpHandlerName; // Assume it's JavaScript } //INFO: to remove? //if (!handlers.ContainsKey(language)) //{ // // We don't have a handler for this language. // logger.debug("We can't handle " + language + " object code!"); // continue; //} // Start collecting its code! objectName = name; objectLanguage = language; objectBuffer = new List <string>(); inObject = true; } } else if (cmd.Equals(CMD_ENDLABEL)) { // < ENDLABEL logger.Debug("\t< ENDLABEL"); string type = line.Trim().ToLower(); if (type.Equals("begin") || type.Equals("topic")) { logger.Debug("\t\tEnd topic label."); topic = "random"; } else if (type.Equals("object")) { logger.Debug("\t\tEnd object label."); inObject = false; } else { logger.Warn("Unknown end topic type \"" + type + "\"", filename, lineno); } } else if (cmd.Equals(CMD_TRIGGER)) { // + TRIGGER logger.Debug("\t+ TRIGGER pattern: " + line); //currentTriggerObject = new Trigger(line); //if (previous.Length > 0) //{ // onTrigger = line + "{previous}" + previous; // currentTriggerObject.setPrevious(true); // topicManager.topic(topic).addPrevious(line, previous); //} //else //{ // onTrigger = line; //} //topicManager.topic(topic).addTrigger(currentTriggerObject); //TODO onld stuff to see if (previous.Length > 0) { // This trigger had a %Previous. To prevent conflict, tag the // trigger with the "that" text. onTrigger = line + "{previous}" + previous; topicManager.topic(topic).trigger(line).setPrevious(true); topicManager.topic(topic).addPrevious(line, previous); } else { // Set the current trigger to this. onTrigger = line; } } else if (cmd.Equals(CMD_REPLY)) { // - REPLY logger.Debug("\t- REPLY: " + line); // This can't come before a trigger! if (onTrigger.Length == 0) { logger.Warn("Reply found before trigger", filename, lineno); continue; } // Warn if we also saw a hard redirect. if (topicManager.topic(topic).trigger(onTrigger).hasRedirect()) { logger.Warn("You can't mix @Redirects with -Replies", filename, lineno); } // Add the reply to the trigger topicManager.topic(topic).trigger(onTrigger).addReply(line); } else if (cmd.Equals(CMD_PREVIOUS)) { // % PREVIOUS // This was handled above. continue; } else if (cmd.Equals(CMD_CONTINUE)) { // ^ CONTINUE // This was handled above. continue; } else if (cmd.Equals(CMD_REDIRECT)) { // @ REDIRECT logger.Debug("\t@ REDIRECT: " + line); // This can't come before a trigger! if (onTrigger.Length == 0) { logger.Warn("Redirect found before trigger", filename, lineno); continue; } // Add the redirect to the trigger. // TODO: this extends RiveScript, not compat w/ Perl yet topicManager.topic(topic).trigger(onTrigger).addRedirect(line); } else if (cmd.Equals(CMD_CONDITION)) { // * CONDITION logger.Debug("\t* CONDITION: " + line); // This can't come before a trigger! if (onTrigger.Length == 0) { logger.Warn("Redirect found before trigger", filename, lineno); continue; } // Add the condition to the trigger. topicManager.topic(topic).trigger(onTrigger).addCondition(line); } else { logger.Warn("Unrecognized command \"" + cmd + "\"", filename, lineno); } } //becouse we use topicmanager to manage topis, we have to fill ast topics foreach (var item in topicManager.listTopics()) { ast.addTopic(item.Value); } if (logger.IsDebugEnable) { logger.Debug($"Parsing {filename} completed in {DateTime.Now.Ticks - startTime} ms"); } return(ast); }
public DbCriteria Like(string table, string fieldname, string fieldvalue, ConcatMode mode) { return(Add(table, fieldname, DbMgr.CreateStringFieldEntry(fieldvalue), DbExpression.SqlCondition.Like, mode)); }
public DbCriteria IsEqual(string table, string fieldname, int?fieldvalue, ConcatMode mode) { return(Add(table, fieldname, DbMgr.CreateIntFieldEntry(fieldvalue), DbExpression.SqlCondition.IsEqual, mode)); }
public DbCriteria Add(string table, string fieldname, DbSelectStatement select_clause, DbExpression.SqlCondition condition, ConcatMode mode) { if (mode == ConcatMode.AND) { And(CreateExpression(table, fieldname, select_clause, condition)); } else if (mode == ConcatMode.OR) { Or(CreateExpression(table, fieldname, select_clause, condition)); } return(this); }
public DbCriteria Add(string table, string fieldname, DbFieldEntry fieldvalue, DbExpression.SqlCondition condition, ConcatMode mode) { if (mode == ConcatMode.AND) { And(CreateExpression(table, fieldname, fieldvalue, condition)); } else if (mode == ConcatMode.OR) { Or(CreateExpression(table, fieldname, fieldvalue, condition)); } return(this); }