001: package fri.patterns.interpreter.parsergenerator.lexer;
002:
003: import java.util.*;
004: import fri.patterns.interpreter.parsergenerator.Token;
005: import fri.patterns.interpreter.parsergenerator.syntax.Rule;
006:
007: /**
008: Lexer result tree element, holding texts, its line/column range, and result children.
009:
010: @author Fritz Ritzberger, 2003
011: */
012:
013: public class ResultTree {
014: private Rule rule;
015: private List sequenceList;
016: private Token.Range range;
017: private StringBuffer buffer;
018: private String stringResult;
019:
020: ResultTree(Rule rule) {
021: this .rule = rule;
022: }
023:
024: /** Returns the character- or byte-range within input where the token was found. */
025: public Token.Range getRange() {
026: return range;
027: }
028:
029: void setRange(Token.Range range) {
030: this .range = range;
031: }
032:
033: /** Returns true if this ResultTree or any of its children has text. */
034: public boolean hasText() {
035: for (int i = 0; sequenceList != null && i < sequenceList.size(); i++) {
036: Object o = sequenceList.get(i);
037: if (o instanceof ResultTree == false)
038: return true; // StringBuffer was allocated with minimum one char
039: else if (((ResultTree) o).hasText())
040: return true;
041: }
042: return false;
043: }
044:
045: /** Returns the String text of this ResultTree, including any text of its children. */
046: public String toString() {
047: if (stringResult == null) {
048: StringBuffer sb = new StringBuffer();
049: for (int i = 0; sequenceList != null
050: && i < sequenceList.size(); i++) {
051: Object o = sequenceList.get(i);
052: if (o instanceof ResultTree)
053: sb.append(((ResultTree) o).toString());
054: else
055: sb.append(o.toString());
056: // since JDK 1.4: sb.append((StringBuffer) o); // is faster than o.toString()
057: }
058: stringResult = sb.toString();
059: }
060: return stringResult;
061: }
062:
063: /** Returns the rule this ResultTree was built from. */
064: public Rule getRule() {
065: return rule;
066: }
067:
068: /** Returns the child at index i of this element, which could be StringBuffer or ResultTree. */
069: public Object getChild(int i) {
070: Object o = sequenceList.get(i);
071: return o instanceof StringBuffer ? o.toString() : o; // avoid StringBuffer.append calls
072: }
073:
074: /** Returns the count of children of this element. */
075: public int getChildCount() {
076: return sequenceList != null ? sequenceList.size() : 0;
077: }
078:
079: ResultTree append(char c) {
080: ensureStringBuffer(null).append(c);
081: return this ;
082: }
083:
084: ResultTree append(String s) {
085: ensureStringBuffer(s);
086: return this ;
087: }
088:
089: ResultTree addChild(ResultTree r) {
090: if (r.hasText()) {
091: ensureSequenceList().add(r);
092: buffer = null; // force new list element
093: }
094: return this ;
095: }
096:
097: private List ensureSequenceList() {
098: if (sequenceList == null)
099: sequenceList = new ArrayList(rule != null ? rule
100: .rightSize() : 1);
101: return sequenceList;
102: }
103:
104: private StringBuffer ensureStringBuffer(String toStore) {
105: if (buffer == null) {
106: if (toStore == null)
107: buffer = new StringBuffer(8);
108: else
109: buffer = new StringBuffer(toStore);
110: ensureSequenceList().add(buffer);
111: } else if (toStore != null) {
112: buffer.append(toStore);
113: }
114: return buffer;
115: }
116:
117: }
|