📄 emitter.java
字号:
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * JFlex 1.4.2 * * Copyright (C) 1998-2008 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 JFlex 1.4.2, $Revision: 358 $, $Date: 2008-05-27 16:28:29 +1000 (Tue, 27 May 2008) $ */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 void emitNoMatch() { println(" zzScanError(ZZ_NO_MATCH);"); } private void emitNextInput() { println(" if (zzCurrentPosL < zzEndReadL)"); println(" zzInput = zzBufferL[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 = zzBufferL[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("/**");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -