1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
3 * Copyright (C) 1998-2004 Gerwin Klein <lsf@jflex.de> *
4 * All rights reserved. *
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. *
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. *
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 *
19 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
23 import JFlex
.gui
.MainFrame
;
26 import java
.io
.FileNotFoundException
;
27 import java
.io
.FileReader
;
28 import java
.io
.IOException
;
29 import java
.util
.Vector
;
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 $
43 final public static String version
= "1.4.1"; //$NON-NLS-1$
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
) {
55 Timer totalTime
= new Timer();
56 Timer time
= new Timer();
58 LexScan scanner
= null;
59 LexParse parser
= null;
60 FileReader inputReader
= null;
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();
77 NFA nfa
= (NFA
) parser
.parse().value
;
81 if (Options
.dump
) Out
.dump(ErrorMessages
.get(ErrorMessages
.NFA_IS
)+
85 nfa
.writeDot(Emitter
.normalize("nfa.dot", null)); //$NON-NLS-1$
87 Out
.println(ErrorMessages
.NFA_STATES
, nfa
.numStates
);
90 DFA dfa
= nfa
.getDFA();
92 Out
.time(ErrorMessages
.DFA_TOOK
, time
);
94 dfa
.checkActions(scanner
, parser
);
98 if (Options
.dump
) Out
.dump(ErrorMessages
.get(ErrorMessages
.DFA_IS
)+
102 dfa
.writeDot(Emitter
.normalize("dfa-big.dot", null)); //$NON-NLS-1$
108 Out
.time(ErrorMessages
.MIN_TOOK
, time
);
111 Out
.dump(ErrorMessages
.get(ErrorMessages
.MIN_DFA_IS
)+
115 dfa
.writeDot(Emitter
.normalize("dfa-min.dot", null)); //$NON-NLS-1$
119 Emitter e
= new Emitter(inputFile
, parser
, dfa
);
124 Out
.time(ErrorMessages
.WRITE_TOOK
, time
);
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
) {
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
]);
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
]));
180 if ( argv
[i
].equals("-jlex") || argv
[i
].equals("--jlex") ) { //$NON-NLS-1$ //$NON-NLS-2$
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;
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;
197 if ( argv
[i
].equals("--dump") || argv
[i
].equals("-dump") ) { //$NON-NLS-1$ //$NON-NLS-2$
202 if ( argv
[i
].equals("--time") || argv
[i
].equals("-time") ) { //$NON-NLS-1$ //$NON-NLS-2$
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$
217 if ( argv
[i
].equals("--help") || argv
[i
].equals("-h") || argv
[i
].equals("/h") ) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
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;
232 if ( argv
[i
].equals("--pack") || argv
[i
].equals("-pack") ) { //$NON-NLS-1$ //$NON-NLS-2$
233 Options
.gen_method
= Options
.PACK
;
237 if ( argv
[i
].equals("--table") || argv
[i
].equals("-table") ) { //$NON-NLS-1$ //$NON-NLS-2$
238 Options
.gen_method
= Options
.TABLE
;
242 if ( argv
[i
].equals("--switch") || argv
[i
].equals("-switch") ) { //$NON-NLS-1$ //$NON-NLS-2$
243 Options
.gen_method
= Options
.SWITCH
;
247 if ( argv
[i
].equals("--nobak") || argv
[i
].equals("-nobak") ) { //$NON-NLS-1$ //$NON-NLS-2$
248 Options
.no_backup
= true;
252 if ( argv
[i
].equals("--charat") || argv
[i
].equals("-charat") ) { //$NON-NLS-1$ //$NON-NLS-2$
253 Options
.char_at
= true;
257 if ( argv
[i
].equals("--sliceandcharat") || argv
[i
].equals("-sliceandcharat") ) { //$NON-NLS-1$ //$NON-NLS-2$
258 Options
.sliceAndCharAt
= true;
262 if ( argv
[i
].startsWith("-") ) { //$NON-NLS-1$
263 Out
.error(ErrorMessages
.UNKNOWN_COMMANDLINE
, argv
[i
]);
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() )
273 Out
.error("Sorry, couldn't open \""+f
+"\""); //$NON-NLS-2$
274 throw new GeneratorException();
282 public static void printUsage() {
283 Out
.println(""); //$NON-NLS-1$
284 Out
.println("Usage: jflex <options> <input-files>");
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");
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
));
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
330 * @param argv the commandline.
332 public static void main(String argv
[]) {
336 catch (GeneratorException e
) {
340 catch (SilentExit e
) {