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