diff --git a/jflex/src/main/java/jflex/generator/Emitter.java b/jflex/src/main/java/jflex/generator/Emitter.java index 01637c9b5..21a1f9b62 100644 --- a/jflex/src/main/java/jflex/generator/Emitter.java +++ b/jflex/src/main/java/jflex/generator/Emitter.java @@ -5,17 +5,9 @@ package jflex.generator; -import java.io.File; -import java.io.PrintWriter; -import java.util.LinkedHashMap; -import java.util.Map; import jflex.base.Build; import jflex.base.Pair; -import jflex.core.AbstractLexScan; -import jflex.core.Action; -import jflex.core.EOFActions; -import jflex.core.LexParse; -import jflex.core.LexScan; +import jflex.core.*; import jflex.core.unicode.CMapBlock; import jflex.core.unicode.CharClasses; import jflex.dfa.DFA; @@ -26,6 +18,10 @@ import jflex.option.Options; import jflex.skeleton.Skeleton; +import java.io.File; +import java.io.PrintWriter; +import java.util.*; + /** * This class manages the actual code generation, putting the scanner together, filling in skeleton * sections etc. @@ -175,8 +171,7 @@ private void emitLookBuffer() { if (!hasGenLookAhead()) return; println(" /** For the backwards DFA of general lookahead statements */"); - println( - " private boolean [] zzFin = new boolean [Math.min(ZZ_BUFFERSIZE, zzMaxBufferLen())+1];"); + println(" private BitSet zzFin = null;"); println(); } @@ -428,11 +423,22 @@ private void emitHeader() { private void emitUserCode() { println(scanner.userCode()); + List additionalImports = new ArrayList<>(); if (scanner.cup2Compatible()) { + additionalImports.addAll(Arrays.asList( + "/* CUP2 imports */", + "import edu.tum.cup2.scanner.*;", + "import edu.tum.cup2.grammar.*;" + )); + } + + if (hasGenLookAhead()) { + additionalImports.add("import java.util.BitSet;"); + } + + if (!additionalImports.isEmpty()) { println(); - println("/* CUP2 imports */"); - println("import edu.tum.cup2.scanner.*;"); - println("import edu.tum.cup2.grammar.*;"); + additionalImports.forEach(this::println); println(); } } @@ -1116,26 +1122,26 @@ private void emitActions() { println(" // general lookahead, find correct zzMarkedPos"); println(" { int zzFState = " + dfa.entryState(action.getEntryState()) + ";"); println(" int zzFPos = zzStartRead;"); - println(" if (zzFin.length <= zzBufferL.length) {"); - println(" zzFin = new boolean[zzBufferL.length+1];"); + println(" if (zzFin == null || zzFin.size() <= zzBufferL.length) {"); + println(" zzFin = new BitSet(zzBufferL.length+1);"); println(" }"); - println(" boolean zzFinL[] = zzFin;"); + println(" BitSet zzFinL = zzFin;"); println(" while (zzFState != -1 && zzFPos < zzMarkedPos) {"); - println(" zzFinL[zzFPos] = ((zzAttrL[zzFState] & 1) == 1);"); + println(" zzFinL.set(zzFPos, ((zzAttrL[zzFState] & 1) == 1));"); println(" zzInput = Character.codePointAt(zzBufferL, zzFPos, zzMarkedPos);"); println(" zzFPos += Character.charCount(zzInput);"); println(" zzFState = zzTransL[ zzRowMapL[zzFState] + zzCMap(zzInput) ];"); println(" }"); println(" if (zzFState != -1) {"); - println(" zzFinL[zzFPos++] = ((zzAttrL[zzFState] & 1) == 1);"); + println(" zzFinL.set(zzFPos++, ((zzAttrL[zzFState] & 1) == 1));"); println(" }"); println(" while (zzFPos <= zzMarkedPos) {"); - println(" zzFinL[zzFPos++] = false;"); + println(" zzFinL.clear(zzFPos++);"); println(" }"); println(); println(" zzFState = " + dfa.entryState(action.getEntryState() + 1) + ";"); println(" zzFPos = zzMarkedPos;"); - println(" while (!zzFinL[zzFPos] || (zzAttrL[zzFState] & 1) != 1) {"); + println(" while (!zzFinL.get(zzFPos) || (zzAttrL[zzFState] & 1) != 1) {"); println( " zzInput = Character.codePointBefore(zzBufferL, zzFPos, zzStartRead);"); println(" zzFPos -= Character.charCount(zzInput);");