Example #1
0
        /// <summary>
        /// Parses the token stream and returns a parse tree. This
        /// method will call Prepare() if not previously called. It
        /// will also call the Reset() method, to make sure that only
        /// the Tokenizer.Reset() method must be explicitly called in
        /// order to reuse a parser for multiple input streams. In case
        /// of a parse error, the parser will attempt to recover and
        /// throw all the errors found in a parser log exception in the
        /// end.
        /// </summary>
        /// <returns>The parse tree</returns>
        /// <exception cref="ParserCreationException">
        /// If the parser couldn't be initialized correctly
        /// </exception>
        /// <exception cref="ParserLogException">
        /// If the input couldn't be parsed correctly
        /// </exception>
        /// <see cref="Prepare"/>
        /// <see cref="Reset(TextReader)"/>
        /// <see cref="Tokenizer.Reset(TextReader)"/>
        public Node Parse()
        {
            Node root = null;

            // Initialize parser
            if (!this.initialized)
            {
                this.Prepare();
            }

            this.tokens.Clear();
            this.errorLog      = new ParserLogException();
            this.errorRecovery = -1;

            // Parse input
            try
            {
                root = this.ParseStart();
            }
            catch (ParseException e)
            {
                this.AddError(e, true);
            }

            // Check for errors
            if (this.errorLog.Count > 0)
            {
                throw this.errorLog;
            }

            return(root);
        }
Example #2
0
        /**
         * Analyzes a parse tree node by traversing all it's child nodes.
         * The tree traversal is depth-first, and the appropriate
         * callback methods will be called. If the node is a production
         * node, a new production node will be created and children will
         * be added by recursively processing the children of the
         * specified production node. This method is used to process a
         * parse tree after creation.
         *
         * @param node           the parse tree node to process
         *
         * @return the resulting parse tree node
         *
         * @throws ParserLogException if the node analysis discovered
         *             errors
         */
        public Node Analyze(Node node) {
            ParserLogException  log = new ParserLogException();

            node = Analyze(node, log);
            if (log.Count > 0) {
                throw log;
            }
            return node;
        }
Example #3
0
        /**
         * Analyzes a parse tree node by traversing all it's child nodes.
         * The tree traversal is depth-first, and the appropriate
         * callback methods will be called. If the node is a production
         * node, a new production node will be created and children will
         * be added by recursively processing the children of the
         * specified production node. This method is used to process a
         * parse tree after creation.
         *
         * @param node           the parse tree node to process
         *
         * @return the resulting parse tree node
         *
         * @throws ParserLogException if the node analysis discovered
         *             errors
         */
        public Node Analyze(Node node)
        {
            ParserLogException log = new ParserLogException();

            node = Analyze(node, log);
            if (log.Count > 0)
            {
                throw log;
            }
            return(node);
        }
Example #4
0
        /**
         * Analyzes a parse tree node by traversing all it's child nodes.
         * The tree traversal is depth-first, and the appropriate
         * callback methods will be called. If the node is a production
         * node, a new production node will be created and children will
         * be added by recursively processing the children of the
         * specified production node. This method is used to process a
         * parse tree after creation.
         *
         * @param node           the parse tree node to process
         * @param log            the parser error log
         *
         * @return the resulting parse tree node
         */
        private Node Analyze(Node node, ParserLogException log)
        {
            Production prod;
            int        errorCount;

            errorCount = log.Count;
            if (node is Production)
            {
                prod = (Production)node;
                prod = NewProduction(prod.Pattern);
                try {
                    Enter(prod);
                } catch (ParseException e) {
                    log.AddError(e);
                }
                for (int i = 0; i < node.Count; i++)
                {
                    try {
                        Child(prod, Analyze(node[i], log));
                    } catch (ParseException e) {
                        log.AddError(e);
                    }
                }
                try {
                    return(Exit(prod));
                } catch (ParseException e) {
                    if (errorCount == log.Count)
                    {
                        log.AddError(e);
                    }
                }
            }
            else
            {
                node.Values.Clear();
                try {
                    Enter(node);
                } catch (ParseException e) {
                    log.AddError(e);
                }
                try {
                    return(Exit(node));
                } catch (ParseException e) {
                    if (errorCount == log.Count)
                    {
                        log.AddError(e);
                    }
                }
            }
            return(null);
        }
Example #5
0
        /**
         * Parses the token stream and returns a parse tree. This
         * method will call Prepare() if not previously called. It
         * will also call the Reset() method, to make sure that only
         * the Tokenizer.Reset() method must be explicitly called in
         * order to reuse a parser for multiple input streams. In case
         * of a parse error, the parser will attempt to recover and
         * throw all the errors found in a parser log exception in the
         * end.
         *
         * @return the parse tree
         *
         * @throws ParserCreationException if the parser couldn't be
         *             initialized correctly
         * @throws ParserLogException if the input couldn't be parsed
         *             correctly
         *
         * @see #Prepare
         * @see #Reset
         * @see Tokenizer#Reset
         */
        public Node Parse() {
            Node  root = null;

            // Initialize parser
            if (!initialized) {
                Prepare();
            }
            this.tokens.Clear();
            this.errorLog = new ParserLogException();
            this.errorRecovery = -1;

            // Parse input
            try {
                root = ParseStart();
            } catch (ParseException e) {
                AddError(e, true);
            }

            // Check for errors
            if (errorLog.Count > 0) {
                throw errorLog;
            }

            return root;
        }
Example #6
0
        /**
         * Analyzes a parse tree node by traversing all it's child nodes.
         * The tree traversal is depth-first, and the appropriate
         * callback methods will be called. If the node is a production
         * node, a new production node will be created and children will
         * be added by recursively processing the children of the
         * specified production node. This method is used to process a
         * parse tree after creation.
         *
         * @param node           the parse tree node to process
         * @param log            the parser error log
         *
         * @return the resulting parse tree node
         */
        private Node Analyze(Node node, ParserLogException log) {
            Production  prod;
            int         errorCount;

            errorCount = log.Count;
            if (node is Production) {
                prod = (Production) node;
                prod = NewProduction(prod.Pattern);
                try {
                    Enter(prod);
                } catch (ParseException e) {
                    log.AddError(e);
                }
                for (int i = 0; i < node.Count; i++) {
                    try {
                        Child(prod, Analyze(node[i], log));
                    } catch (ParseException e) {
                        log.AddError(e);
                    }
                }
                try {
                    return Exit(prod);
                } catch (ParseException e) {
                    if (errorCount == log.Count) {
                        log.AddError(e);
                    }
                }
            } else {
                node.Values.Clear();
                try {
                    Enter(node);
                } catch (ParseException e) {
                    log.AddError(e);
                }
                try {
                    return Exit(node);
                } catch (ParseException e) {
                    if (errorCount == log.Count) {
                        log.AddError(e);
                    }
                }
            }
            return null;
        }