コード例 #1
0
 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;
 }
コード例 #2
0
        /// <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);
        }
コード例 #3
0
        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();
        }
コード例 #4
0
        /// <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);
        }
コード例 #5
0
        /// <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);
        }
コード例 #6
0
        /// <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);
        }
コード例 #7
0
        /// <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);
        }
コード例 #8
0
        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);
                }
            }
        }
コード例 #9
0
        /// <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);
        }
コード例 #10
0
        /// <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);
        }
コード例 #11
0
 public static string LongName(this ConcatMode value)
 {
     return(I18n.Get("ConcatMode." + Enum.GetName(typeof(ConcatMode), value) + ".LongName"));
 }
コード例 #12
0
        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);
        }
コード例 #13
0
 public DbCriteria Like(string table, string fieldname, string fieldvalue, ConcatMode mode)
 {
     return(Add(table, fieldname, DbMgr.CreateStringFieldEntry(fieldvalue), DbExpression.SqlCondition.Like, mode));
 }
コード例 #14
0
 public DbCriteria IsEqual(string table, string fieldname, int?fieldvalue, ConcatMode mode)
 {
     return(Add(table, fieldname, DbMgr.CreateIntFieldEntry(fieldvalue), DbExpression.SqlCondition.IsEqual, mode));
 }
コード例 #15
0
 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);
 }
コード例 #16
0
 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);
 }