/// <summary>
        /// Given a listener that has traversed the tree, extract all the data into a DFS.
        /// </summary>
        /// <param name="parsedState"></param>
        /// <returns></returns>
        private static DetectorFinalState BuildDFS(this FinalStatePatternListener parsedState)
        {
            var result = new DetectorFinalState();

            result.FinalStateObjects.AddRange(parsedState.FSOs);
            result.Criteria.Arguments.AddRange(parsedState.TopLevelCriteria);

            return(result);
        }
        /// <summary>
        /// Return a DFS parsed from the text. Throw if error during parsing.
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static DetectorFinalState Parse(this string text)
        {
            // Lex.
            var input = new AntlrInputStream(text);
            var lexer = new FinalStatePatternLexer(input);
            CommonTokenStream tokens = new CommonTokenStream(lexer);

            // Parse, capture errors.
            var parser = new FinalStatePatternParser(tokens);

            var errors = new ErrorRecorder();

            parser.AddErrorListener(errors);

            var tree = parser.top_level();

            if (errors.Errors.Count > 0)
            {
                string msg = "";
                foreach (var e in errors.Errors)
                {
                    msg += e;
                }
                throw new ArgumentException(msg);
            }

            // Convert to DFS
            var traverser = new FinalStatePatternListener();
            var walker    = new ParseTreeWalker();

            walker.Walk(traverser, tree);

            // And collect the DFS

            return(traverser.BuildDFS());
        }