001: package persistence.antlr;
002:
003: /* ANTLR Translator Generator
004: * Project led by Terence Parr at http://www.jGuru.com
005: * Software rights: http://www.antlr.org/license.html
006: *
007: */
008:
009: import persistence.antlr.collections.impl.Vector;
010:
011: /**A list of alternatives */
012: class AlternativeBlock extends AlternativeElement {
013: protected String initAction = null; // string for init action {...}
014: protected Vector alternatives; // Contains Alternatives
015:
016: protected String label; // can label a looping block to break out of it.
017:
018: protected int alti, altj; // which alts are being compared at the moment with
019: // deterministic()?
020: protected int analysisAlt; // which alt are we computing look on? Must be alti or altj
021:
022: protected boolean hasAnAction = false; // does any alt have an action?
023: protected boolean hasASynPred = false; // does any alt have a syntactic predicate?
024:
025: protected int ID = 0; // used to generate unique variables
026: protected static int nblks; // how many blocks have we allocated?
027: boolean not = false; // true if block is inverted.
028:
029: boolean greedy = true; // Blocks are greedy by default
030: boolean greedySet = false; // but, if not explicitly greedy, warning might be generated
031:
032: protected boolean doAutoGen = true; // false if no AST (or text) to be generated for block
033:
034: protected boolean warnWhenFollowAmbig = true; // warn when an empty path or exit path
035:
036: protected boolean generateAmbigWarnings = true; // the general warning "shut-up" mechanism
037:
038: // conflicts with alt of subrule.
039: // Turning this off will suppress stuff
040: // like the if-then-else ambig.
041:
042: public AlternativeBlock(Grammar g) {
043: super (g);
044: alternatives = new Vector(5);
045: this .not = false;
046: nblks++;
047: ID = nblks;
048: }
049:
050: public AlternativeBlock(Grammar g, Token start, boolean not) {
051: super (g, start);
052: alternatives = new Vector(5);
053: // this.line = start.getLine();
054: // this.column = start.getColumn();
055: this .not = not;
056: nblks++;
057: ID = nblks;
058: }
059:
060: public void addAlternative(Alternative alt) {
061: alternatives.appendElement(alt);
062: }
063:
064: public void generate() {
065: grammar.generator.gen(this );
066: }
067:
068: public Alternative getAlternativeAt(int i) {
069: return (Alternative) alternatives.elementAt(i);
070: }
071:
072: public Vector getAlternatives() {
073: return alternatives;
074: }
075:
076: public boolean getAutoGen() {
077: return doAutoGen;
078: }
079:
080: public String getInitAction() {
081: return initAction;
082: }
083:
084: public String getLabel() {
085: return label;
086: }
087:
088: public Lookahead look(int k) {
089: return grammar.theLLkAnalyzer.look(k, this );
090: }
091:
092: public void prepareForAnalysis() {
093: for (int i = 0; i < alternatives.size(); i++) {
094: // deterministic() uses an alternative cache and sets lookahead depth
095: Alternative a = (Alternative) alternatives.elementAt(i);
096: a.cache = new Lookahead[grammar.maxk + 1];
097: a.lookaheadDepth = GrammarAnalyzer.LOOKAHEAD_DEPTH_INIT;
098: }
099: }
100:
101: /**Walk the syntactic predicate and, for a rule ref R, remove
102: * the ref from the list of FOLLOW references for R (stored
103: * in the symbol table.
104: */
105: public void removeTrackingOfRuleRefs(Grammar g) {
106: for (int i = 0; i < alternatives.size(); i++) {
107: Alternative alt = getAlternativeAt(i);
108: AlternativeElement elem = alt.head;
109: while (elem != null) {
110: if (elem instanceof RuleRefElement) {
111: RuleRefElement rr = (RuleRefElement) elem;
112: RuleSymbol rs = (RuleSymbol) g
113: .getSymbol(rr.targetRule);
114: if (rs == null) {
115: grammar.antlrTool
116: .error("rule "
117: + rr.targetRule
118: + " referenced in (...)=>, but not defined");
119: } else {
120: rs.references.removeElement(rr);
121: }
122: } else if (elem instanceof AlternativeBlock) {// recurse into subrules
123: ((AlternativeBlock) elem)
124: .removeTrackingOfRuleRefs(g);
125: }
126: elem = elem.next;
127: }
128: }
129: }
130:
131: public void setAlternatives(Vector v) {
132: alternatives = v;
133: }
134:
135: public void setAutoGen(boolean doAutoGen_) {
136: doAutoGen = doAutoGen_;
137: }
138:
139: public void setInitAction(String initAction_) {
140: initAction = initAction_;
141: }
142:
143: public void setLabel(String label_) {
144: label = label_;
145: }
146:
147: public void setOption(Token key, Token value) {
148: if (key.getText().equals("warnWhenFollowAmbig")) {
149: if (value.getText().equals("true")) {
150: warnWhenFollowAmbig = true;
151: } else if (value.getText().equals("false")) {
152: warnWhenFollowAmbig = false;
153: } else {
154: grammar.antlrTool
155: .error(
156: "Value for warnWhenFollowAmbig must be true or false",
157: grammar.getFilename(), key.getLine(),
158: key.getColumn());
159: }
160: } else if (key.getText().equals("generateAmbigWarnings")) {
161: if (value.getText().equals("true")) {
162: generateAmbigWarnings = true;
163: } else if (value.getText().equals("false")) {
164: generateAmbigWarnings = false;
165: } else {
166: grammar.antlrTool
167: .error(
168: "Value for generateAmbigWarnings must be true or false",
169: grammar.getFilename(), key.getLine(),
170: key.getColumn());
171: }
172: } else if (key.getText().equals("greedy")) {
173: if (value.getText().equals("true")) {
174: greedy = true;
175: greedySet = true;
176: } else if (value.getText().equals("false")) {
177: greedy = false;
178: greedySet = true;
179: } else {
180: grammar.antlrTool.error(
181: "Value for greedy must be true or false",
182: grammar.getFilename(), key.getLine(), key
183: .getColumn());
184: }
185: } else {
186: grammar.antlrTool.error("Invalid subrule option: "
187: + key.getText(), grammar.getFilename(), key
188: .getLine(), key.getColumn());
189: }
190: }
191:
192: public String toString() {
193: String s = " (";
194: if (initAction != null) {
195: s += initAction;
196: }
197: for (int i = 0; i < alternatives.size(); i++) {
198: Alternative alt = getAlternativeAt(i);
199: Lookahead cache[] = alt.cache;
200: int k = alt.lookaheadDepth;
201: // dump lookahead set
202: if (k == GrammarAnalyzer.LOOKAHEAD_DEPTH_INIT) {
203: } else if (k == GrammarAnalyzer.NONDETERMINISTIC) {
204: s += "{?}:";
205: } else {
206: s += " {";
207: for (int j = 1; j <= k; j++) {
208: s += cache[j].toString(",", grammar.tokenManager
209: .getVocabulary());
210: if (j < k && cache[j + 1] != null)
211: s += ";";
212: }
213: s += "}:";
214: }
215: // dump alternative including pred (if any)
216: AlternativeElement p = alt.head;
217: String pred = alt.semPred;
218: if (pred != null) {
219: s += pred;
220: }
221: while (p != null) {
222: s += p;
223: p = p.next;
224: }
225: if (i < (alternatives.size() - 1)) {
226: s += " |";
227: }
228: }
229: s += " )";
230: return s;
231: }
232:
233: }
|