public virtual GrammarAST GetNodeWithTokenIndex(int index) { if (this.Token != null && this.Token.TokenIndex == index) { return(this); } // walk all children of root. for (int i = 0; i < ChildCount; i++) { GrammarAST child = (GrammarAST)GetChild(i); GrammarAST result = child.GetNodeWithTokenIndex(index); if (result != null) { return(result); } } return(null); }
public virtual string Text(GrammarAST t) { if (t == null) return ""; int tokenStartIndex = t.TokenStartIndex; int tokenStopIndex = t.TokenStopIndex; // ignore tokens from existing option subtrees like: // (ELEMENT_OPTIONS (= assoc right)) // // element options are added back according to the values in the map // returned by getOptions(). IntervalSet ignore = new IntervalSet(); IList<GrammarAST> optionsSubTrees = t.GetNodesWithType(ELEMENT_OPTIONS); foreach (GrammarAST sub in optionsSubTrees) { ignore.Add(sub.TokenStartIndex, sub.TokenStopIndex); } // Individual labels appear as RULE_REF or TOKEN_REF tokens in the tree, // but do not support the ELEMENT_OPTIONS syntax. Make sure to not try // and add the tokenIndex option when writing these tokens. IntervalSet noOptions = new IntervalSet(); IList<GrammarAST> labeledSubTrees = t.GetNodesWithType(new IntervalSet(ASSIGN, PLUS_ASSIGN)); foreach (GrammarAST sub in labeledSubTrees) { noOptions.Add(sub.GetChild(0).TokenStartIndex); } StringBuilder buf = new StringBuilder(); int i = tokenStartIndex; while (i <= tokenStopIndex) { if (ignore.Contains(i)) { i++; continue; } IToken tok = tokenStream.Get(i); // Compute/hold any element options StringBuilder elementOptions = new StringBuilder(); if (!noOptions.Contains(i)) { GrammarAST node = t.GetNodeWithTokenIndex(tok.TokenIndex); if (node != null && (tok.Type == TOKEN_REF || tok.Type == STRING_LITERAL || tok.Type == RULE_REF)) { elementOptions.Append("tokenIndex=").Append(tok.TokenIndex); } if (node is GrammarASTWithOptions) { GrammarASTWithOptions o = (GrammarASTWithOptions)node; foreach (KeyValuePair<string, GrammarAST> entry in o.GetOptions()) { if (elementOptions.Length > 0) { elementOptions.Append(','); } elementOptions.Append(entry.Key); elementOptions.Append('='); elementOptions.Append(entry.Value.Text); } } } buf.Append(tok.Text); // add actual text of the current token to the rewritten alternative i++; // move to the next token // Are there args on a rule? if (tok.Type == RULE_REF && i <= tokenStopIndex && tokenStream.Get(i).Type == ARG_ACTION) { buf.Append('[' + tokenStream.Get(i).Text + ']'); i++; } // now that we have the actual element, we can add the options. if (elementOptions.Length > 0) { buf.Append('<').Append(elementOptions).Append('>'); } } return buf.ToString(); }