| /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
| * JFlex 1.4.3 * |
| * Copyright (C) 1998-2009 Gerwin Klein <lsf@jflex.de> * |
| * All rights reserved. * |
| * * |
| * This program is free software; you can redistribute it and/or modify * |
| * it under the terms of the GNU General Public License. See the file * |
| * COPYRIGHT for more information. * |
| * * |
| * This program is distributed in the hope that it will be useful, * |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
| * GNU General Public License for more details. * |
| * * |
| * You should have received a copy of the GNU General Public License along * |
| * with this program; if not, write to the Free Software Foundation, Inc., * |
| * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * |
| * * |
| * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
| |
| package JFlex; |
| |
| import java.io.*; |
| import java.util.*; |
| import java.text.*; |
| |
| /** |
| * This class manages the actual code generation, putting |
| * the scanner together, filling in skeleton sections etc. |
| * |
| * Table compression, String packing etc. is also done here. |
| * |
| * @author Gerwin Klein |
| * @version $Revision: 1.4.3 $, $Date: 2009/12/21 15:58:48 $ |
| */ |
| final public class Emitter { |
| |
| // bit masks for state attributes |
| static final private int FINAL = 1; |
| static final private int NOLOOK = 8; |
| |
| static final private String date = (new SimpleDateFormat()).format(new Date()); |
| |
| private File inputFile; |
| |
| private PrintWriter out; |
| private Skeleton skel; |
| private LexScan scanner; |
| private LexParse parser; |
| private DFA dfa; |
| |
| // for switch statement: |
| // table[i][j] is the set of input characters that leads from state i to state j |
| private CharSet table[][]; |
| |
| private boolean isTransition[]; |
| |
| // noTarget[i] is the set of input characters that have no target state in state i |
| private CharSet noTarget[]; |
| |
| // for row killing: |
| private int numRows; |
| private int [] rowMap; |
| private boolean [] rowKilled; |
| |
| // for col killing: |
| private int numCols; |
| private int [] colMap; |
| private boolean [] colKilled; |
| |
| |
| /** maps actions to their switch label */ |
| private Hashtable actionTable = new Hashtable(); |
| |
| private CharClassInterval [] intervals; |
| |
| private String visibility = "public"; |
| |
| public Emitter(File inputFile, LexParse parser, DFA dfa) throws IOException { |
| |
| String name = getBaseName(parser.scanner.className) + ".java"; |
| |
| File outputFile = normalize(name, inputFile); |
| |
| Out.println("Writing code to \""+outputFile+"\""); |
| |
| this.out = new PrintWriter(new BufferedWriter(new FileWriter(outputFile))); |
| this.parser = parser; |
| this.scanner = parser.scanner; |
| this.visibility = scanner.visibility; |
| this.inputFile = inputFile; |
| this.dfa = dfa; |
| this.skel = new Skeleton(out); |
| } |
| |
| /** |
| * Computes base name of the class name. Needs to take into account generics. |
| * |
| * @see LexScan#className |
| * @return the |
| */ |
| public static String getBaseName(String className) { |
| int gen = className.indexOf('<'); |
| if (gen < 0) { |
| return className; |
| } |
| else { |
| return className.substring(0, gen); |
| } |
| } |
| |
| |
| /** |
| * Constructs a file in Options.getDir() or in the same directory as |
| * another file. Makes a backup if the file already exists. |
| * |
| * @param name the name (without path) of the file |
| * @param path the path where to construct the file |
| * @param input fall back location if path = <tt>null</tt> |
| * (expected to be a file in the directory to write to) |
| */ |
| public static File normalize(String name, File input) { |
| File outputFile; |
| |
| if ( Options.getDir() == null ) |
| if ( input == null || input.getParent() == null ) |
| outputFile = new File(name); |
| else |
| outputFile = new File(input.getParent(), name); |
| else |
| outputFile = new File(Options.getDir(), name); |
| |
| if ( outputFile.exists() && !Options.no_backup ) { |
| File backup = new File( outputFile.toString()+"~" ); |
| |
| if ( backup.exists() ) backup.delete(); |
| |
| if ( outputFile.renameTo( backup ) ) |
| Out.println("Old file \""+outputFile+"\" saved as \""+backup+"\""); |
| else |
| Out.println("Couldn't save old file \""+outputFile+"\", overwriting!"); |
| } |
| |
| return outputFile; |
| } |
| |
| private void println() { |
| out.println(); |
| } |
| |
| private void println(String line) { |
| out.println(line); |
| } |
| |
| private void println(int i) { |
| out.println(i); |
| } |
| |
| private void print(String line) { |
| out.print(line); |
| } |
| |
| private void print(int i) { |
| out.print(i); |
| } |
| |
| private void print(int i, int tab) { |
| int exp; |
| |
| if (i < 0) |
| exp = 1; |
| else |
| exp = 10; |
| |
| while (tab-- > 1) { |
| if (Math.abs(i) < exp) print(" "); |
| exp*= 10; |
| } |
| |
| print(i); |
| } |
| |
| private boolean hasGenLookAhead() { |
| return dfa.lookaheadUsed; |
| } |
| |
| private void emitLookBuffer() { |
| if (!hasGenLookAhead()) return; |
| |
| println(" /** For the backwards DFA of general lookahead statements */"); |
| println(" private boolean [] zzFin = new boolean [ZZ_BUFFERSIZE+1];"); |
| println(); |
| } |
| |
| private void emitScanError() { |
| print(" private void zzScanError(int errorCode)"); |
| |
| if (scanner.scanErrorException != null) |
| print(" throws "+scanner.scanErrorException); |
| |
| println(" {"); |
| |
| skel.emitNext(); |
| |
| if (scanner.scanErrorException == null) |
| println(" throw new Error(message);"); |
| else |
| println(" throw new "+scanner.scanErrorException+"(message);"); |
| |
| skel.emitNext(); |
| |
| print(" "+visibility+" void yypushback(int number) "); |
| |
| if (scanner.scanErrorException == null) |
| println(" {"); |
| else |
| println(" throws "+scanner.scanErrorException+" {"); |
| } |
| |
| private void emitMain() { |
| if ( !(scanner.standalone || scanner.debugOption || scanner.cupDebug) ) return; |
| |
| if ( scanner.cupDebug ) { |
| println(" /**"); |
| println(" * Converts an int token code into the name of the"); |
| println(" * token by reflection on the cup symbol class/interface "+scanner.cupSymbol); |
| println(" *"); |
| println(" * This code was contributed by Karl Meissner <meissnersd@yahoo.com>"); |
| println(" */"); |
| println(" private String getTokenName(int token) {"); |
| println(" try {"); |
| println(" java.lang.reflect.Field [] classFields = " + scanner.cupSymbol + ".class.getFields();"); |
| println(" for (int i = 0; i < classFields.length; i++) {"); |
| println(" if (classFields[i].getInt(null) == token) {"); |
| println(" return classFields[i].getName();"); |
| println(" }"); |
| println(" }"); |
| println(" } catch (Exception e) {"); |
| println(" e.printStackTrace(System.err);"); |
| println(" }"); |
| println(""); |
| println(" return \"UNKNOWN TOKEN\";"); |
| println(" }"); |
| println(""); |
| println(" /**"); |
| println(" * Same as "+scanner.functionName+" but also prints the token to standard out"); |
| println(" * for debugging."); |
| println(" *"); |
| println(" * This code was contributed by Karl Meissner <meissnersd@yahoo.com>"); |
| println(" */"); |
| |
| print(" "+visibility+" "); |
| if ( scanner.tokenType == null ) { |
| if ( scanner.isInteger ) |
| print( "int" ); |
| else |
| if ( scanner.isIntWrap ) |
| print( "Integer" ); |
| else |
| print( "Yytoken" ); |
| } |
| else |
| print( scanner.tokenType ); |
| |
| print(" debug_"); |
| |
| print(scanner.functionName); |
| |
| print("() throws java.io.IOException"); |
| |
| if ( scanner.lexThrow != null ) { |
| print(", "); |
| print(scanner.lexThrow); |
| } |
| |
| if ( scanner.scanErrorException != null ) { |
| print(", "); |
| print(scanner.scanErrorException); |
| } |
| |
| println(" {"); |
| |
| println(" java_cup.runtime.Symbol s = "+scanner.functionName+"();"); |
| print(" System.out.println( "); |
| if (scanner.lineCount) print("\"line:\" + (yyline+1) + "); |
| if (scanner.columnCount) print("\" col:\" + (yycolumn+1) + "); |
| println("\" --\"+ yytext() + \"--\" + getTokenName(s.sym) + \"--\");"); |
| println(" return s;"); |
| println(" }"); |
| println(""); |
| } |
| |
| if ( scanner.standalone ) { |
| println(" /**"); |
| println(" * Runs the scanner on input files."); |
| println(" *"); |
| println(" * This is a standalone scanner, it will print any unmatched"); |
| println(" * text to System.out unchanged."); |
| println(" *"); |
| println(" * @param argv the command line, contains the filenames to run"); |
| println(" * the scanner on."); |
| println(" */"); |
| } |
| else { |
| println(" /**"); |
| println(" * Runs the scanner on input files."); |
| println(" *"); |
| println(" * This main method is the debugging routine for the scanner."); |
| println(" * It prints debugging information about each returned token to"); |
| println(" * System.out until the end of file is reached, or an error occured."); |
| println(" *"); |
| println(" * @param argv the command line, contains the filenames to run"); |
| println(" * the scanner on."); |
| println(" */"); |
| } |
| |
| String className = getBaseName(scanner.className); |
| |
| println(" public static void main(String argv[]) {"); |
| println(" if (argv.length == 0) {"); |
| println(" System.out.println(\"Usage : java "+className+" <inputfile>\");"); |
| println(" }"); |
| println(" else {"); |
| println(" for (int i = 0; i < argv.length; i++) {"); |
| println(" "+className+" scanner = null;"); |
| println(" try {"); |
| println(" scanner = new "+className+"( new java.io.FileReader(argv[i]) );"); |
| |
| if ( scanner.standalone ) { |
| println(" while ( !scanner.zzAtEOF ) scanner."+scanner.functionName+"();"); |
| } |
| else if (scanner.cupDebug ) { |
| println(" while ( !scanner.zzAtEOF ) scanner.debug_"+scanner.functionName+"();"); |
| } |
| else { |
| println(" do {"); |
| println(" System.out.println(scanner."+scanner.functionName+"());"); |
| println(" } while (!scanner.zzAtEOF);"); |
| println(""); |
| } |
| |
| println(" }"); |
| println(" catch (java.io.FileNotFoundException e) {"); |
| println(" System.out.println(\"File not found : \\\"\"+argv[i]+\"\\\"\");"); |
| println(" }"); |
| println(" catch (java.io.IOException e) {"); |
| println(" System.out.println(\"IO error scanning file \\\"\"+argv[i]+\"\\\"\");"); |
| println(" System.out.println(e);"); |
| println(" }"); |
| println(" catch (Exception e) {"); |
| println(" System.out.println(\"Unexpected exception:\");"); |
| println(" e.printStackTrace();"); |
| println(" }"); |
| println(" }"); |
| println(" }"); |
| println(" }"); |
| println(""); |
| } |
| |
| private String zzBufferLAccess(String idx) { |
| if (Options.sliceAndCharAt) { |
| return "(zzBufferArrayL != null ? zzBufferArrayL[" + idx + "] : zzBufferL.charAt("+idx+"))"; |
| } |
| if (Options.char_at) { |
| return "zzBufferL.charAt("+idx+")"; |
| } |
| return "zzBufferL[" + idx + "]"; |
| } |
| |
| private String zzBufferLLength() { |
| if (Options.sliceAndCharAt) { |
| return "(zzBufferArrayL != null ? zzBufferArrayL.length : zzBufferL.length())"; |
| } |
| if (Options.char_at) { |
| return "zzBufferL.length()"; |
| } |
| return "zzBufferL.length"; |
| } |
| |
| private void emitNoMatch() { |
| println(" zzScanError(ZZ_NO_MATCH);"); |
| } |
| |
| private void emitNextInput() { |
| println(" if (zzCurrentPosL < zzEndReadL)"); |
| println(" zzInput = " + zzBufferLAccess("zzCurrentPosL++") + ";"); |
| println(" else if (zzAtEOF) {"); |
| println(" zzInput = YYEOF;"); |
| println(" break zzForAction;"); |
| println(" }"); |
| println(" else {"); |
| println(" // store back cached positions"); |
| println(" zzCurrentPos = zzCurrentPosL;"); |
| println(" zzMarkedPos = zzMarkedPosL;"); |
| println(" boolean eof = zzRefill();"); |
| println(" // get translated positions and possibly new buffer"); |
| println(" zzCurrentPosL = zzCurrentPos;"); |
| println(" zzMarkedPosL = zzMarkedPos;"); |
| println(" zzBufferL = zzBuffer;"); |
| println(" zzEndReadL = zzEndRead;"); |
| println(" if (eof) {"); |
| println(" zzInput = YYEOF;"); |
| println(" break zzForAction;"); |
| println(" }"); |
| println(" else {"); |
| println(" zzInput = " + zzBufferLAccess("zzCurrentPosL++") + ";"); |
| println(" }"); |
| println(" }"); |
| } |
| |
| private void emitHeader() { |
| println("/* The following code was generated by JFlex "+Main.version+" on "+date+" */"); |
| println(""); |
| } |
| |
| private void emitUserCode() { |
| if ( scanner.userCode.length() > 0 ) |
| println(scanner.userCode.toString()); |
| } |
| |
| private void emitClassName() { |
| if (!endsWithJavadoc(scanner.userCode)) { |
| String path = inputFile.toString(); |
| // slashify path (avoid backslash u sequence = unicode escape) |
| if (File.separatorChar != '/') { |
| path = path.replace(File.separatorChar, '/'); |
| } |
| |
| println("/**"); |
| println(" * This class is a scanner generated by "); |
| println(" * <a href=\"http://www.jflex.de/\">JFlex</a> "+Main.version); |
| println(" * on "+date+" from the specification file"); |
| println(" * <tt>"+path+"</tt>"); |
| println(" */"); |
| } |
| |
| if ( scanner.isPublic ) print("public "); |
| |
| if ( scanner.isAbstract) print("abstract "); |
| |
| if ( scanner.isFinal ) print("final "); |
| |
| print("class "); |
| print(scanner.className); |
| |
| if ( scanner.isExtending != null ) { |
| print(" extends "); |
| print(scanner.isExtending); |
| } |
| |
| if ( scanner.isImplementing != null ) { |
| print(" implements "); |
| print(scanner.isImplementing); |
| } |
| |
| println(" {"); |
| } |
| |
| /** |
| * Try to find out if user code ends with a javadoc comment |
| * |
| * @param buffer the user code |
| * @return true if it ends with a javadoc comment |
| */ |
| public static boolean endsWithJavadoc(StringBuffer usercode) { |
| String s = usercode.toString().trim(); |
| |
| if (!s.endsWith("*/")) return false; |
| |
| // find beginning of javadoc comment |
| int i = s.lastIndexOf("/**"); |
| if (i < 0) return false; |
| |
| // javadoc comment shouldn't contain a comment end |
| return s.substring(i,s.length()-2).indexOf("*/") < 0; |
| } |
| |
| |
| private void emitLexicalStates() { |
| Enumeration stateNames = scanner.states.names(); |
| |
| while ( stateNames.hasMoreElements() ) { |
| String name = (String) stateNames.nextElement(); |
| |
| int num = scanner.states.getNumber(name).intValue(); |
| |
| println(" "+visibility+" static final int "+name+" = "+2*num+";"); |
| } |
| |
| // can't quite get rid of the indirection, even for non-bol lex states: |
| // their DFA states might be the same, but their EOF actions might be different |
| // (see bug #1540228) |
| println(""); |
| println(" /**"); |
| println(" * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l"); |
| println(" * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l"); |
| println(" * at the beginning of a line"); |
| println(" * l is of the form l = 2*k, k a non negative integer"); |
| println(" */"); |
| println(" private static final int ZZ_LEXSTATE[] = { "); |
| |
| int i, j = 0; |
| print(" "); |
| |
| for (i = 0; i < 2*dfa.numLexStates-1; i++) { |
| print( dfa.entryState[i], 2 ); |
| |
| print(", "); |
| |
| if (++j >= 16) { |
| println(); |
| print(" "); |
| j = 0; |
| } |
| } |
| |
| println( dfa.entryState[i] ); |
| println(" };"); |
| } |
| |
| private void emitDynamicInit() { |
| int count = 0; |
| int value = dfa.table[0][0]; |
| |
| println(" /** "); |
| println(" * The transition table of the DFA"); |
| println(" */"); |
| |
| CountEmitter e = new CountEmitter("Trans"); |
| e.setValTranslation(+1); // allow vals in [-1, 0xFFFE] |
| e.emitInit(); |
| |
| for (int i = 0; i < dfa.numStates; i++) { |
| if ( !rowKilled[i] ) { |
| for (int c = 0; c < dfa.numInput; c++) { |
| if ( !colKilled[c] ) { |
| if (dfa.table[i][c] == value) { |
| count++; |
| } |
| else { |
| e.emit(count, value); |
| |
| count = 1; |
| value = dfa.table[i][c]; |
| } |
| } |
| } |
| } |
| } |
| |
| e.emit(count, value); |
| e.emitUnpack(); |
| |
| println(e.toString()); |
| } |
| |
| |
| private void emitCharMapInitFunction() { |
| |
| CharClasses cl = parser.getCharClasses(); |
| |
| if ( cl.getMaxCharCode() < 256 ) return; |
| |
| println(""); |
| println(" /** "); |
| println(" * Unpacks the compressed character translation table."); |
| println(" *"); |
| println(" * @param packed the packed character translation table"); |
| println(" * @return the unpacked character translation table"); |
| println(" */"); |
| println(" private static char [] zzUnpackCMap(String packed) {"); |
| println(" char [] map = new char[0x10000];"); |
| println(" int i = 0; /* index in packed string */"); |
| println(" int j = 0; /* index in unpacked array */"); |
| println(" while (i < "+2*intervals.length+") {"); |
| println(" int count = packed.charAt(i++);"); |
| println(" char value = packed.charAt(i++);"); |
| println(" do map[j++] = value; while (--count > 0);"); |
| println(" }"); |
| println(" return map;"); |
| println(" }"); |
| } |
| |
| private void emitZZTrans() { |
| |
| int i,c; |
| int n = 0; |
| |
| println(" /** "); |
| println(" * The transition table of the DFA"); |
| println(" */"); |
| println(" private static final int ZZ_TRANS [] = {"); |
| |
| print(" "); |
| for (i = 0; i < dfa.numStates; i++) { |
| |
| if ( !rowKilled[i] ) { |
| for (c = 0; c < dfa.numInput; c++) { |
| if ( !colKilled[c] ) { |
| if (n >= 10) { |
| println(); |
| print(" "); |
| n = 0; |
| } |
| print( dfa.table[i][c] ); |
| if (i != dfa.numStates-1 || c != dfa.numInput-1) |
| print( ", "); |
| n++; |
| } |
| } |
| } |
| } |
| |
| println(); |
| println(" };"); |
| } |
| |
| private void emitCharMapArrayUnPacked() { |
| |
| CharClasses cl = parser.getCharClasses(); |
| |
| println(""); |
| println(" /** "); |
| println(" * Translates characters to character classes"); |
| println(" */"); |
| println(" private static final char [] ZZ_CMAP = {"); |
| |
| int n = 0; // numbers of entries in current line |
| print(" "); |
| |
| int max = cl.getMaxCharCode(); |
| |
| // not very efficient, but good enough for <= 255 characters |
| for (char c = 0; c <= max; c++) { |
| print(colMap[cl.getClassCode(c)],2); |
| |
| if (c < max) { |
| print(", "); |
| if ( ++n >= 16 ) { |
| println(); |
| print(" "); |
| n = 0; |
| } |
| } |
| } |
| |
| println(); |
| println(" };"); |
| println(); |
| } |
| |
| private void emitCharMapArray() { |
| CharClasses cl = parser.getCharClasses(); |
| |
| if ( cl.getMaxCharCode() < 256 ) { |
| emitCharMapArrayUnPacked(); |
| return; |
| } |
| |
| // ignores cl.getMaxCharCode(), emits all intervals instead |
| |
| intervals = cl.getIntervals(); |
| |
| println(""); |
| println(" /** "); |
| println(" * Translates characters to character classes"); |
| println(" */"); |
| println(" private static final String ZZ_CMAP_PACKED = "); |
| |
| int n = 0; // numbers of entries in current line |
| print(" \""); |
| |
| int i = 0; |
| int count, value; |
| while ( i < intervals.length ) { |
| count = intervals[i].end-intervals[i].start+1; |
| value = colMap[intervals[i].charClass]; |
| |
| // count could be >= 0x10000 |
| while (count > 0xFFFF) { |
| printUC(0xFFFF); |
| printUC(value); |
| count -= 0xFFFF; |
| n++; |
| } |
| |
| printUC(count); |
| printUC(value); |
| |
| if (i < intervals.length-1) { |
| if ( ++n >= 10 ) { |
| println("\"+"); |
| print(" \""); |
| n = 0; |
| } |
| } |
| |
| i++; |
| } |
| |
| println("\";"); |
| println(); |
| |
| println(" /** "); |
| println(" * Translates characters to character classes"); |
| println(" */"); |
| println(" private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED);"); |
| println(); |
| } |
| |
| |
| /** |
| * Print number as octal/unicode escaped string character. |
| * |
| * @param c the value to print |
| * @prec 0 <= c <= 0xFFFF |
| */ |
| private void printUC(int c) { |
| if (c > 255) { |
| out.print("\\u"); |
| if (c < 0x1000) out.print("0"); |
| out.print(Integer.toHexString(c)); |
| } |
| else { |
| out.print("\\"); |
| out.print(Integer.toOctalString(c)); |
| } |
| } |
| |
| |
| private void emitRowMapArray() { |
| println(""); |
| println(" /** "); |
| println(" * Translates a state to a row index in the transition table"); |
| println(" */"); |
| |
| HiLowEmitter e = new HiLowEmitter("RowMap"); |
| e.emitInit(); |
| for (int i = 0; i < dfa.numStates; i++) { |
| e.emit(rowMap[i]*numCols); |
| } |
| e.emitUnpack(); |
| println(e.toString()); |
| } |
| |
| |
| private void emitAttributes() { |
| println(" /**"); |
| println(" * ZZ_ATTRIBUTE[aState] contains the attributes of state <code>aState</code>"); |
| println(" */"); |
| |
| CountEmitter e = new CountEmitter("Attribute"); |
| e.emitInit(); |
| |
| int count = 1; |
| int value = 0; |
| if ( dfa.isFinal[0] ) value = FINAL; |
| if ( !isTransition[0] ) value|= NOLOOK; |
| |
| for (int i = 1; i < dfa.numStates; i++) { |
| int attribute = 0; |
| if ( dfa.isFinal[i] ) attribute = FINAL; |
| if ( !isTransition[i] ) attribute|= NOLOOK; |
| |
| if (value == attribute) { |
| count++; |
| } |
| else { |
| e.emit(count, value); |
| count = 1; |
| value = attribute; |
| } |
| } |
| |
| e.emit(count, value); |
| e.emitUnpack(); |
| |
| println(e.toString()); |
| } |
| |
| |
| private void emitClassCode() { |
| if ( scanner.eofCode != null ) { |
| println(" /** denotes if the user-EOF-code has already been executed */"); |
| println(" private boolean zzEOFDone;"); |
| println(""); |
| } |
| |
| if ( scanner.classCode != null ) { |
| println(" /* user code: */"); |
| println(scanner.classCode); |
| } |
| } |
| |
| private void emitConstructorDecl() { |
| emitConstructorDecl(true); |
| |
| if ((scanner.standalone || scanner.debugOption) && |
| scanner.ctorArgs.size() > 0) { |
| Out.warning(ErrorMessages.get(ErrorMessages.CTOR_DEBUG)); |
| println(); |
| emitConstructorDecl(false); |
| } |
| } |
| |
| private void emitConstructorDecl(boolean printCtorArgs) { |
| |
| String warn = |
| "// WARNING: this is a default constructor for " + |
| "debug/standalone only. Has no custom parameters or init code."; |
| |
| if (!printCtorArgs) println(warn); |
| |
| print(" "); |
| |
| if ( scanner.isPublic ) print("public "); |
| print( getBaseName(scanner.className) ); |
| print("(java.io.Reader in"); |
| if (printCtorArgs) emitCtorArgs(); |
| print(")"); |
| |
| if ( scanner.initThrow != null && printCtorArgs) { |
| print(" throws "); |
| print( scanner.initThrow ); |
| } |
| |
| println(" {"); |
| |
| if ( scanner.initCode != null && printCtorArgs) { |
| print(" "); |
| print( scanner.initCode ); |
| } |
| |
| println(" this.zzReader = in;"); |
| |
| println(" }"); |
| println(); |
| |
| |
| println(" /**"); |
| println(" * Creates a new scanner."); |
| println(" * There is also java.io.Reader version of this constructor."); |
| println(" *"); |
| println(" * @param in the java.io.Inputstream to read input from."); |
| println(" */"); |
| if (!printCtorArgs) println(warn); |
| |
| print(" "); |
| if ( scanner.isPublic ) print("public "); |
| print( getBaseName(scanner.className) ); |
| print("(java.io.InputStream in"); |
| if (printCtorArgs) emitCtorArgs(); |
| print(")"); |
| |
| if ( scanner.initThrow != null && printCtorArgs ) { |
| print(" throws "); |
| print( scanner.initThrow ); |
| } |
| |
| println(" {"); |
| |
| print(" this(new java.io.InputStreamReader(in)"); |
| if (printCtorArgs) { |
| for (int i=0; i < scanner.ctorArgs.size(); i++) { |
| print(", "+scanner.ctorArgs.elementAt(i)); |
| } |
| } |
| println(");"); |
| |
| println(" }"); |
| } |
| |
| private void emitCtorArgs() { |
| for (int i = 0; i < scanner.ctorArgs.size(); i++) { |
| print(", "+scanner.ctorTypes.elementAt(i)); |
| print(" "+scanner.ctorArgs.elementAt(i)); |
| } |
| } |
| |
| private void emitDoEOF() { |
| if ( scanner.eofCode == null ) return; |
| |
| println(" /**"); |
| println(" * Contains user EOF-code, which will be executed exactly once,"); |
| println(" * when the end of file is reached"); |
| println(" */"); |
| |
| print(" private void zzDoEOF()"); |
| |
| if ( scanner.eofThrow != null ) { |
| print(" throws "); |
| print(scanner.eofThrow); |
| } |
| |
| println(" {"); |
| |
| println(" if (!zzEOFDone) {"); |
| println(" zzEOFDone = true;"); |
| println(" "+scanner.eofCode ); |
| println(" }"); |
| println(" }"); |
| println(""); |
| println(""); |
| } |
| |
| private void emitLexFunctHeader() { |
| |
| if (scanner.cupCompatible) { |
| // force public, because we have to implement java_cup.runtime.Symbol |
| print(" public "); |
| } |
| else { |
| print(" "+visibility+" "); |
| } |
| |
| if ( scanner.tokenType == null ) { |
| if ( scanner.isInteger ) |
| print( "int" ); |
| else |
| if ( scanner.isIntWrap ) |
| print( "Integer" ); |
| else |
| print( "Yytoken" ); |
| } |
| else |
| print( scanner.tokenType ); |
| |
| print(" "); |
| |
| print(scanner.functionName); |
| |
| print("() throws java.io.IOException"); |
| |
| if ( scanner.lexThrow != null ) { |
| print(", "); |
| print(scanner.lexThrow); |
| } |
| |
| if ( scanner.scanErrorException != null ) { |
| print(", "); |
| print(scanner.scanErrorException); |
| } |
| |
| println(" {"); |
| |
| skel.emitNext(); |
| |
| if ( scanner.useRowMap ) { |
| println(" int [] zzTransL = ZZ_TRANS;"); |
| println(" int [] zzRowMapL = ZZ_ROWMAP;"); |
| println(" int [] zzAttrL = ZZ_ATTRIBUTE;"); |
| |
| } |
| |
| skel.emitNext(); |
| |
| if ( scanner.charCount ) { |
| println(" yychar+= zzMarkedPosL-zzStartRead;"); |
| println(""); |
| } |
| |
| if ( scanner.lineCount || scanner.columnCount ) { |
| println(" boolean zzR = false;"); |
| println(" for (zzCurrentPosL = zzStartRead; zzCurrentPosL < zzMarkedPosL;"); |
| println(" zzCurrentPosL++) {"); |
| println(" switch (" + zzBufferLAccess("zzCurrentPosL") + ") {"); |
| println(" case '\\u000B':"); |
| println(" case '\\u000C':"); |
| println(" case '\\u0085':"); |
| println(" case '\\u2028':"); |
| println(" case '\\u2029':"); |
| if ( scanner.lineCount ) |
| println(" yyline++;"); |
| if ( scanner.columnCount ) |
| println(" yycolumn = 0;"); |
| println(" zzR = false;"); |
| println(" break;"); |
| println(" case '\\r':"); |
| if ( scanner.lineCount ) |
| println(" yyline++;"); |
| if ( scanner.columnCount ) |
| println(" yycolumn = 0;"); |
| println(" zzR = true;"); |
| println(" break;"); |
| println(" case '\\n':"); |
| println(" if (zzR)"); |
| println(" zzR = false;"); |
| println(" else {"); |
| if ( scanner.lineCount ) |
| println(" yyline++;"); |
| if ( scanner.columnCount ) |
| println(" yycolumn = 0;"); |
| println(" }"); |
| println(" break;"); |
| println(" default:"); |
| println(" zzR = false;"); |
| if ( scanner.columnCount ) |
| println(" yycolumn++;"); |
| println(" }"); |
| println(" }"); |
| println(); |
| |
| if ( scanner.lineCount ) { |
| println(" if (zzR) {"); |
| println(" // peek one character ahead if it is \\n (if we have counted one line too much)"); |
| println(" boolean zzPeek;"); |
| println(" if (zzMarkedPosL < zzEndReadL)"); |
| println(" zzPeek = " + zzBufferLAccess("zzMarkedPosL") + " == '\\n';"); |
| println(" else if (zzAtEOF)"); |
| println(" zzPeek = false;"); |
| println(" else {"); |
| println(" boolean eof = zzRefill();"); |
| println(" zzEndReadL = zzEndRead;"); |
| println(" zzMarkedPosL = zzMarkedPos;"); |
| println(" zzBufferL = zzBuffer;"); |
| println(" if (eof) "); |
| println(" zzPeek = false;"); |
| println(" else "); |
| println(" zzPeek = " + zzBufferLAccess("zzMarkedPosL") + " == '\\n';"); |
| println(" }"); |
| println(" if (zzPeek) yyline--;"); |
| println(" }"); |
| } |
| } |
| |
| if ( scanner.bolUsed ) { |
| // zzMarkedPos > zzStartRead <=> last match was not empty |
| // if match was empty, last value of zzAtBOL can be used |
| // zzStartRead is always >= 0 |
| println(" if (zzMarkedPosL > zzStartRead) {"); |
| println(" switch (" + zzBufferLAccess("zzMarkedPosL-1") + ") {"); |
| println(" case '\\n':"); |
| println(" case '\\u000B':"); |
| println(" case '\\u000C':"); |
| println(" case '\\u0085':"); |
| println(" case '\\u2028':"); |
| println(" case '\\u2029':"); |
| println(" zzAtBOL = true;"); |
| println(" break;"); |
| println(" case '\\r': "); |
| println(" if (zzMarkedPosL < zzEndReadL)"); |
| println(" zzAtBOL = " + zzBufferLAccess("zzMarkedPosL") + " != '\\n';"); |
| println(" else if (zzAtEOF)"); |
| println(" zzAtBOL = false;"); |
| println(" else {"); |
| println(" boolean eof = zzRefill();"); |
| println(" zzMarkedPosL = zzMarkedPos;"); |
| println(" zzEndReadL = zzEndRead;"); |
| println(" zzBufferL = zzBuffer;"); |
| println(" if (eof) "); |
| println(" zzAtBOL = false;"); |
| println(" else "); |
| println(" zzAtBOL = " + zzBufferLAccess("zzMarkedPosL") + " != '\\n';"); |
| println(" }"); |
| println(" break;"); |
| println(" default:"); |
| println(" zzAtBOL = false;"); |
| println(" }"); |
| println(" }"); |
| } |
| |
| skel.emitNext(); |
| |
| if (scanner.bolUsed) { |
| println(" if (zzAtBOL)"); |
| println(" zzState = ZZ_LEXSTATE[zzLexicalState+1];"); |
| println(" else"); |
| println(" zzState = ZZ_LEXSTATE[zzLexicalState];"); |
| println(); |
| } |
| else { |
| println(" zzState = ZZ_LEXSTATE[zzLexicalState];"); |
| println(); |
| } |
| |
| skel.emitNext(); |
| } |
| |
| |
| private void emitGetRowMapNext() { |
| println(" int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ];"); |
| println(" if (zzNext == "+DFA.NO_TARGET+") break zzForAction;"); |
| println(" zzState = zzNext;"); |
| println(); |
| |
| println(" int zzAttributes = zzAttrL[zzState];"); |
| |
| println(" if ( (zzAttributes & "+FINAL+") == "+FINAL+" ) {"); |
| |
| skel.emitNext(); |
| |
| println(" if ( (zzAttributes & "+NOLOOK+") == "+NOLOOK+" ) break zzForAction;"); |
| |
| skel.emitNext(); |
| } |
| |
| private void emitTransitionTable() { |
| transformTransitionTable(); |
| |
| println(" zzInput = zzCMapL[zzInput];"); |
| println(); |
| |
| println(" boolean zzIsFinal = false;"); |
| println(" boolean zzNoLookAhead = false;"); |
| println(); |
| |
| println(" zzForNext: { switch (zzState) {"); |
| |
| for (int state = 0; state < dfa.numStates; state++) |
| if (isTransition[state]) emitState(state); |
| |
| println(" default:"); |
| println(" // if this is ever reached, there is a serious bug in JFlex"); |
| println(" zzScanError(ZZ_UNKNOWN_ERROR);"); |
| println(" break;"); |
| println(" } }"); |
| println(); |
| |
| println(" if ( zzIsFinal ) {"); |
| |
| skel.emitNext(); |
| |
| println(" if ( zzNoLookAhead ) break zzForAction;"); |
| |
| skel.emitNext(); |
| } |
| |
| |
| /** |
| * Escapes all " ' \ tabs and newlines |
| */ |
| private String escapify(String s) { |
| StringBuffer result = new StringBuffer(s.length()*2); |
| |
| for (int i = 0; i < s.length(); i++) { |
| char c = s.charAt(i); |
| switch (c) { |
| case '\'': result.append("\\\'"); break; |
| case '\"': result.append("\\\""); break; |
| case '\\': result.append("\\\\"); break; |
| case '\t': result.append("\\t"); break; |
| case '\r': if (i+1 == s.length() || s.charAt(i+1) != '\n') result.append("\"+ZZ_NL+\""); |
| break; |
| case '\n': result.append("\"+ZZ_NL+\""); break; |
| default: result.append(c); |
| } |
| } |
| |
| return result.toString(); |
| } |
| |
| public void emitActionTable() { |
| int lastAction = 1; |
| int count = 0; |
| int value = 0; |
| |
| println(" /** "); |
| println(" * Translates DFA states to action switch labels."); |
| println(" */"); |
| CountEmitter e = new CountEmitter("Action"); |
| e.emitInit(); |
| |
| for (int i = 0; i < dfa.numStates; i++) { |
| int newVal = 0; |
| if ( dfa.isFinal[i] ) { |
| Action action = dfa.action[i]; |
| if (action.isEmittable()) { |
| Integer stored = (Integer) actionTable.get(action); |
| if ( stored == null ) { |
| stored = new Integer(lastAction++); |
| actionTable.put(action, stored); |
| } |
| newVal = stored.intValue(); |
| } |
| } |
| |
| if (value == newVal) { |
| count++; |
| } |
| else { |
| if (count > 0) e.emit(count,value); |
| count = 1; |
| value = newVal; |
| } |
| } |
| |
| if (count > 0) e.emit(count,value); |
| |
| e.emitUnpack(); |
| println(e.toString()); |
| } |
| |
| private void emitActions() { |
| println(" switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) {"); |
| |
| int i = actionTable.size()+1; |
| Enumeration actions = actionTable.keys(); |
| while ( actions.hasMoreElements() ) { |
| Action action = (Action) actions.nextElement(); |
| int label = ((Integer) actionTable.get(action)).intValue(); |
| |
| println(" case "+label+": "); |
| |
| if (action.lookAhead() == Action.FIXED_BASE) { |
| println(" // lookahead expression with fixed base length"); |
| println(" zzMarkedPos = zzStartRead + "+action.getLookLength()+";"); |
| } |
| |
| if (action.lookAhead() == Action.FIXED_LOOK || |
| action.lookAhead() == Action.FINITE_CHOICE) { |
| println(" // lookahead expression with fixed lookahead length"); |
| println(" yypushback("+action.getLookLength()+");"); |
| } |
| |
| if (action.lookAhead() == Action.GENERAL_LOOK) { |
| println(" // general lookahead, find correct zzMarkedPos"); |
| println(" { int zzFState = "+dfa.entryState[action.getEntryState()]+";"); |
| println(" int zzFPos = zzStartRead;"); |
| println(" if (zzFin.length <= " + zzBufferLLength() + ") { zzFin = new boolean[" + zzBufferLLength() + "+1]; }"); |
| println(" boolean zzFinL[] = zzFin;"); |
| println(" while (zzFState != -1 && zzFPos < zzMarkedPos) {"); |
| println(" if ((zzAttrL[zzFState] & 1) == 1) { zzFinL[zzFPos] = true; } "); |
| println(" zzInput = " + zzBufferLAccess("zzFPos++") + ";"); |
| println(" zzFState = zzTransL[ zzRowMapL[zzFState] + zzCMapL[zzInput] ];"); |
| println(" }"); |
| println(" if (zzFState != -1 && (zzAttrL[zzFState] & 1) == 1) { zzFinL[zzFPos] = true; } "); |
| println(); |
| println(" zzFState = "+dfa.entryState[action.getEntryState()+1]+";"); |
| println(" zzFPos = zzMarkedPos;"); |
| println(" while (!zzFinL[zzFPos] || (zzAttrL[zzFState] & 1) != 1) {"); |
| println(" zzInput = " + zzBufferLAccess("--zzFPos") + ";"); |
| println(" zzFState = zzTransL[ zzRowMapL[zzFState] + zzCMapL[zzInput] ];"); |
| println(" };"); |
| println(" zzMarkedPos = zzFPos;"); |
| println(" }"); |
| } |
| |
| if ( scanner.debugOption ) { |
| print(" System.out.println("); |
| if ( scanner.lineCount ) |
| print("\"line: \"+(yyline+1)+\" \"+"); |
| if ( scanner.columnCount ) |
| print("\"col: \"+(yycolumn+1)+\" \"+"); |
| println("\"match: --\"+yytext()+\"--\");"); |
| print(" System.out.println(\"action ["+action.priority+"] { "); |
| print(escapify(action.content)); |
| println(" }\");"); |
| } |
| |
| println(" { "+action.content); |
| println(" }"); |
| println(" case "+(i++)+": break;"); |
| } |
| } |
| |
| private void emitEOFVal() { |
| EOFActions eofActions = parser.getEOFActions(); |
| |
| if ( scanner.eofCode != null ) |
| println(" zzDoEOF();"); |
| |
| if ( eofActions.numActions() > 0 ) { |
| println(" switch (zzLexicalState) {"); |
| |
| Enumeration stateNames = scanner.states.names(); |
| |
| // record lex states already emitted: |
| Hashtable used = new Hashtable(); |
| |
| // pick a start value for break case labels. |
| // must be larger than any value of a lex state: |
| int last = dfa.numStates; |
| |
| while ( stateNames.hasMoreElements() ) { |
| String name = (String) stateNames.nextElement(); |
| int num = scanner.states.getNumber(name).intValue(); |
| Action action = eofActions.getAction(num); |
| |
| if (action != null) { |
| println(" case "+name+": {"); |
| if ( scanner.debugOption ) { |
| print(" System.out.println("); |
| if ( scanner.lineCount ) |
| print("\"line: \"+(yyline+1)+\" \"+"); |
| if ( scanner.columnCount ) |
| print("\"col: \"+(yycolumn+1)+\" \"+"); |
| println("\"match: <<EOF>>\");"); |
| print(" System.out.println(\"action ["+action.priority+"] { "); |
| print(escapify(action.content)); |
| println(" }\");"); |
| } |
| println(" "+action.content); |
| println(" }"); |
| println(" case "+(++last)+": break;"); |
| } |
| } |
| |
| println(" default:"); |
| } |
| |
| Action defaultAction = eofActions.getDefault(); |
| |
| if (defaultAction != null) { |
| println(" {"); |
| if ( scanner.debugOption ) { |
| print(" System.out.println("); |
| if ( scanner.lineCount ) |
| print("\"line: \"+(yyline+1)+\" \"+"); |
| if ( scanner.columnCount ) |
| print("\"col: \"+(yycolumn+1)+\" \"+"); |
| println("\"match: <<EOF>>\");"); |
| print(" System.out.println(\"action ["+defaultAction.priority+"] { "); |
| print(escapify(defaultAction.content)); |
| println(" }\");"); |
| } |
| println(" " + defaultAction.content); |
| println(" }"); |
| } |
| else if ( scanner.eofVal != null ) |
| println(" { " + scanner.eofVal + " }"); |
| else if ( scanner.isInteger ) { |
| if ( scanner.tokenType != null ) { |
| Out.error(ErrorMessages.INT_AND_TYPE); |
| throw new GeneratorException(); |
| } |
| println(" return YYEOF;"); |
| } |
| else |
| println(" return null;"); |
| |
| if (eofActions.numActions() > 0) |
| println(" }"); |
| } |
| |
| private void emitState(int state) { |
| |
| println(" case "+state+":"); |
| println(" switch (zzInput) {"); |
| |
| int defaultTransition = getDefaultTransition(state); |
| |
| for (int next = 0; next < dfa.numStates; next++) { |
| |
| if ( next != defaultTransition && table[state][next] != null ) { |
| emitTransition(state, next); |
| } |
| } |
| |
| if ( defaultTransition != DFA.NO_TARGET && noTarget[state] != null ) { |
| emitTransition(state, DFA.NO_TARGET); |
| } |
| |
| emitDefaultTransition(state, defaultTransition); |
| |
| println(" }"); |
| println(""); |
| } |
| |
| private void emitTransition(int state, int nextState) { |
| |
| CharSetEnumerator chars; |
| |
| if (nextState != DFA.NO_TARGET) |
| chars = table[state][nextState].characters(); |
| else |
| chars = noTarget[state].characters(); |
| |
| print(" case "); |
| print(chars.nextElement()); |
| print(": "); |
| |
| while ( chars.hasMoreElements() ) { |
| println(); |
| print(" case "); |
| print(chars.nextElement()); |
| print(": "); |
| } |
| |
| if ( nextState != DFA.NO_TARGET ) { |
| if ( dfa.isFinal[nextState] ) |
| print("zzIsFinal = true; "); |
| |
| if ( !isTransition[nextState] ) |
| print("zzNoLookAhead = true; "); |
| |
| if ( nextState == state ) |
| println("break zzForNext;"); |
| else |
| println("zzState = "+nextState+"; break zzForNext;"); |
| } |
| else |
| println("break zzForAction;"); |
| } |
| |
| private void emitDefaultTransition(int state, int nextState) { |
| print(" default: "); |
| |
| if ( nextState != DFA.NO_TARGET ) { |
| if ( dfa.isFinal[nextState] ) |
| print("zzIsFinal = true; "); |
| |
| if ( !isTransition[nextState] ) |
| print("zzNoLookAhead = true; "); |
| |
| if ( nextState == state ) |
| println("break zzForNext;"); |
| else |
| println("zzState = "+nextState+"; break zzForNext;"); |
| } |
| else |
| println( "break zzForAction;" ); |
| } |
| |
| private int getDefaultTransition(int state) { |
| int max = 0; |
| |
| for (int i = 0; i < dfa.numStates; i++) { |
| if ( table[state][max] == null ) |
| max = i; |
| else |
| if ( table[state][i] != null && table[state][max].size() < table[state][i].size() ) |
| max = i; |
| } |
| |
| if ( table[state][max] == null ) return DFA.NO_TARGET; |
| if ( noTarget[state] == null ) return max; |
| |
| if ( table[state][max].size() < noTarget[state].size() ) |
| max = DFA.NO_TARGET; |
| |
| return max; |
| } |
| |
| // for switch statement: |
| private void transformTransitionTable() { |
| |
| int numInput = parser.getCharClasses().getNumClasses()+1; |
| |
| int i; |
| char j; |
| |
| table = new CharSet[dfa.numStates][dfa.numStates]; |
| noTarget = new CharSet[dfa.numStates]; |
| |
| for (i = 0; i < dfa.numStates; i++) |
| for (j = 0; j < dfa.numInput; j++) { |
| |
| int nextState = dfa.table[i][j]; |
| |
| if ( nextState == DFA.NO_TARGET ) { |
| if ( noTarget[i] == null ) |
| noTarget[i] = new CharSet(numInput, colMap[j]); |
| else |
| noTarget[i].add(colMap[j]); |
| } |
| else { |
| if ( table[i][nextState] == null ) |
| table[i][nextState] = new CharSet(numInput, colMap[j]); |
| else |
| table[i][nextState].add(colMap[j]); |
| } |
| } |
| } |
| |
| private void findActionStates() { |
| isTransition = new boolean [dfa.numStates]; |
| |
| for (int i = 0; i < dfa.numStates; i++) { |
| char j = 0; |
| while ( !isTransition[i] && j < dfa.numInput ) |
| isTransition[i] = dfa.table[i][j++] != DFA.NO_TARGET; |
| } |
| } |
| |
| |
| private void reduceColumns() { |
| colMap = new int [dfa.numInput]; |
| colKilled = new boolean [dfa.numInput]; |
| |
| int i,j,k; |
| int translate = 0; |
| boolean equal; |
| |
| numCols = dfa.numInput; |
| |
| for (i = 0; i < dfa.numInput; i++) { |
| |
| colMap[i] = i-translate; |
| |
| for (j = 0; j < i; j++) { |
| |
| // test for equality: |
| k = -1; |
| equal = true; |
| while (equal && ++k < dfa.numStates) |
| equal = dfa.table[k][i] == dfa.table[k][j]; |
| |
| if (equal) { |
| translate++; |
| colMap[i] = colMap[j]; |
| colKilled[i] = true; |
| numCols--; |
| break; |
| } // if |
| } // for j |
| } // for i |
| } |
| |
| private void reduceRows() { |
| rowMap = new int [dfa.numStates]; |
| rowKilled = new boolean [dfa.numStates]; |
| |
| int i,j,k; |
| int translate = 0; |
| boolean equal; |
| |
| numRows = dfa.numStates; |
| |
| // i is the state to add to the new table |
| for (i = 0; i < dfa.numStates; i++) { |
| |
| rowMap[i] = i-translate; |
| |
| // check if state i can be removed (i.e. already |
| // exists in entries 0..i-1) |
| for (j = 0; j < i; j++) { |
| |
| // test for equality: |
| k = -1; |
| equal = true; |
| while (equal && ++k < dfa.numInput) |
| equal = dfa.table[i][k] == dfa.table[j][k]; |
| |
| if (equal) { |
| translate++; |
| rowMap[i] = rowMap[j]; |
| rowKilled[i] = true; |
| numRows--; |
| break; |
| } // if |
| } // for j |
| } // for i |
| |
| } |
| |
| |
| /** |
| * Set up EOF code section according to scanner.eofcode |
| */ |
| private void setupEOFCode() { |
| if (scanner.eofclose) { |
| scanner.eofCode = LexScan.conc(scanner.eofCode, " yyclose();"); |
| scanner.eofThrow = LexScan.concExc(scanner.eofThrow, "java.io.IOException"); |
| } |
| } |
| |
| |
| /** |
| * Main Emitter method. |
| */ |
| public void emit() { |
| |
| setupEOFCode(); |
| |
| if (scanner.functionName == null) |
| scanner.functionName = "yylex"; |
| |
| reduceColumns(); |
| findActionStates(); |
| |
| emitHeader(); |
| emitUserCode(); |
| emitClassName(); |
| |
| skel.emitNext(); |
| |
| println(" private static final int ZZ_BUFFERSIZE = "+scanner.bufferSize+";"); |
| |
| if (scanner.debugOption) { |
| println(" private static final String ZZ_NL = System.getProperty(\"line.separator\");"); |
| } |
| |
| skel.emitNext(); |
| |
| emitLexicalStates(); |
| |
| emitCharMapArray(); |
| |
| emitActionTable(); |
| |
| if (scanner.useRowMap) { |
| reduceRows(); |
| |
| emitRowMapArray(); |
| |
| if (scanner.packed) |
| emitDynamicInit(); |
| else |
| emitZZTrans(); |
| } |
| |
| skel.emitNext(); |
| |
| if (scanner.useRowMap) |
| emitAttributes(); |
| |
| skel.emitNext(); |
| |
| emitLookBuffer(); |
| |
| emitClassCode(); |
| |
| skel.emitNext(); |
| |
| emitConstructorDecl(); |
| |
| emitCharMapInitFunction(); |
| |
| skel.emitNext(); |
| |
| emitScanError(); |
| |
| skel.emitNext(); |
| |
| emitDoEOF(); |
| |
| skel.emitNext(); |
| |
| emitLexFunctHeader(); |
| |
| emitNextInput(); |
| |
| if (scanner.useRowMap) |
| emitGetRowMapNext(); |
| else |
| emitTransitionTable(); |
| |
| skel.emitNext(); |
| |
| emitActions(); |
| |
| skel.emitNext(); |
| |
| emitEOFVal(); |
| |
| skel.emitNext(); |
| |
| emitNoMatch(); |
| |
| skel.emitNext(); |
| |
| emitMain(); |
| |
| skel.emitNext(); |
| |
| out.close(); |
| } |
| |
| } |