Files
CSJavaCC/csjavacc/parser/RStringLiteral.java

1307 lines
44 KiB
Java

/*
* 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.*;
import csjavacc.struct.Nfa;
import csjavacc.struct.RegularExpression;
final class KindInfo
{
long[] validKinds;
long[] finalKinds;
int validKindCnt = 0;
int finalKindCnt = 0;
KindInfo(int maxKind)
{
validKinds = new long[maxKind / 64 + 1];
finalKinds = new long[maxKind / 64 + 1];
}
public void InsertValidKind(int kind)
{
validKinds[kind / 64] |= (1L << (kind % 64));
validKindCnt++;
}
public void InsertFinalKind(int kind)
{
finalKinds[kind / 64] |= (1L << (kind % 64));
finalKindCnt++;
}
};
/**
* Describes string literals.
*/
public class RStringLiteral extends RegularExpression {
/**
* The string image of the literal.
*/
public String image;
static int maxStrKind = 0;
static int maxLen = 0;
static int charCnt = 0;
static Vector charPosKind = new Vector(); // Elements are hashtables
// with single char keys;
static int[] maxLenForActive = new int[100]; // 6400 tokens
public static String[] allImages;
static int[][] intermediateKinds;
static int[][] intermediateMatchedPos;
static int startStateCnt = 0;
static boolean subString[];
static boolean subStringAtPos[];
static Hashtable[] statesForPos;
// Need to call this method after gnerating code for each lexical state. It
// initializes all the static variables, so that there is no interference
// between the various states of the lexer.
public static void ReInit()
{
maxStrKind = 0;
maxLen = 0;
charPosKind = new Vector();
maxLenForActive = new int[100]; // 6400 tokens
intermediateKinds = null;
intermediateMatchedPos = null;
startStateCnt = 0;
subString = null;
subStringAtPos = null;
statesForPos = null;
}
public static void DumpStrLiteralImages(java.io.PrintWriter ostr)
{
String image;
int charCnt = 0, i;
ostr.println("public static String[] jjstrLiteralImages = {");
if (allImages == null || allImages.length == 0){
ostr.println("};");
return;
}
allImages[0] = "";
for (i = 0; i < allImages.length; i++)
{
if ((image = allImages[i]) == null ||
((LexGen.toSkip[i / 64] & (1L << (i % 64))) == 0L &&
(LexGen.toMore[i / 64] & (1L << (i % 64))) == 0L &&
(LexGen.toToken[i / 64] & (1L << (i % 64))) == 0L) ||
(LexGen.toSkip[i / 64] & (1L << (i % 64))) != 0L ||
(LexGen.toMore[i / 64] & (1L << (i % 64))) != 0L ||
LexGen.canReachOnMore[LexGen.lexStates[i]] ||
((Options.getIgnoreCase() || LexGen.ignoreCase[i]) &&
(!image.equals(image.toLowerCase()) ||
!image.equals(image.toUpperCase()))))
{
allImages[i] = null;
if ((charCnt += 6) > 80){
ostr.println("");
charCnt = 0;
}
ostr.print("null, ");
continue;
}
String toPrint = "\"";
for (int j = 0; j < image.length(); j++){
if (image.charAt(j) <= 0xff)
// C# (csharp) doesn't allow octal char literals
toPrint += ("\\x" + Integer.toHexString((int)image.charAt(j)));
else{
String hexVal = Integer.toHexString((int)image.charAt(j));
if (hexVal.length() == 3)
hexVal = "0" + hexVal;
toPrint += ("\\u" + hexVal);
}
}
toPrint += ( "\", ");
if ((charCnt += toPrint.length()) >= 80)
{
ostr.println("");
charCnt = 0;
}
ostr.print(toPrint);
}
while (++i < LexGen.maxOrdinal)
{
if ((charCnt += 6) > 80)
{
ostr.println("");
charCnt = 0;
}
ostr.print("null, ");
continue;
}
ostr.println("};");
}
// Used for top level string literals
public void GenerateDfa(java.io.PrintWriter ostr, int kind)
{
String s;
Hashtable temp;
KindInfo info;
int len;
if (maxStrKind <= ordinal)
maxStrKind = ordinal + 1;
if ((len = image.length()) > maxLen)
maxLen = len;
char c;
for (int i = 0; i < len; i++)
{
if (Options.getIgnoreCase())
s = ("" + (c = image.charAt(i))).toLowerCase();
else
s = "" + (c = image.charAt(i));
if (!NfaState.unicodeWarningGiven && c > 0xff &&
!Options.getCSUnicodeEscape() &&
!Options.getUserCharStream())
{
NfaState.unicodeWarningGiven = true;
CSJavaCCErrors.warning(LexGen.curRE, "Non-ASCII characters used in regular expression." +
"Please make sure you use the correct Reader when you create the parser that can handle your character set.");
}
if (i >= charPosKind.size()) // Kludge, but OK
charPosKind.addElement(temp = new Hashtable());
else
temp = (Hashtable)charPosKind.elementAt(i);
if ((info = (KindInfo)temp.get(s)) == null)
temp.put(s, info = new KindInfo(LexGen.maxOrdinal));
if (i + 1 == len)
info.InsertFinalKind(ordinal);
else
info.InsertValidKind(ordinal);
if (!Options.getIgnoreCase() && LexGen.ignoreCase[ordinal] &&
c != Character.toLowerCase(c))
{
s = ("" + image.charAt(i)).toLowerCase();
if (i >= charPosKind.size()) // Kludge, but OK
charPosKind.addElement(temp = new Hashtable());
else
temp = (Hashtable)charPosKind.elementAt(i);
if ((info = (KindInfo)temp.get(s)) == null)
temp.put(s, info = new KindInfo(LexGen.maxOrdinal));
if (i + 1 == len)
info.InsertFinalKind(ordinal);
else
info.InsertValidKind(ordinal);
}
if (!Options.getIgnoreCase() && LexGen.ignoreCase[ordinal] &&
c != Character.toUpperCase(c))
{
s = ("" + image.charAt(i)).toUpperCase();
if (i >= charPosKind.size()) // Kludge, but OK
charPosKind.addElement(temp = new Hashtable());
else
temp = (Hashtable)charPosKind.elementAt(i);
if ((info = (KindInfo)temp.get(s)) == null)
temp.put(s, info = new KindInfo(LexGen.maxOrdinal));
if (i + 1 == len)
info.InsertFinalKind(ordinal);
else
info.InsertValidKind(ordinal);
}
}
maxLenForActive[ordinal / 64] = Math.max(maxLenForActive[ordinal / 64],
len -1);
allImages[ordinal] = image;
}
public Nfa GenerateNfa(boolean ignoreCase)
{
if (image.length() == 1)
{
RCharacterList temp = new RCharacterList(image.charAt(0));
return temp.GenerateNfa(ignoreCase);
}
NfaState startState = new NfaState();
NfaState theStartState = startState;
NfaState finalState = null;
if (image.length() == 0)
return new Nfa(theStartState, theStartState);
int i;
for (i = 0; i < image.length(); i++)
{
finalState = new NfaState();
startState.charMoves = new char[1];
startState.AddChar(image.charAt(i));
if (Options.getIgnoreCase() || ignoreCase)
{
startState.AddChar(Character.toLowerCase(image.charAt(i)));
startState.AddChar(Character.toUpperCase(image.charAt(i)));
}
startState.next = finalState;
startState = finalState;
}
return new Nfa(theStartState, finalState);
}
static void DumpNullStrLiterals(java.io.PrintWriter ostr)
{
ostr.println("{");
if (NfaState.generatedStates != 0)
ostr.println(" return jjMoveNfa" + LexGen.lexStateSuffix + "(" + NfaState.InitStateName() + ", 0);");
else
ostr.println(" return 1;");
ostr.println("}");
}
private static int GetStateSetForKind(int pos, int kind)
{
if (LexGen.mixed[LexGen.lexStateIndex] || NfaState.generatedStates == 0)
return -1;
Hashtable allStateSets = statesForPos[pos];
if (allStateSets == null)
return -1;
Enumeration e = allStateSets.keys();
while (e.hasMoreElements())
{
String s = (String)e.nextElement();
long[] actives = (long[])allStateSets.get(s);
s = s.substring(s.indexOf(", ") + 2);
s = s.substring(s.indexOf(", ") + 2);
if (s.equals("null;"))
continue;
if (actives != null &&
(actives[kind / 64] & (1L << (kind % 64))) != 0L)
{
return NfaState.AddStartStateSet(s);
}
}
return -1;
}
static String GetLabel(int kind)
{
RegularExpression re = LexGen.rexprs[kind];
if (re instanceof RStringLiteral)
return " \"" + CSJavaCCGlobals.add_escapes(((RStringLiteral)re).image) + "\"";
else if (!re.label.equals(""))
return " <" + re.label + ">";
else
return " <token of kind " + kind + ">";
}
static int GetLine(int kind)
{
return LexGen.rexprs[kind].line;
}
static int GetColumn(int kind)
{
return LexGen.rexprs[kind].column;
}
/**
* Returns true if s1 starts with s2 (ignoring case for each character).
*/
static private boolean StartsWithIgnoreCase(String s1, String s2)
{
if (s1.length() < s2.length())
return false;
for (int i = 0; i < s2.length(); i++)
{
char c1 = s1.charAt(i), c2 = s2.charAt(i);
if (c1 != c2 && Character.toLowerCase(c2) != c1 &&
Character.toUpperCase(c2) != c1)
return false;
}
return true;
}
static void FillSubString()
{
String image;
subString = new boolean[maxStrKind + 1];
subStringAtPos = new boolean[maxLen];
for (int i = 0; i < maxStrKind; i++)
{
subString[i] = false;
if ((image = allImages[i]) == null ||
LexGen.lexStates[i] != LexGen.lexStateIndex)
continue;
if (LexGen.mixed[LexGen.lexStateIndex])
{
// We will not optimize for mixed case
subString[i] = true;
subStringAtPos[image.length() - 1] = true;
continue;
}
for (int j = 0; j < maxStrKind; j++)
{
if (j != i && LexGen.lexStates[j] == LexGen.lexStateIndex &&
((String)allImages[j]) != null)
{
if (((String)allImages[j]).indexOf(image) == 0)
{
subString[i] = true;
subStringAtPos[image.length() - 1] = true;
break;
}
else if (Options.getIgnoreCase() &&
StartsWithIgnoreCase((String)allImages[j], image))
{
subString[i] = true;
subStringAtPos[image.length() - 1] = true;
break;
}
}
}
}
}
static void DumpStartWithStates(java.io.PrintWriter ostr)
{
ostr.println((Options.getStatic() ? "static " : "") + "private int " +
"jjStartNfaWithStates" + LexGen.lexStateSuffix + "(int pos, int kind, int state)");
ostr.println("{");
ostr.println(" jjmatchedKind = kind;");
ostr.println(" jjmatchedPos = pos;");
if (Options.getDebugTokenManager())
{
ostr.println(" debugStream.WriteLine(\" No more string literal token matches are possible.\");");
ostr.println(" debugStream.WriteLine(\" Currently matched the first \" + (jjmatchedPos + 1) + \" characters as a \" + tokenImage[jjmatchedKind] + \" token.\");");
}
ostr.println(" try { curChar = input_stream.readChar(); }");
ostr.println(" catch(System.IO.IOException e) { return pos + 1; }");
if (Options.getDebugTokenManager())
ostr.println(" debugStream.WriteLine(" + (LexGen.maxLexStates > 1 ? "\"<\" + lexStateNames[curLexState] + \">\" + " : "") + "\"Current character : \" + " +
"TokenMgrError.addEscapes(\"\"+(curChar)) + \" (\" + (int)curChar + \") at line \" + input_stream.getLine() + \" column \" + input_stream.getColumn());");
ostr.println(" return jjMoveNfa" + LexGen.lexStateSuffix + "(state, pos + 1);");
ostr.println("}");
}
private static boolean boilerPlateDumped = false;
static void DumpBoilerPlate(java.io.PrintWriter ostr)
{
ostr.println((Options.getStatic() ? "static " : "") + "private int " +
"jjStopAtPos(int pos, int kind)");
ostr.println("{");
ostr.println(" jjmatchedKind = kind;");
ostr.println(" jjmatchedPos = pos;");
if (Options.getDebugTokenManager())
{
ostr.println(" debugStream.WriteLine(\" No more string literal token matches are possible.\");");
ostr.println(" debugStream.WriteLine(\" Currently matched the first \" + (jjmatchedPos + 1) + \" characters as a \" + tokenImage[jjmatchedKind] + \" token.\");");
}
ostr.println(" return pos + 1;");
ostr.println("}");
}
static String[] ReArrange(Hashtable tab)
{
String[] ret = new String[tab.size()];
Enumeration e = tab.keys();
int cnt = 0;
while (e.hasMoreElements())
{
int i = 0, j;
String s;
char c = (s = (String)e.nextElement()).charAt(0);
while (i < cnt && ret[i].charAt(0) < c) i++;
if (i < cnt)
for (j = cnt - 1; j >= i; j--)
ret[j + 1] = ret[j];
ret[i] = s;
cnt++;
}
return ret;
}
static void DumpDfaCode(java.io.PrintWriter ostr)
{
Hashtable tab;
String key;
KindInfo info;
int maxLongsReqd = maxStrKind / 64 + 1;
int i, j, k;
boolean ifGenerated;
LexGen.maxLongsReqd[LexGen.lexStateIndex] = maxLongsReqd;
if (maxLen == 0)
{
ostr.println((Options.getStatic() ? "static " : "") + "private int " +
"jjMoveStringLiteralDfa0" + LexGen.lexStateSuffix + "()");
DumpNullStrLiterals(ostr);
return;
}
if (!boilerPlateDumped)
{
DumpBoilerPlate(ostr);
boilerPlateDumped = true;
}
if (!LexGen.mixed[LexGen.lexStateIndex] && NfaState.generatedStates != 0)
DumpStartWithStates(ostr);
boolean startNfaNeeded;
for (i = 0; i < maxLen; i++)
{
boolean atLeastOne = false;
startNfaNeeded = false;
tab = (Hashtable)charPosKind.elementAt(i);
String[] keys = ReArrange(tab);
ostr.print((Options.getStatic() ? "static " : "") + "private int " +
"jjMoveStringLiteralDfa" + i + LexGen.lexStateSuffix + "(");
if (i != 0)
{
if (i == 1)
{
for (j = 0; j < maxLongsReqd - 1; j++)
if (i <= maxLenForActive[j])
{
if (atLeastOne)
ostr.print(", ");
else
atLeastOne = true;
ostr.print("long active" + j);
}
if (i <= maxLenForActive[j])
{
if (atLeastOne)
ostr.print(", ");
ostr.print("long active" + j);
}
}
else
{
for (j = 0; j < maxLongsReqd - 1; j++)
if (i <= maxLenForActive[j] + 1)
{
if (atLeastOne)
ostr.print(", ");
else
atLeastOne = true;
ostr.print("long old" + j + ", long active" + j);
}
if (i <= maxLenForActive[j] + 1)
{
if (atLeastOne)
ostr.print(", ");
ostr.print("long old" + j + ", long active" + j);
}
}
}
ostr.println(")");
ostr.println("{");
if (i != 0)
{
if (i > 1)
{
atLeastOne = false;
ostr.print(" if ((");
for (j = 0; j < maxLongsReqd - 1; j++)
if (i <= maxLenForActive[j] + 1)
{
if (atLeastOne)
ostr.print(" | ");
else
atLeastOne = true;
ostr.print("(active" + j + " &= old" + j + ")");
}
if (i <= maxLenForActive[j] + 1)
{
if (atLeastOne)
ostr.print(" | ");
ostr.print("(active" + j + " &= old" + j + ")");
}
ostr.println(") == 0L)");
if (!LexGen.mixed[LexGen.lexStateIndex] && NfaState.generatedStates != 0)
{
ostr.print(" return jjStartNfa" + LexGen.lexStateSuffix +
"(" + (i - 2) + ", ");
for (j = 0; j < maxLongsReqd - 1; j++)
if (i <= maxLenForActive[j] + 1)
ostr.print("old" + j + ", ");
else
ostr.print("0L, ");
if (i <= maxLenForActive[j] + 1)
ostr.println("old" + j + "); ");
else
ostr.println("0L);");
}
else if (NfaState.generatedStates != 0)
ostr.println(" return jjMoveNfa" + LexGen.lexStateSuffix + "(" + NfaState.InitStateName() + ", " + (i - 1) + ");");
else
ostr.println(" return " + i + ";");
}
if (i != 0 && Options.getDebugTokenManager())
{
ostr.println(" if (jjmatchedKind != 0 && jjmatchedKind != 0x" + Integer.toHexString(Integer.MAX_VALUE) + ")");
ostr.println(" debugStream.WriteLine(\" Currently matched the first \" + (jjmatchedPos + 1) + \" characters as a \" + tokenImage[jjmatchedKind] + \" token.\");");
ostr.println(" debugStream.WriteLine(\" Possible string literal matches : { \"");
for (int vecs = 0; vecs < maxStrKind / 64 + 1; vecs++)
{
if (i <= maxLenForActive[vecs])
{
ostr.println(" + ");
ostr.print(" jjKindsForBitVector(" + vecs + ", ");
ostr.print("active" + vecs + ") ");
}
}
ostr.println(" + \" } \");");
}
ostr.println(" try { curChar = input_stream.readChar(); }");
ostr.println(" catch(System.IO.IOException e) {");
if (!LexGen.mixed[LexGen.lexStateIndex] && NfaState.generatedStates != 0)
{
ostr.print(" jjStopStringLiteralDfa" + LexGen.lexStateSuffix + "(" + (i - 1) + ", ");
for (k = 0; k < maxLongsReqd - 1; k++)
if (i <= maxLenForActive[k])
ostr.print("active" + k + ", ");
else
ostr.print("0L, ");
if (i <= maxLenForActive[k])
ostr.println("active" + k + ");");
else
ostr.println("0L);");
if (i != 0 && Options.getDebugTokenManager())
{
ostr.println(" if (jjmatchedKind != 0 && jjmatchedKind != 0x" + Integer.toHexString(Integer.MAX_VALUE) + ")");
ostr.println(" debugStream.WriteLine(\" Currently matched the first \" + (jjmatchedPos + 1) + \" characters as a \" + tokenImage[jjmatchedKind] + \" token.\");");
}
ostr.println(" return " + i + ";");
}
else if (NfaState.generatedStates != 0)
ostr.println(" return jjMoveNfa" + LexGen.lexStateSuffix + "(" + NfaState.InitStateName() + ", " + (i - 1) + ");");
else
ostr.println(" return " + i + ";");
ostr.println(" }");
}
if (i != 0 && Options.getDebugTokenManager())
ostr.println(" debugStream.WriteLine(" + (LexGen.maxLexStates > 1 ? "\"<\" + lexStateNames[curLexState] + \">\" + " : "") + "\"Current character : \" + " +
"TokenMgrError.addEscapes(\"\"+(curChar)) + \" (\" + (int)curChar + \") at line \" + input_stream.getLine() + \" column \" + input_stream.getColumn());");
ostr.println(" switch((int)curChar)");
ostr.println(" {");
CaseLoop:
for (int q = 0; q < keys.length; q++)
{
key = keys[q];
info = (KindInfo)tab.get(key);
ifGenerated = false;
char c = key.charAt(0);
if (i == 0 && c < 128 && info.finalKindCnt != 0 &&
(NfaState.generatedStates == 0 || !NfaState.CanStartNfaUsingAscii(c)))
{
int kind;
Outer:
for (j = 0; j < maxLongsReqd; j++)
if (info.finalKinds[j] != 0L)
break;
for (k = 0; k < 64; k++)
if ((info.finalKinds[j] & (1L << k)) != 0L &&
!subString[kind = (j * 64 + k)])
{
if ((intermediateKinds != null &&
intermediateKinds[(j * 64 + k)] != null &&
intermediateKinds[(j * 64 + k)][i] < (j * 64 + k) &&
intermediateMatchedPos != null &&
intermediateMatchedPos[(j * 64 + k)][i] == i) ||
(LexGen.canMatchAnyChar[LexGen.lexStateIndex] >= 0 &&
LexGen.canMatchAnyChar[LexGen.lexStateIndex] < (j * 64 + k)))
break;
else if ((LexGen.toSkip[kind / 64] & (1L << (kind % 64))) != 0L &&
(LexGen.toSpecial[kind / 64] & (1L << (kind % 64))) == 0L &&
LexGen.actions[kind] == null &&
LexGen.newLexState[kind] == null)
{
LexGen.AddCharToSkip(c, kind);
if (Options.getIgnoreCase())
{
if (c != Character.toUpperCase(c))
LexGen.AddCharToSkip(Character.toUpperCase(c), kind);
if (c != Character.toLowerCase(c))
LexGen.AddCharToSkip(Character.toLowerCase(c), kind);
}
continue CaseLoop;
}
}
}
// Since we know key is a single character ...
if (Options.getIgnoreCase())
{
if (c != Character.toUpperCase(c))
ostr.println(" case " + (int)Character.toUpperCase(c) + ":");
if (c != Character.toLowerCase(c))
ostr.println(" case " + (int)Character.toLowerCase(c) + ":");
}
ostr.println(" case " + (int)c + ":");
long matchedKind;
String prefix = (i == 0) ? " " : " ";
if (info.finalKindCnt != 0)
{
for (j = 0; j < maxLongsReqd; j++)
{
if ((matchedKind = info.finalKinds[j]) == 0L)
continue;
for (k = 0; k < 64; k++)
{
if ((matchedKind & (1L << k)) == 0L)
continue;
if (ifGenerated)
{
ostr.print(" else if ");
}
else if (i != 0)
ostr.print(" if ");
ifGenerated = true;
int kindToPrint;
if (i != 0)
{
ostr.println("((active" + j +
" & 0x" + Long.toHexString(1L << k) + "L) != 0L)");
}
if (intermediateKinds != null &&
intermediateKinds[(j * 64 + k)] != null &&
intermediateKinds[(j * 64 + k)][i] < (j * 64 + k) &&
intermediateMatchedPos != null &&
intermediateMatchedPos[(j * 64 + k)][i] == i)
{
CSJavaCCErrors.warning(" \"" +
CSJavaCCGlobals.add_escapes(allImages[j * 64 + k]) +
"\" cannot be matched as a string literal token " +
"at line " + GetLine(j * 64 + k) + ", column " + GetColumn(j * 64 + k) +
". It will be matched as " +
GetLabel(intermediateKinds[(j * 64 + k)][i]) + ".");
kindToPrint = intermediateKinds[(j * 64 + k)][i];
}
else if (i == 0 &&
LexGen.canMatchAnyChar[LexGen.lexStateIndex] >= 0 &&
LexGen.canMatchAnyChar[LexGen.lexStateIndex] < (j * 64 + k))
{
CSJavaCCErrors.warning(" \"" +
CSJavaCCGlobals.add_escapes(allImages[j * 64 + k]) +
"\" cannot be matched as a string literal token " +
"at line " + GetLine(j * 64 + k) + ", column " + GetColumn(j * 64 + k) +
". It will be matched as " +
GetLabel(LexGen.canMatchAnyChar[LexGen.lexStateIndex]) + ".");
kindToPrint = LexGen.canMatchAnyChar[LexGen.lexStateIndex];
}
else
kindToPrint = j * 64 + k;
if (!subString[(j * 64 + k)])
{
int stateSetName = GetStateSetForKind(i, j * 64 + k);
if (stateSetName != -1)
{
ostr.println(prefix + "return jjStartNfaWithStates" +
LexGen.lexStateSuffix + "(" + i +
", " + kindToPrint + ", " + stateSetName + ");");
}
else
ostr.println(prefix + "return jjStopAtPos" + "(" + i + ", " + kindToPrint + ");");
}
else
{
if ((LexGen.initMatch[LexGen.lexStateIndex] != 0 &&
LexGen.initMatch[LexGen.lexStateIndex] != Integer.MAX_VALUE) ||
i != 0)
{
ostr.println(" {");
ostr.println(prefix + "jjmatchedKind = " +
kindToPrint + ";");
ostr.println(prefix + "jjmatchedPos = " + i + ";");
ostr.println(" }");
}
else
ostr.println(prefix + "jjmatchedKind = " +
kindToPrint + ";");
}
}
}
}
if (info.validKindCnt != 0)
{
atLeastOne = false;
if (i == 0)
{
ostr.print(" return ");
ostr.print("jjMoveStringLiteralDfa" + (i + 1) +
LexGen.lexStateSuffix + "(");
for (j = 0; j < maxLongsReqd - 1; j++)
if ((i + 1) <= maxLenForActive[j])
{
if (atLeastOne)
ostr.print(", ");
else
atLeastOne = true;
ostr.print("0x" + Long.toHexString(info.validKinds[j]) + "L");
}
if ((i + 1) <= maxLenForActive[j])
{
if (atLeastOne)
ostr.print(", ");
ostr.print("0x" + Long.toHexString(info.validKinds[j]) + "L");
}
ostr.println(");");
}
else
{
ostr.print(" return ");
ostr.print("jjMoveStringLiteralDfa" + (i + 1) +
LexGen.lexStateSuffix + "(");
for (j = 0; j < maxLongsReqd - 1; j++)
if ((i + 1) <= maxLenForActive[j] + 1)
{
if (atLeastOne)
ostr.print(", ");
else
atLeastOne = true;
if (info.validKinds[j] != 0L)
ostr.print("active" + j + ", 0x" +
Long.toHexString(info.validKinds[j]) + "L");
else
ostr.print("active" + j + ", 0L");
}
if ((i + 1) <= maxLenForActive[j] + 1)
{
if (atLeastOne)
ostr.print(", ");
if (info.validKinds[j] != 0L)
ostr.print("active" + j + ", 0x" +
Long.toHexString(info.validKinds[j]) + "L");
else
ostr.print("active" + j + ", 0L");
}
ostr.println(");");
}
}
else
{
// A very special case.
if (i == 0 && LexGen.mixed[LexGen.lexStateIndex])
{
if (NfaState.generatedStates != 0)
ostr.println(" return jjMoveNfa" + LexGen.lexStateSuffix + "(" + NfaState.InitStateName() + ", 0);");
else
ostr.println(" return 1;");
}
else if (i != 0) // No more str literals to look for
{
ostr.println(" break;");
startNfaNeeded = true;
}
}
}
/* default means that the current character is not in any of the
strings at this position. */
ostr.println(" default :");
if (Options.getDebugTokenManager())
ostr.println(" debugStream.WriteLine(\" No string literal matches possible.\");");
if (NfaState.generatedStates != 0)
{
if (i == 0)
{
/* This means no string literal is possible. Just move nfa with
this guy and return. */
ostr.println(" return jjMoveNfa" + LexGen.lexStateSuffix + "(" + NfaState.InitStateName() + ", 0);");
}
else
{
ostr.println(" break;");
startNfaNeeded = true;
}
}
else
{
ostr.println(" return " + (i + 1) + ";");
}
ostr.println(" }");
if (i != 0)
{
if (startNfaNeeded)
{
if (!LexGen.mixed[LexGen.lexStateIndex] && NfaState.generatedStates != 0)
{
/* Here, a string literal is successfully matched and no more
string literals are possible. So set the kind and state set
upto and including this position for the matched string. */
ostr.print(" return jjStartNfa" + LexGen.lexStateSuffix + "(" + (i - 1) + ", ");
for (k = 0; k < maxLongsReqd - 1; k++)
if (i <= maxLenForActive[k])
ostr.print("active" + k + ", ");
else
ostr.print("0L, ");
if (i <= maxLenForActive[k])
ostr.println("active" + k + ");");
else
ostr.println("0L);");
}
else if (NfaState.generatedStates != 0)
ostr.println(" return jjMoveNfa" + LexGen.lexStateSuffix + "(" + NfaState.InitStateName() + ", " + i + ");");
else
ostr.println(" return " + (i + 1) + ";");
}
}
ostr.println("}");
}
}
static final int GetStrKind(String str)
{
for (int i = 0; i < maxStrKind; i++)
{
if (LexGen.lexStates[i] != LexGen.lexStateIndex)
continue;
String image = allImages[i];
if (image != null && image.equals(str))
return i;
}
return Integer.MAX_VALUE;
}
static void GenerateNfaStartStates(java.io.PrintWriter ostr,
NfaState initialState)
{
boolean[] seen = new boolean[NfaState.generatedStates];
Hashtable stateSets = new Hashtable();
String stateSetString = "";
int i, j, kind, jjmatchedPos = 0;
int maxKindsReqd = maxStrKind / 64 + 1;
long[] actives;
Vector newStates = new Vector();
Vector oldStates = null, jjtmpStates;
statesForPos = new Hashtable[maxLen];
intermediateKinds = new int[maxStrKind + 1][];
intermediateMatchedPos = new int[maxStrKind + 1][];
for (i = 0; i < maxStrKind; i++)
{
if (LexGen.lexStates[i] != LexGen.lexStateIndex)
continue;
String image = allImages[i];
if (image == null || image.length() < 1)
continue;
try
{
if ((oldStates = (Vector)initialState.epsilonMoves.clone()) == null ||
oldStates.size() == 0)
{
DumpNfaStartStatesCode(statesForPos, ostr);
return;
}
}
catch(Exception e)
{
CSJavaCCErrors.semantic_error("Error cloning state vector");
}
intermediateKinds[i] = new int[image.length()];
intermediateMatchedPos[i] = new int[image.length()];
jjmatchedPos = 0;
kind = Integer.MAX_VALUE;
for (j = 0; j < image.length(); j++)
{
if (oldStates == null || oldStates.size() <= 0)
{
// Here, j > 0
kind = intermediateKinds[i][j] = intermediateKinds[i][j - 1];
jjmatchedPos = intermediateMatchedPos[i][j] = intermediateMatchedPos[i][j - 1];
}
else
{
kind = NfaState.MoveFromSet(image.charAt(j), oldStates, newStates);
oldStates.removeAllElements();
if (j == 0 && kind != Integer.MAX_VALUE &&
LexGen.canMatchAnyChar[LexGen.lexStateIndex] != -1 &&
kind > LexGen.canMatchAnyChar[LexGen.lexStateIndex])
kind = LexGen.canMatchAnyChar[LexGen.lexStateIndex];
if (GetStrKind(image.substring(0, j + 1)) < kind)
{
intermediateKinds[i][j] = kind = Integer.MAX_VALUE;
jjmatchedPos = 0;
}
else if (kind != Integer.MAX_VALUE)
{
intermediateKinds[i][j] = kind;
jjmatchedPos = intermediateMatchedPos[i][j] = j;
}
else if (j == 0)
kind = intermediateKinds[i][j] = Integer.MAX_VALUE;
else
{
kind = intermediateKinds[i][j] = intermediateKinds[i][j - 1];
jjmatchedPos = intermediateMatchedPos[i][j] = intermediateMatchedPos[i][j - 1];
}
stateSetString = NfaState.GetStateSetString(newStates);
}
if (kind == Integer.MAX_VALUE &&
(newStates == null || newStates.size() == 0))
continue;
int p;
if (stateSets.get(stateSetString) == null)
{
stateSets.put(stateSetString, stateSetString);
for (p = 0; p < newStates.size(); p++)
{
if (seen[((NfaState)newStates.elementAt(p)).stateName])
((NfaState)newStates.elementAt(p)).inNextOf++;
else
seen[((NfaState)newStates.elementAt(p)).stateName] = true;
}
}
else
{
for (p = 0; p < newStates.size(); p++)
seen[((NfaState)newStates.elementAt(p)).stateName] = true;
}
jjtmpStates = oldStates;
oldStates = newStates;
(newStates = jjtmpStates).removeAllElements();
if (statesForPos[j] == null)
statesForPos[j] = new Hashtable();
if ((actives = ((long[])statesForPos[j].get(kind + ", " +
jjmatchedPos + ", " + stateSetString))) == null)
{
actives = new long[maxKindsReqd];
statesForPos[j].put(kind + ", " + jjmatchedPos + ", " +
stateSetString, actives);
}
actives[i / 64] |= 1L << (i % 64);
//String name = NfaState.StoreStateSet(stateSetString);
}
}
DumpNfaStartStatesCode(statesForPos, ostr);
}
static void DumpNfaStartStatesCode(Hashtable[] statesForPos,
java.io.PrintWriter ostr)
{
if (maxStrKind == 0) { // No need to generate this function
return;
}
int i, maxKindsReqd = maxStrKind / 64 + 1;
boolean condGenerated = false;
int ind = 0;
ostr.print("private" + (Options.getStatic() ? " static" : "") + " int jjStopStringLiteralDfa" +
LexGen.lexStateSuffix + "(int pos, ");
for (i = 0; i < maxKindsReqd - 1; i++)
ostr.print("long active" + i + ", ");
ostr.println("long active" + i + ")\n{");
if (Options.getDebugTokenManager())
ostr.println(" debugStream.WriteLine(\" No more string literal token matches are possible.\");");
ostr.println(" switch (pos)\n {");
for (i = 0; i < maxLen - 1; i++)
{
if (statesForPos[i] == null)
continue;
ostr.println(" case " + i + ":");
Enumeration e = statesForPos[i].keys();
while (e.hasMoreElements())
{
String stateSetString = (String)e.nextElement();
long[] actives = (long[])statesForPos[i].get(stateSetString);
for (int j = 0; j < maxKindsReqd; j++)
{
if (actives[j] == 0L)
continue;
if (condGenerated)
ostr.print(" || ");
else
ostr.print(" if (");
condGenerated = true;
ostr.print("(active" + j + " & unchecked((long)0x" +
Long.toHexString(actives[j]) + "L)) != 0L");
}
if (condGenerated)
{
ostr.println(")");
String kindStr = stateSetString.substring(0,
ind = stateSetString.indexOf(", "));
String afterKind = stateSetString.substring(ind + 2);
int jjmatchedPos = Integer.parseInt(
afterKind.substring(0, afterKind.indexOf(", ")));
if (!kindStr.equals(String.valueOf(Integer.MAX_VALUE)))
ostr.println(" {");
if (!kindStr.equals(String.valueOf(Integer.MAX_VALUE)))
{
if (i == 0)
{
ostr.println(" jjmatchedKind = " + kindStr + ";");
if ((LexGen.initMatch[LexGen.lexStateIndex] != 0 &&
LexGen.initMatch[LexGen.lexStateIndex] != Integer.MAX_VALUE))
ostr.println(" jjmatchedPos = 0;");
}
else if (i == jjmatchedPos)
{
if (subStringAtPos[i])
{
ostr.println(" if (jjmatchedPos != " + i + ")");
ostr.println(" {");
ostr.println(" jjmatchedKind = " + kindStr + ";");
ostr.println(" jjmatchedPos = " + i + ";");
ostr.println(" }");
}
else
{
ostr.println(" jjmatchedKind = " + kindStr + ";");
ostr.println(" jjmatchedPos = " + i + ";");
}
}
else
{
if (jjmatchedPos > 0)
ostr.println(" if (jjmatchedPos < " + jjmatchedPos + ")");
else
ostr.println(" if (jjmatchedPos == 0)");
ostr.println(" {");
ostr.println(" jjmatchedKind = " + kindStr + ";");
ostr.println(" jjmatchedPos = " + jjmatchedPos + ";");
ostr.println(" }");
}
}
kindStr = stateSetString.substring(0,
ind = stateSetString.indexOf(", "));
afterKind = stateSetString.substring(ind + 2);
stateSetString = afterKind.substring(
afterKind.indexOf(", ") + 2);
if (stateSetString.equals("null;"))
ostr.println(" return -1;");
else
ostr.println(" return " +
NfaState.AddStartStateSet(stateSetString) + ";");
if (!kindStr.equals(String.valueOf(Integer.MAX_VALUE)))
ostr.println(" }");
condGenerated = false;
}
}
ostr.println(" return -1;");
}
ostr.println(" default :");
ostr.println(" return -1;");
ostr.println(" }");
ostr.println("}");
ostr.print("private" + (Options.getStatic() ? " static" : "") + " int jjStartNfa" +
LexGen.lexStateSuffix + "(int pos, ");
for (i = 0; i < maxKindsReqd - 1; i++)
ostr.print("long active" + i + ", ");
ostr.println("long active" + i + ")\n{");
if (LexGen.mixed[LexGen.lexStateIndex])
{
if (NfaState.generatedStates != 0)
ostr.println(" return jjMoveNfa" + LexGen.lexStateSuffix + "(" + NfaState.InitStateName() + ", pos + 1);");
else
ostr.println(" return pos + 1;");
ostr.println("}");
return;
}
ostr.print(" return jjMoveNfa" + LexGen.lexStateSuffix + "(" +
"jjStopStringLiteralDfa" + LexGen.lexStateSuffix + "(pos, ");
for (i = 0; i < maxKindsReqd - 1; i++)
ostr.print("active" + i + ", ");
ostr.print("active" + i + ")");
ostr.println(", pos + 1);");
ostr.println("}");
}
public static void reInit()
{
maxStrKind = 0;
maxLen = 0;
charCnt = 0;
charPosKind = new Vector();
maxLenForActive = new int[100];
allImages = null;
intermediateKinds = null;
intermediateMatchedPos = null;
startStateCnt = 0;
subString = null;
subStringAtPos = null;
statesForPos = null;
boilerPlateDumped = false;
}
}