move JFlex to CE source
[fedora-idea.git] / tools / lexer / jflex-1.4 / src / JFlex / Main.java
blob20227c03cbdfc466ebb23890820c19b1baf6be08
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * JFlex 1.4.1 *
3 * Copyright (C) 1998-2004 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 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
21 package JFlex;
23 import JFlex.gui.MainFrame;
25 import java.io.File;
26 import java.io.FileNotFoundException;
27 import java.io.FileReader;
28 import java.io.IOException;
29 import java.util.Vector;
32 /**
33 * This is the main class of JFlex controlling the scanner generation process.
34 * It is responsible for parsing the commandline, getting input files,
35 * starting up the GUI if necessary, etc.
37 * @author Gerwin Klein
38 * @version JFlex 1.4.1, $Revision: 2.20 $, $Date: 2004/11/06 23:03:32 $
40 public class Main {
42 /** JFlex version */
43 final public static String version = "1.4.1"; //$NON-NLS-1$
45 /**
46 * Generates a scanner for the specified input file.
48 * @param inputFile a file containing a lexical specification
49 * to generate a scanner for.
51 public static void generate(File inputFile) {
53 Out.resetCounters();
55 Timer totalTime = new Timer();
56 Timer time = new Timer();
58 LexScan scanner = null;
59 LexParse parser = null;
60 FileReader inputReader = null;
62 totalTime.start();
64 try {
65 Out.println(ErrorMessages.READING, inputFile.toString());
66 inputReader = new FileReader(inputFile);
67 scanner = new LexScan(inputReader);
68 scanner.setFile(inputFile);
69 parser = new LexParse(scanner);
71 catch (FileNotFoundException e) {
72 Out.error(ErrorMessages.CANNOT_OPEN, inputFile.toString());
73 throw new GeneratorException();
76 try {
77 NFA nfa = (NFA) parser.parse().value;
79 Out.checkErrors();
81 if (Options.dump) Out.dump(ErrorMessages.get(ErrorMessages.NFA_IS)+
82 Out.NL+nfa+Out.NL);
84 if (Options.dot)
85 nfa.writeDot(Emitter.normalize("nfa.dot", null)); //$NON-NLS-1$
87 Out.println(ErrorMessages.NFA_STATES, nfa.numStates);
89 time.start();
90 DFA dfa = nfa.getDFA();
91 time.stop();
92 Out.time(ErrorMessages.DFA_TOOK, time);
94 dfa.checkActions(scanner, parser);
96 nfa = null;
98 if (Options.dump) Out.dump(ErrorMessages.get(ErrorMessages.DFA_IS)+
99 Out.NL+dfa+Out.NL);
101 if (Options.dot)
102 dfa.writeDot(Emitter.normalize("dfa-big.dot", null)); //$NON-NLS-1$
104 time.start();
105 dfa.minimize();
106 time.stop();
108 Out.time(ErrorMessages.MIN_TOOK, time);
110 if (Options.dump)
111 Out.dump(ErrorMessages.get(ErrorMessages.MIN_DFA_IS)+
112 Out.NL+dfa);
114 if (Options.dot)
115 dfa.writeDot(Emitter.normalize("dfa-min.dot", null)); //$NON-NLS-1$
117 time.start();
119 Emitter e = new Emitter(inputFile, parser, dfa);
120 e.emit();
122 time.stop();
124 Out.time(ErrorMessages.WRITE_TOOK, time);
126 totalTime.stop();
128 Out.time(ErrorMessages.TOTAL_TIME, totalTime);
130 catch (ScannerException e) {
131 Out.error(e.file, e.message, e.line, e.column);
132 throw new GeneratorException();
134 catch (MacroException e) {
135 Out.error(e.getMessage());
136 throw new GeneratorException();
138 catch (IOException e) {
139 Out.error(ErrorMessages.IO_ERROR, e.toString());
140 throw new GeneratorException();
142 catch (OutOfMemoryError e) {
143 Out.error(ErrorMessages.OUT_OF_MEMORY);
144 throw new GeneratorException();
146 catch (GeneratorException e) {
147 throw new GeneratorException();
149 catch (Exception e) {
150 e.printStackTrace();
151 throw new GeneratorException();
156 public static Vector parseOptions(String argv[]) throws SilentExit {
157 Vector files = new Vector();
159 for (int i = 0; i < argv.length; i++) {
161 if ( argv[i].equals("-d") || argv[i].equals("--outdir") ) { //$NON-NLS-1$ //$NON-NLS-2$
162 if ( ++i >= argv.length ) {
163 Out.error(ErrorMessages.NO_DIRECTORY);
164 throw new GeneratorException();
166 Options.setDir(argv[i]);
167 continue;
170 if ( argv[i].equals("--skel") || argv[i].equals("-skel") ) { //$NON-NLS-1$ //$NON-NLS-2$
171 if ( ++i >= argv.length ) {
172 Out.error(ErrorMessages.NO_SKEL_FILE);
173 throw new GeneratorException();
176 Options.setSkeleton(new File(argv[i]));
177 continue;
180 if ( argv[i].equals("-jlex") || argv[i].equals("--jlex") ) { //$NON-NLS-1$ //$NON-NLS-2$
181 Options.jlex = true;
182 continue;
185 if ( argv[i].equals("-v") || argv[i].equals("--verbose") || argv[i].equals("-verbose") ) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
186 Options.verbose = true;
187 Options.progress = true;
188 continue;
191 if ( argv[i].equals("-q") || argv[i].equals("--quiet") || argv[i].equals("-quiet") ) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
192 Options.verbose = false;
193 Options.progress = false;
194 continue;
197 if ( argv[i].equals("--dump") || argv[i].equals("-dump") ) { //$NON-NLS-1$ //$NON-NLS-2$
198 Options.dump = true;
199 continue;
202 if ( argv[i].equals("--time") || argv[i].equals("-time") ) { //$NON-NLS-1$ //$NON-NLS-2$
203 Options.time = true;
204 continue;
207 if ( argv[i].equals("--version") || argv[i].equals("-version") ) { //$NON-NLS-1$ //$NON-NLS-2$
208 Out.println(ErrorMessages.THIS_IS_JFLEX, version);
209 throw new SilentExit();
212 if ( argv[i].equals("--dot") || argv[i].equals("-dot") ) { //$NON-NLS-1$ //$NON-NLS-2$
213 Options.dot = true;
214 continue;
217 if ( argv[i].equals("--help") || argv[i].equals("-h") || argv[i].equals("/h") ) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
218 printUsage();
219 throw new SilentExit();
222 if ( argv[i].equals("--info") || argv[i].equals("-info") ) { //$NON-NLS-1$ //$NON-NLS-2$
223 Out.printSystemInfo();
224 throw new SilentExit();
227 if ( argv[i].equals("--nomin") || argv[i].equals("-nomin") ) { //$NON-NLS-1$ //$NON-NLS-2$
228 Options.no_minimize = true;
229 continue;
232 if ( argv[i].equals("--pack") || argv[i].equals("-pack") ) { //$NON-NLS-1$ //$NON-NLS-2$
233 Options.gen_method = Options.PACK;
234 continue;
237 if ( argv[i].equals("--table") || argv[i].equals("-table") ) { //$NON-NLS-1$ //$NON-NLS-2$
238 Options.gen_method = Options.TABLE;
239 continue;
242 if ( argv[i].equals("--switch") || argv[i].equals("-switch") ) { //$NON-NLS-1$ //$NON-NLS-2$
243 Options.gen_method = Options.SWITCH;
244 continue;
247 if ( argv[i].equals("--nobak") || argv[i].equals("-nobak") ) { //$NON-NLS-1$ //$NON-NLS-2$
248 Options.no_backup = true;
249 continue;
252 if ( argv[i].equals("--charat") || argv[i].equals("-charat") ) { //$NON-NLS-1$ //$NON-NLS-2$
253 Options.char_at = true;
254 continue;
257 if ( argv[i].equals("--sliceandcharat") || argv[i].equals("-sliceandcharat") ) { //$NON-NLS-1$ //$NON-NLS-2$
258 Options.sliceAndCharAt = true;
259 continue;
262 if ( argv[i].startsWith("-") ) { //$NON-NLS-1$
263 Out.error(ErrorMessages.UNKNOWN_COMMANDLINE, argv[i]);
264 printUsage();
265 throw new SilentExit();
268 // if argv[i] is not an option, try to read it as file
269 File f = new File(argv[i]);
270 if ( f.isFile() && f.canRead() )
271 files.addElement(f);
272 else {
273 Out.error("Sorry, couldn't open \""+f+"\""); //$NON-NLS-2$
274 throw new GeneratorException();
278 return files;
282 public static void printUsage() {
283 Out.println(""); //$NON-NLS-1$
284 Out.println("Usage: jflex <options> <input-files>");
285 Out.println("");
286 Out.println("Where <options> can be one or more of");
287 Out.println("-d <directory> write generated file to <directory>");
288 Out.println("--skel <file> use external skeleton <file>");
289 Out.println("--switch");
290 Out.println("--table");
291 Out.println("--pack set default code generation method");
292 Out.println("--jlex strict JLex compatibility");
293 Out.println("--nomin skip minimization step");
294 Out.println("--nobak don't create backup files");
295 Out.println("--dump display transition tables");
296 Out.println("--dot write graphviz .dot files for the generated automata (alpha)");
297 Out.println("--verbose");
298 Out.println("-v display generation progress messages (default)");
299 Out.println("--quiet");
300 Out.println("-q display errors only");
301 Out.println("--time display generation time statistics");
302 Out.println("--version print the version number of this copy of jflex");
303 Out.println("--info print system + JDK information");
304 Out.println("--help");
305 Out.println("-h print this message");
306 Out.println("");
307 Out.println(ErrorMessages.THIS_IS_JFLEX, version);
308 Out.println("Have a nice day!");
312 public static void generate(String argv[]) throws SilentExit {
313 Vector files = parseOptions(argv);
315 if (files.size() > 0) {
316 for (int i = 0; i < files.size(); i++)
317 generate((File) files.elementAt(i));
319 else {
320 new MainFrame();
326 * Starts the generation process with the files in <code>argv</code> or
327 * pops up a window to choose a file, when <code>argv</code> doesn't have
328 * any file entries.
330 * @param argv the commandline.
332 public static void main(String argv[]) {
333 try {
334 generate(argv);
336 catch (GeneratorException e) {
337 Out.statistics();
338 System.exit(1);
340 catch (SilentExit e) {
341 System.exit(1);