KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > javacc > parser > LookaheadCalc


1 /*
2  * Copyright © 2002 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
3  * California 95054, U.S.A. All rights reserved. Sun Microsystems, Inc. has
4  * intellectual property rights relating to technology embodied in the product
5  * that is described in this document. In particular, and without limitation,
6  * these intellectual property rights may include one or more of the U.S.
7  * patents listed at http://www.sun.com/patents and one or more additional
8  * patents or pending patent applications in the U.S. and in other countries.
9  * U.S. Government Rights - Commercial software. Government users are subject
10  * to the Sun Microsystems, Inc. standard license agreement and applicable
11  * provisions of the FAR and its supplements. Use is subject to license terms.
12  * Sun, Sun Microsystems, the Sun logo and Java are trademarks or registered
13  * trademarks of Sun Microsystems, Inc. in the U.S. and other countries. This
14  * product is covered and controlled by U.S. Export Control laws and may be
15  * subject to the export or import laws in other countries. Nuclear, missile,
16  * chemical biological weapons or nuclear maritime end uses or end users,
17  * whether direct or indirect, are strictly prohibited. Export or reexport
18  * to countries subject to U.S. embargo or to entities identified on U.S.
19  * export exclusion lists, including, but not limited to, the denied persons
20  * and specially designated nationals lists is strictly prohibited.
21  */

22
23 package org.javacc.parser;
24
25 import java.util.Vector JavaDoc;
26
27 public class LookaheadCalc extends JavaCCGlobals {
28
29   static MatchInfo overlap(Vector JavaDoc v1, Vector JavaDoc v2) {
30     MatchInfo m1, m2, m3;
31     int size;
32     boolean diff;
33     for (int i = 0; i < v1.size(); i++) {
34       m1 = (MatchInfo)v1.elementAt(i);
35       for (int j = 0; j < v2.size(); j++) {
36         m2 = (MatchInfo)v2.elementAt(j);
37         size = m1.firstFreeLoc; m3 = m1;
38         if (size > m2.firstFreeLoc) {
39           size = m2.firstFreeLoc; m3 = m2;
40         }
41         if (size == 0) return null;
42         // we wish to ignore empty expansions and the JAVACODE stuff here.
43
diff = false;
44         for (int k = 0; k < size; k++) {
45           if (m1.match[k] != m2.match[k]) {
46             diff = true;
47             break;
48           }
49         }
50         if (!diff) return m3;
51       }
52     }
53     return null;
54   }
55
56   static boolean javaCodeCheck(Vector JavaDoc v) {
57     for (int i = 0; i < v.size(); i++) {
58       if (((MatchInfo)v.elementAt(i)).firstFreeLoc == 0) {
59         return true;
60       }
61     }
62     return false;
63   }
64
65   static String JavaDoc image(MatchInfo m) {
66     String JavaDoc ret = "";
67     for (int i = 0; i < m.firstFreeLoc; i++) {
68       if (m.match[i] == 0) {
69         ret += " <EOF>";
70       } else {
71         RegularExpression re = (RegularExpression)rexps_of_tokens.get(new Integer JavaDoc(m.match[i]));
72         if (re instanceof RStringLiteral) {
73           ret += " \"" + add_escapes(((RStringLiteral)re).image) + "\"";
74         } else if (re.label != null && !re.label.equals("")) {
75           ret += " <" + re.label + ">";
76         } else {
77           ret += " <token of kind " + i + ">";
78         }
79       }
80     }
81     if (m.firstFreeLoc == 0) {
82       return "";
83     } else {
84       return ret.substring(1);
85     }
86   }
87
88   public static void choiceCalc(Choice ch) {
89     int first = firstChoice(ch);
90     // dbl[i] and dbr[i] are vectors of size limited matches for choice i
91
// of ch. dbl ignores matches with semantic lookaheads (when force_la_check
92
// is false), while dbr ignores semantic lookahead.
93
Vector JavaDoc[] dbl = new Vector JavaDoc[ch.choices.size()];
94     Vector JavaDoc[] dbr = new Vector JavaDoc[ch.choices.size()];
95     int[] minLA = new int[ch.choices.size()-1];
96     MatchInfo[] overlapInfo = new MatchInfo[ch.choices.size()-1];
97     int[] other = new int[ch.choices.size()-1];
98     MatchInfo m;
99     Vector JavaDoc v;
100     boolean overlapDetected;
101     for (int la = 1; la <= Options.getChoiceAmbiguityCheck(); la++) {
102       MatchInfo.laLimit = la;
103       LookaheadWalk.considerSemanticLA = !Options.getForceLaCheck();
104       for (int i = first; i < ch.choices.size()-1; i++) {
105         LookaheadWalk.sizeLimitedMatches = new java.util.Vector JavaDoc();
106         m = new MatchInfo();
107         m.firstFreeLoc = 0;
108         v = new java.util.Vector JavaDoc();
109         v.addElement(m);
110         LookaheadWalk.genFirstSet(v, (Expansion)ch.choices.elementAt(i));
111         dbl[i] = LookaheadWalk.sizeLimitedMatches;
112       }
113       LookaheadWalk.considerSemanticLA = false;
114       for (int i = first+1; i < ch.choices.size(); i++) {
115         LookaheadWalk.sizeLimitedMatches = new java.util.Vector JavaDoc();
116         m = new MatchInfo();
117         m.firstFreeLoc = 0;
118         v = new java.util.Vector JavaDoc();
119         v.addElement(m);
120         LookaheadWalk.genFirstSet(v, (Expansion)ch.choices.elementAt(i));
121         dbr[i] = LookaheadWalk.sizeLimitedMatches;
122       }
123       if (la == 1) {
124         for (int i = first; i < ch.choices.size()-1; i++) {
125           Expansion exp = (Expansion)ch.choices.elementAt(i);
126           if (Semanticize.emptyExpansionExists(exp)) {
127             JavaCCErrors.warning(exp, "This choice can expand to the empty token sequence and will therefore always be taken in favor of the choices appearing later.");
128             break;
129           } else if (javaCodeCheck(dbl[i])) {
130             JavaCCErrors.warning(exp, "JAVACODE non-terminal will force this choice to be taken in favor of the choices appearing later.");
131             break;
132           }
133         }
134       }
135       overlapDetected = false;
136       for (int i = first; i < ch.choices.size()-1; i++) {
137         for (int j = i+1; j < ch.choices.size(); j++) {
138           if ((m = overlap(dbl[i], dbr[j])) != null) {
139             minLA[i] = la+1;
140             overlapInfo[i] = m;
141             other[i] = j;
142             overlapDetected = true;
143             break;
144           }
145         }
146       }
147       if (!overlapDetected) {
148         break;
149       }
150     }
151     for (int i = first; i < ch.choices.size()-1; i++) {
152       if (explicitLA((Expansion)ch.choices.elementAt(i)) && !Options.getForceLaCheck()) {
153         continue;
154       }
155       if (minLA[i] > Options.getChoiceAmbiguityCheck()) {
156         JavaCCErrors.warning("Choice conflict involving two expansions at");
157         System.err.print(" line " + ((Expansion)ch.choices.elementAt(i)).line);
158         System.err.print(", column " + ((Expansion)ch.choices.elementAt(i)).column);
159         System.err.print(" and line " + ((Expansion)ch.choices.elementAt(other[i])).line);
160         System.err.print(", column " + ((Expansion)ch.choices.elementAt(other[i])).column);
161         System.err.println(" respectively.");
162         System.err.println(" A common prefix is: " + image(overlapInfo[i]));
163         System.err.println(" Consider using a lookahead of " + minLA[i] + " or more for earlier expansion.");
164       } else if (minLA[i] > 1) {
165         JavaCCErrors.warning("Choice conflict involving two expansions at");
166         System.err.print(" line " + ((Expansion)ch.choices.elementAt(i)).line);
167         System.err.print(", column " + ((Expansion)ch.choices.elementAt(i)).column);
168         System.err.print(" and line " + ((Expansion)ch.choices.elementAt(other[i])).line);
169         System.err.print(", column " + ((Expansion)ch.choices.elementAt(other[i])).column);
170         System.err.println(" respectively.");
171         System.err.println(" A common prefix is: " + image(overlapInfo[i]));
172         System.err.println(" Consider using a lookahead of " + minLA[i] + " for earlier expansion.");
173       }
174     }
175   }
176
177   static boolean explicitLA(Expansion exp) {
178     if (!(exp instanceof Sequence)) {
179       return false;
180     }
181     Sequence seq = (Sequence)exp;
182     Object JavaDoc obj = seq.units.elementAt(0);
183     if (!(obj instanceof Lookahead)) {
184       return false;
185     }
186     Lookahead la = (Lookahead)obj;
187     return la.isExplicit;
188   }
189
190   static int firstChoice(Choice ch) {
191     if (Options.getForceLaCheck()) {
192       return 0;
193     }
194     for (int i = 0; i < ch.choices.size(); i++) {
195       if (!explicitLA((Expansion)ch.choices.elementAt(i))) {
196         return i;
197       }
198     }
199     return ch.choices.size();
200   }
201
202   private static String JavaDoc image(Expansion exp) {
203     if (exp instanceof OneOrMore) {
204       return "(...)+";
205     } else if (exp instanceof ZeroOrMore) {
206       return "(...)*";
207     } else /* if (exp instanceof ZeroOrOne) */ {
208       return "[...]";
209     }
210   }
211
212   public static void ebnfCalc(Expansion exp, Expansion nested) {
213     // exp is one of OneOrMore, ZeroOrMore, ZeroOrOne
214
MatchInfo m, m1 = null;
215     Vector JavaDoc v, first, follow;
216     int la;
217     for (la = 1; la <= Options.getOtherAmbiguityCheck(); la++) {
218       MatchInfo.laLimit = la;
219       LookaheadWalk.sizeLimitedMatches = new java.util.Vector JavaDoc();
220       m = new MatchInfo();
221       m.firstFreeLoc = 0;
222       v = new java.util.Vector JavaDoc();
223       v.addElement(m);
224       LookaheadWalk.considerSemanticLA = !Options.getForceLaCheck();
225       LookaheadWalk.genFirstSet(v, nested);
226       first = LookaheadWalk.sizeLimitedMatches;
227       LookaheadWalk.sizeLimitedMatches = new java.util.Vector JavaDoc();
228       LookaheadWalk.considerSemanticLA = false;
229       LookaheadWalk.genFollowSet(v, exp, Expansion.nextGenerationIndex++);
230       follow = LookaheadWalk.sizeLimitedMatches;
231       if (la == 1) {
232         if (javaCodeCheck(first)) {
233           JavaCCErrors.warning(nested, "JAVACODE non-terminal within " + image(exp) + " construct will force this construct to be entered in favor of expansions occurring after construct.");
234         }
235       }
236       if ((m = overlap(first, follow)) == null) {
237         break;
238       }
239       m1 = m;
240     }
241     if (la > Options.getOtherAmbiguityCheck()) {
242       JavaCCErrors.warning("Choice conflict in " + image(exp) + " construct at line " + exp.line + ", column " + exp.column + ".");
243       System.err.println(" Expansion nested within construct and expansion following construct");
244       System.err.println(" have common prefixes, one of which is: " + image(m1));
245       System.err.println(" Consider using a lookahead of " + la + " or more for nested expansion.");
246     } else if (la > 1) {
247       JavaCCErrors.warning("Choice conflict in " + image(exp) + " construct at line " + exp.line + ", column " + exp.column + ".");
248       System.err.println(" Expansion nested within construct and expansion following construct");
249       System.err.println(" have common prefixes, one of which is: " + image(m1));
250       System.err.println(" Consider using a lookahead of " + la + " for nested expansion.");
251     }
252   }
253
254 }
255
Popular Tags