/// <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); }
/** * 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; }
/** * 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); }
/** * 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); }
/** * 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; }
/** * 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; }