7ca5bab577455642ce6d75d0c9a9128cdc2f093c
[idea/community.git] / tools / lexer / jflex-1.4 / src / JFlex / Emitter.java
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * JFlex 1.4.3                                                             *
3  * Copyright (C) 1998-2009  Gerwin Klein <lsf@jflex.de>                    *
4  * All rights reserved.                                                    *
5  *                                                                         *
6  * This program is free software; you can redistribute it and/or modify    *
7  * it under the terms of the GNU General Public License. See the file      *
8  * COPYRIGHT for more information.                                         *
9  *                                                                         *
10  * This program is distributed in the hope that it will be useful,         *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of          *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
13  * GNU General Public License for more details.                            *
14  *                                                                         *
15  * You should have received a copy of the GNU General Public License along *
16  * with this program; if not, write to the Free Software Foundation, Inc., *
17  * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                 *
18  *                                                                         *
19  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
20
21 package JFlex;
22
23 import java.io.*;
24 import java.util.*;
25 import java.text.*;
26
27 /**
28  * This class manages the actual code generation, putting
29  * the scanner together, filling in skeleton sections etc.
30  *
31  * Table compression, String packing etc. is also done here.
32  *
33  * @author Gerwin Klein
34  * @version $Revision: 1.4.3 $, $Date: 2009/12/21 15:58:48 $
35  */
36 final public class Emitter {
37     
38   // bit masks for state attributes
39   static final private int FINAL = 1;
40   static final private int NOLOOK = 8;
41
42   static final private String date = (new SimpleDateFormat()).format(new Date());
43
44   private File inputFile;
45
46   private PrintWriter out;
47   private Skeleton skel;
48   private LexScan scanner;
49   private LexParse parser;
50   private DFA dfa;
51
52   // for switch statement:
53   // table[i][j] is the set of input characters that leads from state i to state j
54   private CharSet table[][];
55
56   private boolean isTransition[];
57   
58   // noTarget[i] is the set of input characters that have no target state in state i
59   private CharSet noTarget[];
60       
61   // for row killing:
62   private int numRows;
63   private int [] rowMap;
64   private boolean [] rowKilled;
65   
66   // for col killing:
67   private int numCols;
68   private int [] colMap;
69   private boolean [] colKilled;
70   
71
72   /** maps actions to their switch label */
73   private Hashtable actionTable = new Hashtable();
74
75   private CharClassInterval [] intervals;
76
77   private String visibility = "public";
78
79   public Emitter(File inputFile, LexParse parser, DFA dfa) throws IOException {
80
81     String name = getBaseName(parser.scanner.className) + ".java";
82
83     File outputFile = normalize(name, inputFile);
84
85     Out.println("Writing code to \""+outputFile+"\"");
86     
87     this.out = new PrintWriter(new BufferedWriter(new FileWriter(outputFile)));
88     this.parser = parser;
89     this.scanner = parser.scanner;
90     this.visibility = scanner.visibility;
91     this.inputFile = inputFile;
92     this.dfa = dfa;
93     this.skel = new Skeleton(out);
94   }
95
96   /**
97    * Computes base name of the class name. Needs to take into account generics.
98    *
99    * @see LexScan#className
100    * @return the
101    */
102   public static String getBaseName(String className) {
103     int gen = className.indexOf('<');
104     if (gen < 0) {
105       return className;
106     }
107     else {
108       return className.substring(0, gen);
109     }
110   }
111   
112
113   /**
114    * Constructs a file in Options.getDir() or in the same directory as
115    * another file. Makes a backup if the file already exists.
116    *
117    * @param name  the name (without path) of the file
118    * @param path  the path where to construct the file
119    * @param input fall back location if path = <tt>null</tt>
120    *              (expected to be a file in the directory to write to)   
121    */
122   public static File normalize(String name, File input) {
123     File outputFile;
124
125     if ( Options.getDir() == null ) 
126       if ( input == null || input.getParent() == null )
127         outputFile = new File(name);
128       else
129         outputFile = new File(input.getParent(), name);
130     else 
131       outputFile = new File(Options.getDir(), name);
132         
133     if ( outputFile.exists() && !Options.no_backup ) {      
134       File backup = new File( outputFile.toString()+"~" );
135       
136       if ( backup.exists() ) backup.delete();
137       
138       if ( outputFile.renameTo( backup ) )
139         Out.println("Old file \""+outputFile+"\" saved as \""+backup+"\"");
140       else
141         Out.println("Couldn't save old file \""+outputFile+"\", overwriting!");
142     }
143
144     return outputFile;
145   }
146   
147   private void println() {
148     out.println();
149   }
150
151   private void println(String line) {
152     out.println(line);
153   }
154
155   private void println(int i) {
156     out.println(i);
157   }
158
159   private void print(String line) {
160     out.print(line);
161   }
162
163   private void print(int i) {
164     out.print(i);
165   }
166
167   private void print(int i, int tab) {
168     int exp;
169
170     if (i < 0) 
171       exp = 1;
172     else
173       exp = 10;
174
175     while (tab-- > 1) {
176       if (Math.abs(i) < exp) print(" ");
177       exp*= 10;
178     }
179
180     print(i);
181   }
182
183   private boolean hasGenLookAhead() {
184     return dfa.lookaheadUsed;
185   }
186   
187   private void emitLookBuffer() {
188     if (!hasGenLookAhead()) return;
189     
190     println("  /** For the backwards DFA of general lookahead statements */");
191     println("  private boolean [] zzFin = new boolean [ZZ_BUFFERSIZE+1];");
192     println();
193   }
194   
195   private void emitScanError() {
196     print("  private void zzScanError(int errorCode)");
197     
198     if (scanner.scanErrorException != null) 
199       print(" throws "+scanner.scanErrorException);
200
201     println(" {");
202
203     skel.emitNext();
204
205     if (scanner.scanErrorException == null)
206       println("    throw new Error(message);");
207     else
208       println("    throw new "+scanner.scanErrorException+"(message);");    
209
210     skel.emitNext();
211
212     print("  "+visibility+" void yypushback(int number) ");     
213     
214     if (scanner.scanErrorException == null)
215       println(" {");
216     else       
217       println(" throws "+scanner.scanErrorException+" {");
218   }
219
220   private void emitMain() {
221     if ( !(scanner.standalone || scanner.debugOption || scanner.cupDebug) ) return;
222
223     if ( scanner.cupDebug ) {
224       println("  /**");
225       println("   * Converts an int token code into the name of the");
226       println("   * token by reflection on the cup symbol class/interface "+scanner.cupSymbol);
227       println("   *");
228       println("   * This code was contributed by Karl Meissner <meissnersd@yahoo.com>"); 
229       println("   */");
230       println("  private String getTokenName(int token) {");
231       println("    try {");
232       println("      java.lang.reflect.Field [] classFields = " + scanner.cupSymbol + ".class.getFields();");
233       println("      for (int i = 0; i < classFields.length; i++) {");
234       println("        if (classFields[i].getInt(null) == token) {");
235       println("          return classFields[i].getName();");
236       println("        }");
237       println("      }");
238       println("    } catch (Exception e) {");
239       println("      e.printStackTrace(System.err);");
240       println("    }");
241       println("");
242       println("    return \"UNKNOWN TOKEN\";");
243       println("  }");
244       println("");
245       println("  /**");
246       println("   * Same as "+scanner.functionName+" but also prints the token to standard out");
247       println("   * for debugging.");
248       println("   *");
249       println("   * This code was contributed by Karl Meissner <meissnersd@yahoo.com>"); 
250       println("   */");
251
252       print("  "+visibility+" ");
253       if ( scanner.tokenType == null ) {
254         if ( scanner.isInteger )
255           print( "int" );
256         else 
257           if ( scanner.isIntWrap )
258             print( "Integer" );
259           else
260             print( "Yytoken" );
261       }
262       else
263         print( scanner.tokenType );
264       
265       print(" debug_");
266       
267       print(scanner.functionName);
268       
269       print("() throws java.io.IOException");
270     
271       if ( scanner.lexThrow != null ) {
272         print(", ");
273         print(scanner.lexThrow);
274       }
275
276       if ( scanner.scanErrorException != null ) {
277         print(", ");
278         print(scanner.scanErrorException);
279       }
280       
281       println(" {");
282
283       println("    java_cup.runtime.Symbol s = "+scanner.functionName+"();");
284       print("    System.out.println( ");
285       if (scanner.lineCount) print("\"line:\" + (yyline+1) + ");
286       if (scanner.columnCount) print("\" col:\" + (yycolumn+1) + ");
287       println("\" --\"+ yytext() + \"--\" + getTokenName(s.sym) + \"--\");");
288       println("    return s;");
289       println("  }");
290       println("");
291     }
292
293     if ( scanner.standalone ) {
294       println("  /**");
295       println("   * Runs the scanner on input files.");
296       println("   *");
297       println("   * This is a standalone scanner, it will print any unmatched");
298       println("   * text to System.out unchanged.");      
299       println("   *");
300       println("   * @param argv   the command line, contains the filenames to run");
301       println("   *               the scanner on.");
302       println("   */");
303     }
304     else {
305       println("  /**");
306       println("   * Runs the scanner on input files.");
307       println("   *");
308       println("   * This main method is the debugging routine for the scanner.");
309       println("   * It prints debugging information about each returned token to");
310       println("   * System.out until the end of file is reached, or an error occured.");
311       println("   *"); 
312       println("   * @param argv   the command line, contains the filenames to run");
313       println("   *               the scanner on."); 
314       println("   */"); 
315     }      
316     
317     String className = getBaseName(scanner.className);
318     
319     println("  public static void main(String argv[]) {");
320     println("    if (argv.length == 0) {");
321     println("      System.out.println(\"Usage : java "+className+" <inputfile>\");");
322     println("    }");
323     println("    else {");
324     println("      for (int i = 0; i < argv.length; i++) {");
325     println("        "+className+" scanner = null;");
326     println("        try {");
327     println("          scanner = new "+className+"( new java.io.FileReader(argv[i]) );");
328
329     if ( scanner.standalone ) {      
330       println("          while ( !scanner.zzAtEOF ) scanner."+scanner.functionName+"();");
331     }
332     else if (scanner.cupDebug ) {
333       println("          while ( !scanner.zzAtEOF ) scanner.debug_"+scanner.functionName+"();");
334     }
335     else {
336       println("          do {");
337       println("            System.out.println(scanner."+scanner.functionName+"());");
338       println("          } while (!scanner.zzAtEOF);");
339       println("");
340     }
341  
342     println("        }");
343     println("        catch (java.io.FileNotFoundException e) {");
344     println("          System.out.println(\"File not found : \\\"\"+argv[i]+\"\\\"\");");
345     println("        }");
346     println("        catch (java.io.IOException e) {");
347     println("          System.out.println(\"IO error scanning file \\\"\"+argv[i]+\"\\\"\");");
348     println("          System.out.println(e);");
349     println("        }"); 
350     println("        catch (Exception e) {");
351     println("          System.out.println(\"Unexpected exception:\");");
352     println("          e.printStackTrace();");
353     println("        }"); 
354     println("      }");
355     println("    }");
356     println("  }");
357     println("");    
358   }
359   
360   private String zzBufferLAccess(String idx) {
361     if (Options.sliceAndCharAt) {
362       return "(zzBufferArrayL != null ? zzBufferArrayL[" + idx + "] : zzBufferL.charAt("+idx+"))";
363     }
364     if (Options.char_at) {
365       return "zzBufferL.charAt("+idx+")";
366     }
367     return "zzBufferL[" + idx + "]";
368   }
369
370   private String zzBufferLLength() {
371     if (Options.sliceAndCharAt) {
372       return "(zzBufferArrayL != null ? zzBufferArrayL.length : zzBufferL.length())";
373     }
374     if (Options.char_at) {
375       return "zzBufferL.length()";
376     }
377     return "zzBufferL.length";
378   }
379
380   private void emitNoMatch() {
381     println("            zzScanError(ZZ_NO_MATCH);");
382   }
383   
384   private void emitNextInput() {
385     println("          if (zzCurrentPosL < zzEndReadL)");
386     println("            zzInput = " + zzBufferLAccess("zzCurrentPosL++") + ";");
387     println("          else if (zzAtEOF) {");
388     println("            zzInput = YYEOF;");
389     println("            break zzForAction;");
390     println("          }");
391     println("          else {");
392     println("            // store back cached positions");
393     println("            zzCurrentPos  = zzCurrentPosL;");
394     println("            zzMarkedPos   = zzMarkedPosL;");
395     println("            boolean eof = zzRefill();");
396     println("            // get translated positions and possibly new buffer");
397     println("            zzCurrentPosL  = zzCurrentPos;");
398     println("            zzMarkedPosL   = zzMarkedPos;");
399     println("            zzBufferL      = zzBuffer;");
400     println("            zzEndReadL     = zzEndRead;");
401     println("            if (eof) {");
402     println("              zzInput = YYEOF;");
403     println("              break zzForAction;");  
404     println("            }");
405     println("            else {");
406     println("              zzInput = " + zzBufferLAccess("zzCurrentPosL++") + ";");
407     println("            }");
408     println("          }"); 
409   }
410
411   private void emitHeader() {
412     println("/* The following code was generated by JFlex "+Main.version+" on "+date+" */");   
413     println(""); 
414   } 
415
416   private void emitUserCode() {
417     if ( scanner.userCode.length() > 0 )
418       println(scanner.userCode.toString());
419   }
420
421   private void emitClassName() {    
422     if (!endsWithJavadoc(scanner.userCode)) {
423       String path = inputFile.toString();
424       // slashify path (avoid backslash u sequence = unicode escape)
425       if (File.separatorChar != '/') {
426             path = path.replace(File.separatorChar, '/');
427       }
428         
429       println("/**");
430       println(" * This class is a scanner generated by ");
431       println(" * <a href=\"http://www.jflex.de/\">JFlex</a> "+Main.version);
432       println(" * on "+date+" from the specification file");    
433       println(" * <tt>"+path+"</tt>");      
434       println(" */");
435     }   
436
437     if ( scanner.isPublic ) print("public ");
438
439     if ( scanner.isAbstract) print("abstract ");
440    
441     if ( scanner.isFinal ) print("final ");
442     
443     print("class ");
444     print(scanner.className);
445     
446     if ( scanner.isExtending != null ) {
447       print(" extends ");
448       print(scanner.isExtending);
449     }
450
451     if ( scanner.isImplementing != null ) {
452       print(" implements ");
453       print(scanner.isImplementing);
454     }   
455     
456     println(" {");
457   }  
458
459   /**
460    * Try to find out if user code ends with a javadoc comment 
461    * 
462    * @param buffer   the user code
463    * @return true    if it ends with a javadoc comment
464    */
465   public static boolean endsWithJavadoc(StringBuffer usercode) {
466     String s = usercode.toString().trim();
467         
468     if (!s.endsWith("*/")) return false;
469     
470     // find beginning of javadoc comment   
471     int i = s.lastIndexOf("/**");    
472     if (i < 0) return false; 
473        
474     // javadoc comment shouldn't contain a comment end
475     return s.substring(i,s.length()-2).indexOf("*/") < 0;
476   }
477
478
479   private void emitLexicalStates() {
480     Enumeration stateNames = scanner.states.names();
481     
482     while ( stateNames.hasMoreElements() ) {
483       String name = (String) stateNames.nextElement();
484       
485       int num = scanner.states.getNumber(name).intValue();
486
487       println("  "+visibility+" static final int "+name+" = "+2*num+";");
488     }
489
490     // can't quite get rid of the indirection, even for non-bol lex states: 
491     // their DFA states might be the same, but their EOF actions might be different
492     // (see bug #1540228)
493     println("");
494     println("  /**");
495     println("   * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l");
496     println("   * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l");
497     println("   *                  at the beginning of a line");
498     println("   * l is of the form l = 2*k, k a non negative integer");
499     println("   */");
500     println("  private static final int ZZ_LEXSTATE[] = { ");
501   
502     int i, j = 0;
503     print("    ");
504     
505     for (i = 0; i < 2*dfa.numLexStates-1; i++) {
506       print( dfa.entryState[i], 2 );
507
508       print(", ");
509
510       if (++j >= 16) {
511         println();
512         print("    ");
513         j = 0;
514       }
515     }
516             
517     println( dfa.entryState[i] );
518     println("  };");
519   }
520
521   private void emitDynamicInit() {    
522     int count = 0;
523     int value = dfa.table[0][0];
524
525     println("  /** ");
526     println("   * The transition table of the DFA");
527     println("   */");
528
529     CountEmitter e = new CountEmitter("Trans");
530     e.setValTranslation(+1); // allow vals in [-1, 0xFFFE]
531     e.emitInit();
532     
533     for (int i = 0; i < dfa.numStates; i++) {
534       if ( !rowKilled[i] ) {
535         for (int c = 0; c < dfa.numInput; c++) {
536           if ( !colKilled[c] ) {
537             if (dfa.table[i][c] == value) {
538               count++;
539             } 
540             else {
541               e.emit(count, value);
542
543               count = 1;
544               value = dfa.table[i][c];              
545             }
546           }
547         }
548       }
549     }
550
551     e.emit(count, value);
552     e.emitUnpack();
553     
554     println(e.toString());
555   }
556
557
558   private void emitCharMapInitFunction() {
559
560     CharClasses cl = parser.getCharClasses();
561     
562     if ( cl.getMaxCharCode() < 256 ) return;
563
564     println("");
565     println("  /** ");
566     println("   * Unpacks the compressed character translation table.");
567     println("   *");
568     println("   * @param packed   the packed character translation table");
569     println("   * @return         the unpacked character translation table");
570     println("   */");
571     println("  private static char [] zzUnpackCMap(String packed) {");
572     println("    char [] map = new char[0x10000];");
573     println("    int i = 0;  /* index in packed string  */");
574     println("    int j = 0;  /* index in unpacked array */");
575     println("    while (i < "+2*intervals.length+") {");
576     println("      int  count = packed.charAt(i++);");
577     println("      char value = packed.charAt(i++);");
578     println("      do map[j++] = value; while (--count > 0);");
579     println("    }");
580     println("    return map;");
581     println("  }");
582   }
583
584   private void emitZZTrans() {    
585
586     int i,c;
587     int n = 0;
588     
589     println("  /** ");
590     println("   * The transition table of the DFA");
591     println("   */");
592     println("  private static final int ZZ_TRANS [] = {"); 
593
594     print("    ");
595     for (i = 0; i < dfa.numStates; i++) {
596       
597       if ( !rowKilled[i] ) {        
598         for (c = 0; c < dfa.numInput; c++) {          
599           if ( !colKilled[c] ) {            
600             if (n >= 10) {
601               println();
602               print("    ");
603               n = 0;
604             }
605             print( dfa.table[i][c] );
606             if (i != dfa.numStates-1 || c != dfa.numInput-1)
607               print( ", ");
608             n++;
609           }
610         }
611       }
612     }
613
614     println();
615     println("  };");
616   }
617   
618   private void emitCharMapArrayUnPacked() {
619   
620     CharClasses cl = parser.getCharClasses();
621     
622     println("");
623     println("  /** ");
624     println("   * Translates characters to character classes");
625     println("   */");
626     println("  private static final char [] ZZ_CMAP = {");
627   
628     int n = 0;  // numbers of entries in current line    
629     print("    ");
630     
631     int max =  cl.getMaxCharCode();
632         
633     // not very efficient, but good enough for <= 255 characters
634     for (char c = 0; c <= max; c++) {
635       print(colMap[cl.getClassCode(c)],2);
636       
637       if (c < max) {
638         print(", ");        
639         if ( ++n >= 16 ) { 
640           println();
641           print("    ");
642           n = 0; 
643         }
644       }
645     }
646     
647     println();
648     println("  };");
649     println();
650   }
651
652   private void emitCharMapArray() {       
653     CharClasses cl = parser.getCharClasses();
654
655     if ( cl.getMaxCharCode() < 256 ) {
656       emitCharMapArrayUnPacked();
657       return;
658     }
659
660     // ignores cl.getMaxCharCode(), emits all intervals instead
661
662     intervals = cl.getIntervals();
663     
664     println("");
665     println("  /** ");
666     println("   * Translates characters to character classes");
667     println("   */");
668     println("  private static final String ZZ_CMAP_PACKED = ");
669   
670     int n = 0;  // numbers of entries in current line    
671     print("    \"");
672     
673     int i = 0;
674     int count, value;
675     while ( i < intervals.length ) {
676       count = intervals[i].end-intervals[i].start+1;
677       value = colMap[intervals[i].charClass];
678
679       // count could be >= 0x10000
680       while (count > 0xFFFF) {
681         printUC(0xFFFF);
682         printUC(value);
683         count -= 0xFFFF;
684         n++;       
685       }
686         
687       printUC(count);
688       printUC(value);
689
690       if (i < intervals.length-1) {
691         if ( ++n >= 10 ) { 
692           println("\"+");
693           print("    \"");
694           n = 0;
695         }
696       }
697
698       i++;
699     }
700       
701     println("\";");
702     println();
703
704     println("  /** ");
705     println("   * Translates characters to character classes");
706     println("   */");
707     println("  private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED);");
708     println();
709   }
710
711
712   /**
713    * Print number as octal/unicode escaped string character.
714    * 
715    * @param c   the value to print
716    * @prec  0 <= c <= 0xFFFF 
717    */
718   private void printUC(int c) {
719     if (c > 255) {
720       out.print("\\u");
721       if (c < 0x1000) out.print("0");
722       out.print(Integer.toHexString(c));
723     }
724     else {
725       out.print("\\");
726       out.print(Integer.toOctalString(c));
727     }    
728   }
729
730
731   private void emitRowMapArray() {
732     println("");
733     println("  /** ");
734     println("   * Translates a state to a row index in the transition table");
735     println("   */");
736     
737     HiLowEmitter e = new HiLowEmitter("RowMap");
738     e.emitInit();
739     for (int i = 0; i < dfa.numStates; i++) {
740       e.emit(rowMap[i]*numCols);
741     }    
742     e.emitUnpack();
743     println(e.toString());
744   }
745
746
747   private void emitAttributes() {
748     println("  /**");
749     println("   * ZZ_ATTRIBUTE[aState] contains the attributes of state <code>aState</code>");
750     println("   */");
751     
752     CountEmitter e = new CountEmitter("Attribute");    
753     e.emitInit();
754     
755     int count = 1;
756     int value = 0; 
757     if ( dfa.isFinal[0]    ) value = FINAL;
758     if ( !isTransition[0]  ) value|= NOLOOK;
759        
760     for (int i = 1;  i < dfa.numStates; i++) {      
761       int attribute = 0;      
762       if ( dfa.isFinal[i]    ) attribute = FINAL;
763       if ( !isTransition[i]  ) attribute|= NOLOOK;
764
765       if (value == attribute) {
766         count++;
767       }
768       else {        
769         e.emit(count, value);
770         count = 1;
771         value = attribute;
772       }
773     }
774     
775     e.emit(count, value);    
776     e.emitUnpack();
777     
778     println(e.toString());
779   }
780
781
782   private void emitClassCode() {
783     if ( scanner.eofCode != null ) {
784       println("  /** denotes if the user-EOF-code has already been executed */");
785       println("  private boolean zzEOFDone;");
786       println("");
787     }
788
789     if ( scanner.classCode != null ) {
790       println("  /* user code: */");
791       println(scanner.classCode);
792     }
793   }
794
795   private void emitConstructorDecl() {
796     emitConstructorDecl(true);
797     
798     if ((scanner.standalone || scanner.debugOption) && 
799         scanner.ctorArgs.size() > 0) {
800       Out.warning(ErrorMessages.get(ErrorMessages.CTOR_DEBUG));
801       println();
802       emitConstructorDecl(false);
803     }
804   }
805   
806   private void emitConstructorDecl(boolean printCtorArgs) {
807  
808     String warn = 
809         "// WARNING: this is a default constructor for " +
810         "debug/standalone only. Has no custom parameters or init code.";
811     
812     if (!printCtorArgs) println(warn); 
813     
814     print("  ");
815
816     if ( scanner.isPublic ) print("public ");   
817     print( getBaseName(scanner.className) );      
818     print("(java.io.Reader in");
819     if (printCtorArgs) emitCtorArgs();
820     print(")");
821     
822     if ( scanner.initThrow != null && printCtorArgs) {
823       print(" throws ");
824       print( scanner.initThrow );
825     }
826     
827     println(" {");
828
829     if ( scanner.initCode != null && printCtorArgs) {
830       print("  ");
831       print( scanner.initCode );
832     }
833
834     println("    this.zzReader = in;");
835
836     println("  }");
837     println();
838
839     
840     println("  /**");
841     println("   * Creates a new scanner.");
842     println("   * There is also java.io.Reader version of this constructor.");
843     println("   *");
844     println("   * @param   in  the java.io.Inputstream to read input from.");
845     println("   */");
846     if (!printCtorArgs) println(warn);
847     
848     print("  ");
849     if ( scanner.isPublic ) print("public ");    
850     print( getBaseName(scanner.className) );      
851     print("(java.io.InputStream in");
852     if (printCtorArgs) emitCtorArgs();
853     print(")");
854     
855     if ( scanner.initThrow != null && printCtorArgs ) {
856       print(" throws ");
857       print( scanner.initThrow );
858     }
859     
860     println(" {");    
861
862     print("    this(new java.io.InputStreamReader(in)");
863     if (printCtorArgs) {
864       for (int i=0; i < scanner.ctorArgs.size(); i++) {
865         print(", "+scanner.ctorArgs.elementAt(i));
866       }      
867     }
868     println(");");
869     
870     println("  }");
871   }
872
873   private void emitCtorArgs() {
874     for (int i = 0; i < scanner.ctorArgs.size(); i++) {
875       print(", "+scanner.ctorTypes.elementAt(i));
876       print(" "+scanner.ctorArgs.elementAt(i));
877     }    
878   }
879
880   private void emitDoEOF() {
881     if ( scanner.eofCode == null ) return;
882     
883     println("  /**");
884     println("   * Contains user EOF-code, which will be executed exactly once,");
885     println("   * when the end of file is reached");
886     println("   */");
887     
888     print("  private void zzDoEOF()");
889     
890     if ( scanner.eofThrow != null ) {
891       print(" throws ");
892       print(scanner.eofThrow);
893     }
894     
895     println(" {");
896     
897     println("    if (!zzEOFDone) {");
898     println("      zzEOFDone = true;");
899     println("    "+scanner.eofCode );
900     println("    }");
901     println("  }");
902     println("");
903     println("");
904   }
905
906   private void emitLexFunctHeader() {
907     
908     if (scanner.cupCompatible)  {
909       // force public, because we have to implement java_cup.runtime.Symbol
910       print("  public ");
911     }
912     else {
913       print("  "+visibility+" ");
914     }
915     
916     if ( scanner.tokenType == null ) {
917       if ( scanner.isInteger )
918         print( "int" );
919       else 
920       if ( scanner.isIntWrap )
921         print( "Integer" );
922       else
923         print( "Yytoken" );
924     }
925     else
926       print( scanner.tokenType );
927       
928     print(" ");
929     
930     print(scanner.functionName);
931       
932     print("() throws java.io.IOException");
933     
934     if ( scanner.lexThrow != null ) {
935       print(", ");
936       print(scanner.lexThrow);
937     }
938
939     if ( scanner.scanErrorException != null ) {
940       print(", ");
941       print(scanner.scanErrorException);
942     }
943     
944     println(" {");
945     
946     skel.emitNext();
947
948     if ( scanner.useRowMap ) {
949       println("    int [] zzTransL = ZZ_TRANS;");
950       println("    int [] zzRowMapL = ZZ_ROWMAP;");
951       println("    int [] zzAttrL = ZZ_ATTRIBUTE;");
952
953     }
954
955     skel.emitNext();    
956         
957     if ( scanner.charCount ) {
958       println("      yychar+= zzMarkedPosL-zzStartRead;");
959       println("");
960     }
961     
962     if ( scanner.lineCount || scanner.columnCount ) {
963       println("      boolean zzR = false;");
964       println("      for (zzCurrentPosL = zzStartRead; zzCurrentPosL < zzMarkedPosL;");
965       println("                                                             zzCurrentPosL++) {");
966       println("        switch (" + zzBufferLAccess("zzCurrentPosL") + ") {");
967       println("        case '\\u000B':"); 
968       println("        case '\\u000C':"); 
969       println("        case '\\u0085':");
970       println("        case '\\u2028':"); 
971       println("        case '\\u2029':"); 
972       if ( scanner.lineCount )
973         println("          yyline++;");
974       if ( scanner.columnCount )
975         println("          yycolumn = 0;");
976       println("          zzR = false;");
977       println("          break;");      
978       println("        case '\\r':");
979       if ( scanner.lineCount )
980         println("          yyline++;");
981       if ( scanner.columnCount )
982         println("          yycolumn = 0;");
983       println("          zzR = true;");
984       println("          break;");
985       println("        case '\\n':");
986       println("          if (zzR)");
987       println("            zzR = false;");
988       println("          else {");
989       if ( scanner.lineCount )
990         println("            yyline++;");
991       if ( scanner.columnCount )
992         println("            yycolumn = 0;");
993       println("          }");
994       println("          break;");
995       println("        default:");
996       println("          zzR = false;");
997       if ( scanner.columnCount ) 
998         println("          yycolumn++;");
999       println("        }");
1000       println("      }");
1001       println();
1002
1003       if ( scanner.lineCount ) {
1004         println("      if (zzR) {");
1005         println("        // peek one character ahead if it is \\n (if we have counted one line too much)");
1006         println("        boolean zzPeek;");
1007         println("        if (zzMarkedPosL < zzEndReadL)");
1008         println("          zzPeek = " + zzBufferLAccess("zzMarkedPosL") + " == '\\n';");
1009         println("        else if (zzAtEOF)");
1010         println("          zzPeek = false;");
1011         println("        else {");
1012         println("          boolean eof = zzRefill();");
1013         println("          zzEndReadL = zzEndRead;");
1014         println("          zzMarkedPosL = zzMarkedPos;");
1015         println("          zzBufferL = zzBuffer;");
1016         println("          if (eof) ");
1017         println("            zzPeek = false;");
1018         println("          else ");
1019         println("            zzPeek = " +  zzBufferLAccess("zzMarkedPosL") + " == '\\n';");
1020         println("        }");
1021         println("        if (zzPeek) yyline--;");
1022         println("      }");
1023       }
1024     }
1025
1026     if ( scanner.bolUsed ) {
1027       // zzMarkedPos > zzStartRead <=> last match was not empty
1028       // if match was empty, last value of zzAtBOL can be used
1029       // zzStartRead is always >= 0
1030       println("      if (zzMarkedPosL > zzStartRead) {");
1031       println("        switch (" + zzBufferLAccess("zzMarkedPosL-1") + ") {");
1032       println("        case '\\n':");
1033       println("        case '\\u000B':"); 
1034       println("        case '\\u000C':"); 
1035       println("        case '\\u0085':");
1036       println("        case '\\u2028':"); 
1037       println("        case '\\u2029':"); 
1038       println("          zzAtBOL = true;");
1039       println("          break;"); 
1040       println("        case '\\r': "); 
1041       println("          if (zzMarkedPosL < zzEndReadL)");
1042       println("            zzAtBOL = " + zzBufferLAccess("zzMarkedPosL") + " != '\\n';");
1043       println("          else if (zzAtEOF)");
1044       println("            zzAtBOL = false;");
1045       println("          else {");
1046       println("            boolean eof = zzRefill();");
1047       println("            zzMarkedPosL = zzMarkedPos;");
1048       println("            zzEndReadL = zzEndRead;");
1049       println("            zzBufferL = zzBuffer;");
1050       println("            if (eof) ");
1051       println("              zzAtBOL = false;");
1052       println("            else ");
1053       println("              zzAtBOL = " + zzBufferLAccess("zzMarkedPosL") + " != '\\n';");
1054       println("          }");      
1055       println("          break;"); 
1056       println("        default:"); 
1057       println("          zzAtBOL = false;");
1058       println("        }"); 
1059       println("      }"); 
1060     }
1061
1062     skel.emitNext();
1063     
1064     if (scanner.bolUsed) {
1065       println("      if (zzAtBOL)");
1066       println("        zzState = ZZ_LEXSTATE[zzLexicalState+1];");
1067       println("      else");    
1068       println("        zzState = ZZ_LEXSTATE[zzLexicalState];");
1069       println();
1070     }
1071     else {
1072       println("      zzState = ZZ_LEXSTATE[zzLexicalState];");
1073       println();
1074     }
1075
1076     skel.emitNext();
1077   }
1078
1079   
1080   private void emitGetRowMapNext() {
1081     println("          int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ];");
1082     println("          if (zzNext == "+DFA.NO_TARGET+") break zzForAction;");
1083     println("          zzState = zzNext;");
1084     println();
1085
1086     println("          int zzAttributes = zzAttrL[zzState];");
1087
1088     println("          if ( (zzAttributes & "+FINAL+") == "+FINAL+" ) {");
1089
1090     skel.emitNext();
1091     
1092     println("            if ( (zzAttributes & "+NOLOOK+") == "+NOLOOK+" ) break zzForAction;");
1093
1094     skel.emitNext();    
1095   }  
1096
1097   private void emitTransitionTable() {
1098     transformTransitionTable();
1099     
1100     println("          zzInput = zzCMapL[zzInput];");
1101     println();
1102
1103     println("          boolean zzIsFinal = false;");
1104     println("          boolean zzNoLookAhead = false;");
1105     println();
1106     
1107     println("          zzForNext: { switch (zzState) {");
1108
1109     for (int state = 0; state < dfa.numStates; state++)
1110       if (isTransition[state]) emitState(state);
1111
1112     println("            default:");
1113     println("              // if this is ever reached, there is a serious bug in JFlex");
1114     println("              zzScanError(ZZ_UNKNOWN_ERROR);");
1115     println("              break;");
1116     println("          } }");
1117     println();
1118     
1119     println("          if ( zzIsFinal ) {");
1120     
1121     skel.emitNext();
1122     
1123     println("            if ( zzNoLookAhead ) break zzForAction;");
1124
1125     skel.emitNext();    
1126   }
1127
1128
1129   /**
1130    * Escapes all " ' \ tabs and newlines
1131    */
1132   private String escapify(String s) {
1133     StringBuffer result = new StringBuffer(s.length()*2);
1134     
1135     for (int i = 0; i < s.length(); i++) {
1136       char c = s.charAt(i);
1137       switch (c) {
1138       case '\'': result.append("\\\'"); break;
1139       case '\"': result.append("\\\""); break;
1140       case '\\': result.append("\\\\"); break;
1141       case '\t': result.append("\\t"); break;
1142       case '\r': if (i+1 == s.length() || s.charAt(i+1) != '\n') result.append("\"+ZZ_NL+\""); 
1143                  break;
1144       case '\n': result.append("\"+ZZ_NL+\""); break;
1145       default: result.append(c);
1146       }
1147     }
1148
1149     return result.toString();
1150   }
1151
1152   public void emitActionTable() {
1153     int lastAction = 1;    
1154     int count = 0;
1155     int value = 0;
1156
1157     println("  /** ");
1158     println("   * Translates DFA states to action switch labels.");
1159     println("   */");
1160     CountEmitter e = new CountEmitter("Action");    
1161     e.emitInit();
1162
1163     for (int i = 0; i < dfa.numStates; i++) {
1164       int newVal = 0; 
1165       if ( dfa.isFinal[i] ) {
1166         Action action = dfa.action[i];
1167         if (action.isEmittable()) {
1168           Integer stored = (Integer) actionTable.get(action);
1169           if ( stored == null ) { 
1170             stored = new Integer(lastAction++);
1171             actionTable.put(action, stored);
1172           }
1173           newVal = stored.intValue();
1174         }
1175       }
1176       
1177       if (value == newVal) {
1178         count++;
1179       }
1180       else {
1181         if (count > 0) e.emit(count,value);
1182         count = 1;
1183         value = newVal;        
1184       }
1185     }
1186     
1187     if (count > 0) e.emit(count,value);
1188
1189     e.emitUnpack();    
1190     println(e.toString());
1191   }
1192
1193   private void emitActions() {
1194     println("      switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) {");
1195
1196     int i = actionTable.size()+1;  
1197     Enumeration actions = actionTable.keys();
1198     while ( actions.hasMoreElements() ) {
1199       Action action = (Action) actions.nextElement();
1200       int label = ((Integer) actionTable.get(action)).intValue();
1201
1202       println("        case "+label+": "); 
1203       
1204       if (action.lookAhead() == Action.FIXED_BASE) {
1205         println("          // lookahead expression with fixed base length");
1206         println("          zzMarkedPos = zzStartRead + "+action.getLookLength()+";");        
1207       }
1208       
1209       if (action.lookAhead() == Action.FIXED_LOOK || 
1210           action.lookAhead() == Action.FINITE_CHOICE) {
1211         println("          // lookahead expression with fixed lookahead length");
1212         println("          yypushback("+action.getLookLength()+");");        
1213       }
1214       
1215       if (action.lookAhead() == Action.GENERAL_LOOK) {
1216         println("          // general lookahead, find correct zzMarkedPos");
1217         println("          { int zzFState = "+dfa.entryState[action.getEntryState()]+";");
1218         println("            int zzFPos = zzStartRead;");
1219         println("            if (zzFin.length <= " + zzBufferLLength() + ") { zzFin = new boolean[" + zzBufferLLength() + "+1]; }");
1220         println("            boolean zzFinL[] = zzFin;");
1221         println("            while (zzFState != -1 && zzFPos < zzMarkedPos) {");
1222         println("              if ((zzAttrL[zzFState] & 1) == 1) { zzFinL[zzFPos] = true; } ");
1223         println("              zzInput = " + zzBufferLAccess("zzFPos++") + ";");
1224         println("              zzFState = zzTransL[ zzRowMapL[zzFState] + zzCMapL[zzInput] ];");
1225         println("            }");
1226         println("            if (zzFState != -1 && (zzAttrL[zzFState] & 1) == 1) { zzFinL[zzFPos] = true; } ");
1227         println();                
1228         println("            zzFState = "+dfa.entryState[action.getEntryState()+1]+";");
1229         println("            zzFPos = zzMarkedPos;");
1230         println("            while (!zzFinL[zzFPos] || (zzAttrL[zzFState] & 1) != 1) {");
1231         println("              zzInput = " + zzBufferLAccess("--zzFPos") + ";");
1232         println("              zzFState = zzTransL[ zzRowMapL[zzFState] + zzCMapL[zzInput] ];");
1233         println("            };");
1234         println("            zzMarkedPos = zzFPos;");
1235         println("          }");
1236       }
1237       
1238       if ( scanner.debugOption ) {
1239         print("          System.out.println(");
1240         if ( scanner.lineCount )
1241           print("\"line: \"+(yyline+1)+\" \"+");
1242         if ( scanner.columnCount )
1243           print("\"col: \"+(yycolumn+1)+\" \"+");
1244         println("\"match: --\"+yytext()+\"--\");");        
1245         print("          System.out.println(\"action ["+action.priority+"] { ");
1246         print(escapify(action.content));
1247         println(" }\");");
1248       }
1249       
1250       println("          { "+action.content);
1251       println("          }");
1252       println("        case "+(i++)+": break;"); 
1253     }
1254   }
1255
1256   private void emitEOFVal() {
1257     EOFActions eofActions = parser.getEOFActions();
1258
1259     if ( scanner.eofCode != null ) 
1260       println("            zzDoEOF();");
1261       
1262     if ( eofActions.numActions() > 0 ) {
1263       println("            switch (zzLexicalState) {");
1264       
1265       Enumeration stateNames = scanner.states.names();
1266
1267       // record lex states already emitted:
1268       Hashtable used = new Hashtable();
1269
1270       // pick a start value for break case labels. 
1271       // must be larger than any value of a lex state:
1272       int last = dfa.numStates;
1273       
1274       while ( stateNames.hasMoreElements() ) {
1275         String name = (String) stateNames.nextElement();
1276         int num = scanner.states.getNumber(name).intValue();
1277         Action action = eofActions.getAction(num);
1278
1279         if (action != null) {
1280           println("            case "+name+": {");
1281           if ( scanner.debugOption ) {
1282             print("              System.out.println(");
1283             if ( scanner.lineCount )
1284               print("\"line: \"+(yyline+1)+\" \"+");
1285             if ( scanner.columnCount )
1286               print("\"col: \"+(yycolumn+1)+\" \"+");
1287             println("\"match: <<EOF>>\");");        
1288             print("              System.out.println(\"action ["+action.priority+"] { ");
1289             print(escapify(action.content));
1290             println(" }\");");
1291           }
1292           println("              "+action.content);
1293           println("            }");
1294           println("            case "+(++last)+": break;");
1295         }
1296       }
1297       
1298       println("            default:");
1299     }
1300
1301     Action defaultAction = eofActions.getDefault();
1302
1303     if (defaultAction != null) {
1304       println("              {");
1305       if ( scanner.debugOption ) {
1306         print("                System.out.println(");
1307         if ( scanner.lineCount )
1308           print("\"line: \"+(yyline+1)+\" \"+");
1309         if ( scanner.columnCount )
1310           print("\"col: \"+(yycolumn+1)+\" \"+");
1311         println("\"match: <<EOF>>\");");        
1312         print("                System.out.println(\"action ["+defaultAction.priority+"] { ");
1313         print(escapify(defaultAction.content));
1314         println(" }\");");
1315       }
1316       println("                " + defaultAction.content);
1317       println("              }");
1318     }
1319     else if ( scanner.eofVal != null ) 
1320       println("              { " + scanner.eofVal + " }");
1321     else if ( scanner.isInteger ) {
1322       if ( scanner.tokenType != null ) {
1323         Out.error(ErrorMessages.INT_AND_TYPE);
1324         throw new GeneratorException();
1325       }
1326       println("            return YYEOF;");
1327     }
1328     else
1329       println("            return null;");
1330
1331     if (eofActions.numActions() > 0)
1332       println("            }");
1333   }
1334   
1335   private void emitState(int state) {
1336     
1337     println("            case "+state+":");
1338     println("              switch (zzInput) {");
1339    
1340     int defaultTransition = getDefaultTransition(state);
1341     
1342     for (int next = 0; next < dfa.numStates; next++) {
1343             
1344       if ( next != defaultTransition && table[state][next] != null ) {
1345         emitTransition(state, next);
1346       }
1347     }
1348     
1349     if ( defaultTransition != DFA.NO_TARGET && noTarget[state] != null ) {
1350       emitTransition(state, DFA.NO_TARGET);
1351     }
1352     
1353     emitDefaultTransition(state, defaultTransition);
1354     
1355     println("              }");
1356     println("");
1357   }
1358   
1359   private void emitTransition(int state, int nextState) {
1360
1361     CharSetEnumerator chars;
1362     
1363     if (nextState != DFA.NO_TARGET) 
1364       chars = table[state][nextState].characters();
1365     else 
1366       chars = noTarget[state].characters();
1367   
1368     print("                case ");
1369     print(chars.nextElement());
1370     print(": ");
1371     
1372     while ( chars.hasMoreElements() ) {
1373       println();
1374       print("                case ");
1375       print(chars.nextElement());
1376       print(": ");
1377     } 
1378     
1379     if ( nextState != DFA.NO_TARGET ) {
1380       if ( dfa.isFinal[nextState] )
1381         print("zzIsFinal = true; ");
1382         
1383       if ( !isTransition[nextState] )
1384         print("zzNoLookAhead = true; ");
1385         
1386       if ( nextState == state ) 
1387         println("break zzForNext;");
1388       else
1389         println("zzState = "+nextState+"; break zzForNext;");
1390     }
1391     else
1392       println("break zzForAction;");
1393   }
1394   
1395   private void emitDefaultTransition(int state, int nextState) {
1396     print("                default: ");
1397     
1398     if ( nextState != DFA.NO_TARGET ) {
1399       if ( dfa.isFinal[nextState] )
1400         print("zzIsFinal = true; ");
1401         
1402       if ( !isTransition[nextState] )
1403         print("zzNoLookAhead = true; ");
1404         
1405       if ( nextState == state ) 
1406         println("break zzForNext;");
1407       else
1408         println("zzState = "+nextState+"; break zzForNext;");
1409     }
1410     else
1411       println( "break zzForAction;" );
1412   }
1413   
1414   private int getDefaultTransition(int state) {
1415     int max = 0;
1416     
1417     for (int i = 0; i < dfa.numStates; i++) {
1418       if ( table[state][max] == null )
1419         max = i;
1420       else
1421       if ( table[state][i] != null && table[state][max].size() < table[state][i].size() )
1422         max = i;
1423     }
1424     
1425     if ( table[state][max] == null ) return DFA.NO_TARGET;
1426     if ( noTarget[state] == null ) return max;
1427     
1428     if ( table[state][max].size() < noTarget[state].size() ) 
1429       max = DFA.NO_TARGET;
1430     
1431     return max;
1432   }
1433
1434   // for switch statement:
1435   private void transformTransitionTable() {
1436     
1437     int numInput = parser.getCharClasses().getNumClasses()+1;
1438
1439     int i;    
1440     char j;
1441     
1442     table = new CharSet[dfa.numStates][dfa.numStates];
1443     noTarget = new CharSet[dfa.numStates];
1444     
1445     for (i = 0; i < dfa.numStates;  i++) 
1446       for (j = 0; j < dfa.numInput; j++) {
1447
1448         int nextState = dfa.table[i][j];
1449         
1450         if ( nextState == DFA.NO_TARGET ) {
1451           if ( noTarget[i] == null ) 
1452             noTarget[i] = new CharSet(numInput, colMap[j]);
1453           else
1454             noTarget[i].add(colMap[j]);
1455         }
1456         else {
1457           if ( table[i][nextState] == null ) 
1458             table[i][nextState] = new CharSet(numInput, colMap[j]);
1459           else
1460             table[i][nextState].add(colMap[j]);
1461         }
1462       }
1463   }
1464
1465   private void findActionStates() {
1466     isTransition = new boolean [dfa.numStates];
1467     
1468     for (int i = 0; i < dfa.numStates;  i++) {
1469       char j = 0;
1470       while ( !isTransition[i] && j < dfa.numInput )
1471         isTransition[i] = dfa.table[i][j++] != DFA.NO_TARGET;
1472     }
1473   }
1474
1475   
1476   private void reduceColumns() {
1477     colMap = new int [dfa.numInput];
1478     colKilled = new boolean [dfa.numInput];
1479
1480     int i,j,k;
1481     int translate = 0;
1482     boolean equal;
1483
1484     numCols = dfa.numInput;
1485
1486     for (i = 0; i < dfa.numInput; i++) {
1487       
1488       colMap[i] = i-translate;
1489       
1490       for (j = 0; j < i; j++) {
1491         
1492         // test for equality:
1493         k = -1;
1494         equal = true;        
1495         while (equal && ++k < dfa.numStates) 
1496           equal = dfa.table[k][i] == dfa.table[k][j];
1497         
1498         if (equal) {
1499           translate++;
1500           colMap[i] = colMap[j];
1501           colKilled[i] = true;
1502           numCols--;
1503           break;
1504         } // if
1505       } // for j
1506     } // for i
1507   }
1508   
1509   private void reduceRows() {
1510     rowMap = new int [dfa.numStates];
1511     rowKilled = new boolean [dfa.numStates];
1512     
1513     int i,j,k;
1514     int translate = 0;
1515     boolean equal;
1516
1517     numRows = dfa.numStates;
1518
1519     // i is the state to add to the new table
1520     for (i = 0; i < dfa.numStates; i++) {
1521       
1522       rowMap[i] = i-translate;
1523       
1524       // check if state i can be removed (i.e. already
1525       // exists in entries 0..i-1)
1526       for (j = 0; j < i; j++) {
1527         
1528         // test for equality:
1529         k = -1;
1530         equal = true;
1531         while (equal && ++k < dfa.numInput) 
1532           equal = dfa.table[i][k] == dfa.table[j][k];
1533         
1534         if (equal) {
1535           translate++;
1536           rowMap[i] = rowMap[j];
1537           rowKilled[i] = true;
1538           numRows--;
1539           break;
1540         } // if
1541       } // for j
1542     } // for i
1543     
1544   } 
1545
1546
1547   /**
1548    * Set up EOF code section according to scanner.eofcode 
1549    */
1550   private void setupEOFCode() {
1551     if (scanner.eofclose) {
1552       scanner.eofCode = LexScan.conc(scanner.eofCode, "  yyclose();");
1553       scanner.eofThrow = LexScan.concExc(scanner.eofThrow, "java.io.IOException");
1554     }    
1555   } 
1556
1557
1558   /**
1559    * Main Emitter method.  
1560    */
1561   public void emit() {    
1562
1563     setupEOFCode();
1564
1565     if (scanner.functionName == null) 
1566       scanner.functionName = "yylex";
1567
1568     reduceColumns();
1569     findActionStates();
1570
1571     emitHeader();
1572     emitUserCode();
1573     emitClassName();
1574     
1575     skel.emitNext();
1576     
1577     println("  private static final int ZZ_BUFFERSIZE = "+scanner.bufferSize+";");
1578
1579     if (scanner.debugOption) {
1580       println("  private static final String ZZ_NL = System.getProperty(\"line.separator\");");
1581     }
1582
1583     skel.emitNext();
1584
1585     emitLexicalStates();
1586    
1587     emitCharMapArray();
1588     
1589     emitActionTable();
1590     
1591     if (scanner.useRowMap) {
1592      reduceRows();
1593     
1594       emitRowMapArray();
1595
1596       if (scanner.packed)
1597         emitDynamicInit();
1598       else
1599         emitZZTrans();
1600     }
1601     
1602     skel.emitNext();
1603     
1604     if (scanner.useRowMap) 
1605       emitAttributes();    
1606     
1607     skel.emitNext();
1608     
1609     emitLookBuffer();
1610     
1611     emitClassCode();
1612     
1613     skel.emitNext();
1614     
1615     emitConstructorDecl();
1616         
1617     emitCharMapInitFunction();
1618
1619     skel.emitNext();
1620     
1621     emitScanError();
1622
1623     skel.emitNext();        
1624
1625     emitDoEOF();
1626     
1627     skel.emitNext();
1628     
1629     emitLexFunctHeader();
1630     
1631     emitNextInput();
1632
1633     if (scanner.useRowMap)
1634       emitGetRowMapNext();
1635     else
1636       emitTransitionTable();
1637         
1638     skel.emitNext();
1639
1640     emitActions();
1641         
1642     skel.emitNext();
1643
1644     emitEOFVal();
1645     
1646     skel.emitNext();
1647     
1648     emitNoMatch();
1649
1650     skel.emitNext();
1651     
1652     emitMain();
1653     
1654     skel.emitNext();
1655
1656     out.close();
1657   }
1658
1659 }