Beispiel #1
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);
        }
Beispiel #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
         * @param log            the parser error log
         *
         * @return the resulting parse tree node
         */
        public virtual Node Analyze(Node node, ParserLogException log)
        {
            Production prod;
            int        errorCount;

            Node res = null;

            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 {
                    res = Exit(prod);
                    return(res);
                } catch (ParseException e) {
                    if (errorCount == log.Count)
                    {
                        log.AddError(e);
                    }
                }
            }
            else
            {
                node.Values.Clear();
                try {
                    Enter(node);
                } catch (ParseException e) {
                    log.AddError(e);
                }
                try {
                    res = Exit(node);
                    return(res);
                } catch (ParseException e) {
                    if (errorCount == log.Count)
                    {
                        log.AddError(e);
                    }
                }
            }
            return(null);
        }
Beispiel #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 virtual Node Analyze(Node node)
        {
            ParserLogException log = new ParserLogException();

            node = Analyze(node, log);
            if (log.Count > 0)
            {
                throw log;
            }
            return(node);
        }