Initial commit
This commit is contained in:
261
csjavacc/parser/LookaheadCalc.java
Normal file
261
csjavacc/parser/LookaheadCalc.java
Normal file
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* Copyright © 2002 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* California 95054, U.S.A. All rights reserved. Sun Microsystems, Inc. has
|
||||
* intellectual property rights relating to technology embodied in the product
|
||||
* that is described in this document. In particular, and without limitation,
|
||||
* these intellectual property rights may include one or more of the U.S.
|
||||
* patents listed at http://www.sun.com/patents and one or more additional
|
||||
* patents or pending patent applications in the U.S. and in other countries.
|
||||
* U.S. Government Rights - Commercial software. Government users are subject
|
||||
* to the Sun Microsystems, Inc. standard license agreement and applicable
|
||||
* provisions of the FAR and its supplements. Use is subject to license terms.
|
||||
* Sun, Sun Microsystems, the Sun logo and Java are trademarks or registered
|
||||
* trademarks of Sun Microsystems, Inc. in the U.S. and other countries. This
|
||||
* product is covered and controlled by U.S. Export Control laws and may be
|
||||
* subject to the export or import laws in other countries. Nuclear, missile,
|
||||
* chemical biological weapons or nuclear maritime end uses or end users,
|
||||
* whether direct or indirect, are strictly prohibited. Export or reexport
|
||||
* to countries subject to U.S. embargo or to entities identified on U.S.
|
||||
* export exclusion lists, including, but not limited to, the denied persons
|
||||
* and specially designated nationals lists is strictly prohibited.
|
||||
*/
|
||||
|
||||
package csjavacc.parser;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
import csjavacc.struct.Choice;
|
||||
import csjavacc.struct.Expansion;
|
||||
import csjavacc.struct.Lookahead;
|
||||
import csjavacc.struct.MatchInfo;
|
||||
import csjavacc.struct.RegularExpression;
|
||||
import csjavacc.struct.ZeroOrMore;
|
||||
|
||||
public class LookaheadCalc extends CSJavaCCGlobals {
|
||||
|
||||
static MatchInfo overlap(Vector v1, Vector v2) {
|
||||
MatchInfo m1, m2, m3;
|
||||
int size;
|
||||
boolean diff;
|
||||
for (int i = 0; i < v1.size(); i++) {
|
||||
m1 = (MatchInfo)v1.elementAt(i);
|
||||
for (int j = 0; j < v2.size(); j++) {
|
||||
m2 = (MatchInfo)v2.elementAt(j);
|
||||
size = m1.firstFreeLoc; m3 = m1;
|
||||
if (size > m2.firstFreeLoc) {
|
||||
size = m2.firstFreeLoc; m3 = m2;
|
||||
}
|
||||
if (size == 0) return null;
|
||||
// we wish to ignore empty expansions and the CSCODE stuff here.
|
||||
diff = false;
|
||||
for (int k = 0; k < size; k++) {
|
||||
if (m1.match[k] != m2.match[k]) {
|
||||
diff = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!diff) return m3;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static boolean csCodeCheck(Vector v) {
|
||||
for (int i = 0; i < v.size(); i++) {
|
||||
if (((MatchInfo)v.elementAt(i)).firstFreeLoc == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static String image(MatchInfo m) {
|
||||
String ret = "";
|
||||
for (int i = 0; i < m.firstFreeLoc; i++) {
|
||||
if (m.match[i] == 0) {
|
||||
ret += " <EOF>";
|
||||
} else {
|
||||
RegularExpression re = (RegularExpression)rexps_of_tokens.get(new Integer(m.match[i]));
|
||||
if (re instanceof RStringLiteral) {
|
||||
ret += " \"" + add_escapes(((RStringLiteral)re).image) + "\"";
|
||||
} else if (re.label != null && !re.label.equals("")) {
|
||||
ret += " <" + re.label + ">";
|
||||
} else {
|
||||
ret += " <token of kind " + i + ">";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m.firstFreeLoc == 0) {
|
||||
return "";
|
||||
} else {
|
||||
return ret.substring(1);
|
||||
}
|
||||
}
|
||||
|
||||
public static void choiceCalc(Choice ch) {
|
||||
int first = firstChoice(ch);
|
||||
// dbl[i] and dbr[i] are vectors of size limited matches for choice i
|
||||
// of ch. dbl ignores matches with semantic lookaheads (when force_la_check
|
||||
// is false), while dbr ignores semantic lookahead.
|
||||
Vector[] dbl = new Vector[ch.choices.size()];
|
||||
Vector[] dbr = new Vector[ch.choices.size()];
|
||||
int[] minLA = new int[ch.choices.size()-1];
|
||||
MatchInfo[] overlapInfo = new MatchInfo[ch.choices.size()-1];
|
||||
int[] other = new int[ch.choices.size()-1];
|
||||
MatchInfo m;
|
||||
Vector v;
|
||||
boolean overlapDetected;
|
||||
for (int la = 1; la <= Options.getChoiceAmbiguityCheck(); la++) {
|
||||
MatchInfo.laLimit = la;
|
||||
LookaheadWalk.considerSemanticLA = !Options.getForceLaCheck();
|
||||
for (int i = first; i < ch.choices.size()-1; i++) {
|
||||
LookaheadWalk.sizeLimitedMatches = new java.util.Vector();
|
||||
m = new MatchInfo();
|
||||
m.firstFreeLoc = 0;
|
||||
v = new java.util.Vector();
|
||||
v.addElement(m);
|
||||
LookaheadWalk.genFirstSet(v, (Expansion)ch.choices.elementAt(i));
|
||||
dbl[i] = LookaheadWalk.sizeLimitedMatches;
|
||||
}
|
||||
LookaheadWalk.considerSemanticLA = false;
|
||||
for (int i = first+1; i < ch.choices.size(); i++) {
|
||||
LookaheadWalk.sizeLimitedMatches = new java.util.Vector();
|
||||
m = new MatchInfo();
|
||||
m.firstFreeLoc = 0;
|
||||
v = new java.util.Vector();
|
||||
v.addElement(m);
|
||||
LookaheadWalk.genFirstSet(v, (Expansion)ch.choices.elementAt(i));
|
||||
dbr[i] = LookaheadWalk.sizeLimitedMatches;
|
||||
}
|
||||
if (la == 1) {
|
||||
for (int i = first; i < ch.choices.size()-1; i++) {
|
||||
Expansion exp = (Expansion)ch.choices.elementAt(i);
|
||||
if (Semanticize.emptyExpansionExists(exp)) {
|
||||
CSJavaCCErrors.warning(exp, "This choice can expand to the empty token sequence and will therefore always be taken in favor of the choices appearing later.");
|
||||
break;
|
||||
} else if (csCodeCheck(dbl[i])) {
|
||||
CSJavaCCErrors.warning(exp, "CSCODE non-terminal will force this choice to be taken in favor of the choices appearing later.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
overlapDetected = false;
|
||||
for (int i = first; i < ch.choices.size()-1; i++) {
|
||||
for (int j = i+1; j < ch.choices.size(); j++) {
|
||||
if ((m = overlap(dbl[i], dbr[j])) != null) {
|
||||
minLA[i] = la+1;
|
||||
overlapInfo[i] = m;
|
||||
other[i] = j;
|
||||
overlapDetected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!overlapDetected) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int i = first; i < ch.choices.size()-1; i++) {
|
||||
if (explicitLA((Expansion)ch.choices.elementAt(i)) && !Options.getForceLaCheck()) {
|
||||
continue;
|
||||
}
|
||||
if (minLA[i] > Options.getChoiceAmbiguityCheck()) {
|
||||
CSJavaCCErrors.warning("Choice conflict involving two expansions at");
|
||||
System.err.print(" line " + ((Expansion)ch.choices.elementAt(i)).line);
|
||||
System.err.print(", column " + ((Expansion)ch.choices.elementAt(i)).column);
|
||||
System.err.print(" and line " + ((Expansion)ch.choices.elementAt(other[i])).line);
|
||||
System.err.print(", column " + ((Expansion)ch.choices.elementAt(other[i])).column);
|
||||
System.err.println(" respectively.");
|
||||
System.err.println(" A common prefix is: " + image(overlapInfo[i]));
|
||||
System.err.println(" Consider using a lookahead of " + minLA[i] + " or more for earlier expansion.");
|
||||
} else if (minLA[i] > 1) {
|
||||
CSJavaCCErrors.warning("Choice conflict involving two expansions at");
|
||||
System.err.print(" line " + ((Expansion)ch.choices.elementAt(i)).line);
|
||||
System.err.print(", column " + ((Expansion)ch.choices.elementAt(i)).column);
|
||||
System.err.print(" and line " + ((Expansion)ch.choices.elementAt(other[i])).line);
|
||||
System.err.print(", column " + ((Expansion)ch.choices.elementAt(other[i])).column);
|
||||
System.err.println(" respectively.");
|
||||
System.err.println(" A common prefix is: " + image(overlapInfo[i]));
|
||||
System.err.println(" Consider using a lookahead of " + minLA[i] + " for earlier expansion.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static boolean explicitLA(Expansion exp) {
|
||||
if (!(exp instanceof Sequence)) {
|
||||
return false;
|
||||
}
|
||||
Sequence seq = (Sequence)exp;
|
||||
Object obj = seq.units.elementAt(0);
|
||||
if (!(obj instanceof Lookahead)) {
|
||||
return false;
|
||||
}
|
||||
Lookahead la = (Lookahead)obj;
|
||||
return la.isExplicit;
|
||||
}
|
||||
|
||||
static int firstChoice(Choice ch) {
|
||||
if (Options.getForceLaCheck()) {
|
||||
return 0;
|
||||
}
|
||||
for (int i = 0; i < ch.choices.size(); i++) {
|
||||
if (!explicitLA((Expansion)ch.choices.elementAt(i))) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return ch.choices.size();
|
||||
}
|
||||
|
||||
private static String image(Expansion exp) {
|
||||
if (exp instanceof OneOrMore) {
|
||||
return "(...)+";
|
||||
} else if (exp instanceof ZeroOrMore) {
|
||||
return "(...)*";
|
||||
} else /* if (exp instanceof ZeroOrOne) */ {
|
||||
return "[...]";
|
||||
}
|
||||
}
|
||||
|
||||
public static void ebnfCalc(Expansion exp, Expansion nested) {
|
||||
// exp is one of OneOrMore, ZeroOrMore, ZeroOrOne
|
||||
MatchInfo m, m1 = null;
|
||||
Vector v, first, follow;
|
||||
int la;
|
||||
for (la = 1; la <= Options.getOtherAmbiguityCheck(); la++) {
|
||||
MatchInfo.laLimit = la;
|
||||
LookaheadWalk.sizeLimitedMatches = new java.util.Vector();
|
||||
m = new MatchInfo();
|
||||
m.firstFreeLoc = 0;
|
||||
v = new java.util.Vector();
|
||||
v.addElement(m);
|
||||
LookaheadWalk.considerSemanticLA = !Options.getForceLaCheck();
|
||||
LookaheadWalk.genFirstSet(v, nested);
|
||||
first = LookaheadWalk.sizeLimitedMatches;
|
||||
LookaheadWalk.sizeLimitedMatches = new java.util.Vector();
|
||||
LookaheadWalk.considerSemanticLA = false;
|
||||
LookaheadWalk.genFollowSet(v, exp, Expansion.nextGenerationIndex++);
|
||||
follow = LookaheadWalk.sizeLimitedMatches;
|
||||
if (la == 1) {
|
||||
if (csCodeCheck(first)) {
|
||||
CSJavaCCErrors.warning(nested, "CSCODE non-terminal within " + image(exp) + " construct will force this construct to be entered in favor of expansions occurring after construct.");
|
||||
}
|
||||
}
|
||||
if ((m = overlap(first, follow)) == null) {
|
||||
break;
|
||||
}
|
||||
m1 = m;
|
||||
}
|
||||
if (la > Options.getOtherAmbiguityCheck()) {
|
||||
CSJavaCCErrors.warning("Choice conflict in " + image(exp) + " construct at line " + exp.line + ", column " + exp.column + ".");
|
||||
System.err.println(" Expansion nested within construct and expansion following construct");
|
||||
System.err.println(" have common prefixes, one of which is: " + image(m1));
|
||||
System.err.println(" Consider using a lookahead of " + la + " or more for nested expansion.");
|
||||
} else if (la > 1) {
|
||||
CSJavaCCErrors.warning("Choice conflict in " + image(exp) + " construct at line " + exp.line + ", column " + exp.column + ".");
|
||||
System.err.println(" Expansion nested within construct and expansion following construct");
|
||||
System.err.println(" have common prefixes, one of which is: " + image(m1));
|
||||
System.err.println(" Consider using a lookahead of " + la + " for nested expansion.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user