📄 main.java
字号:
package java_cup;import java.util.Enumeration; import java.io.*;/** This class serves as the main driver for the JavaCup system. * It accepts user options and coordinates overall control flow. * The main flow of control includes the following activities: * <ul> * <li> Parse user supplied arguments and options. * <li> Open output files. * <li> Parse the specification from standard input. * <li> Check for unused terminals, non-terminals, and productions. * <li> Build the state machine, tables, etc. * <li> Output the generated code. * <li> Close output files. * <li> Print a summary if requested. * </ul> * * Options to the main program include: <dl> * <dt> -package name * <dd> specify package generated classes go in [default none] * <dt> -parser name * <dd> specify parser class name [default "parser"] * <dt> -symbols name * <dd> specify name for symbol constant class [default "sym"] * <dt> -interface * <dd> emit symbol constant <i>interface</i>, rather than class * <dt> -nonterms * <dd> put non terminals in symbol constant class * <dt> -expect # * <dd> number of conflicts expected/allowed [default 0] * <dt> -compact_red * <dd> compact tables by defaulting to most frequent reduce * <dt> -nowarn * <dd> don't warn about useless productions, etc. * <dt> -nosummary * <dd> don't print the usual summary of parse states, etc. * <dt> -progress * <dd> print messages to indicate progress of the system * <dt> -time * <dd> print time usage summary * <dt> -dump_grammar * <dd> produce a dump of the symbols and grammar * <dt> -dump_states * <dd> produce a dump of parse state machine * <dt> -dump_tables * <dd> produce a dump of the parse tables * <dt> -dump * <dd> produce a dump of all of the above * <dt> -debug * <dd> turn on debugging messages within JavaCup * <dt> -nopositions * <dd> don't generate the positions code * </dl> * * @version last updated: 7/3/96 * @author Frank Flannery */public class Main { /*-----------------------------------------------------------*/ /*--- Constructor(s) ----------------------------------------*/ /*-----------------------------------------------------------*/ /** Only constructor is private, so we do not allocate any instances of this class. */ private Main() { } /*-------------------------*/ /* Options set by the user */ /*-------------------------*/ /** User option -- do we print progress messages. */ protected static boolean print_progress = true; /** User option -- do we produce a dump of the state machine */ protected static boolean opt_dump_states = false; /** User option -- do we produce a dump of the parse tables */ protected static boolean opt_dump_tables = false; /** User option -- do we produce a dump of the grammar */ protected static boolean opt_dump_grammar = false; /** User option -- do we show timing information as a part of the summary */ protected static boolean opt_show_timing = false; /** User option -- do we run produce extra debugging messages */ protected static boolean opt_do_debug = false; /** User option -- do we compact tables by making most common reduce the default action */ protected static boolean opt_compact_red = false; /** User option -- should we include non terminal symbol numbers in the symbol constant class. */ protected static boolean include_non_terms = false; /** User option -- do not print a summary. */ protected static boolean no_summary = false; /** User option -- number of conflicts to expect */ protected static int expect_conflicts = 0; /* frankf added this 6/18/96 */ /** User option -- should generator generate code for left/right values? */ protected static boolean lr_values = true; /** User option -- should symbols be put in a class or an interface? */ protected static boolean sym_interface = false; /*----------------------------------------------------------------------*/ /* Timing data (not all of these time intervals are mutually exclusive) */ /*----------------------------------------------------------------------*/ /** Timing data -- when did we start */ protected static long start_time = 0; /** Timing data -- when did we end preliminaries */ protected static long prelim_end = 0; /** Timing data -- when did we end parsing */ protected static long parse_end = 0; /** Timing data -- when did we end checking */ protected static long check_end = 0; /** Timing data -- when did we end dumping */ protected static long dump_end = 0; /** Timing data -- when did we end state and table building */ protected static long build_end = 0; /** Timing data -- when did we end nullability calculation */ protected static long nullability_end = 0; /** Timing data -- when did we end first set calculation */ protected static long first_end = 0; /** Timing data -- when did we end state machine construction */ protected static long machine_end = 0; /** Timing data -- when did we end table construction */ protected static long table_end = 0; /** Timing data -- when did we end checking for non-reduced productions */ protected static long reduce_check_end = 0; /** Timing data -- when did we finish emitting code */ protected static long emit_end = 0; /** Timing data -- when were we completely done */ protected static long final_time = 0; /* Additional timing information is also collected in emit */ /*-----------------------------------------------------------*/ /*--- Main Program ------------------------------------------*/ /*-----------------------------------------------------------*/ /** The main driver for the system. * @param argv an array of strings containing command line arguments. */ public static void main(String argv[]) throws internal_error, java.io.IOException, java.lang.Exception { boolean did_output = false; start_time = System.currentTimeMillis(); /* process user options and arguments */ parse_args(argv); /* frankf 6/18/96 hackish, yes, but works */ emit.set_lr_values(lr_values); /* open output files */ if (print_progress) System.err.println("Opening files..."); /* use a buffered version of standard input */ input_file = new BufferedInputStream(System.in); prelim_end = System.currentTimeMillis(); /* parse spec into internal data structures */ if (print_progress) System.err.println("Parsing specification from standard input..."); parse_grammar_spec(); parse_end = System.currentTimeMillis(); /* don't proceed unless we are error free */ if (lexer.error_count == 0) { /* check for unused bits */ if (print_progress) System.err.println("Checking specification..."); check_unused(); check_end = System.currentTimeMillis(); /* build the state machine and parse tables */ if (print_progress) System.err.println("Building parse tables..."); build_parser(); build_end = System.currentTimeMillis(); /* output the generated code, if # of conflicts permits */ if (lexer.error_count != 0) { // conflicts! don't emit code, don't dump tables. opt_dump_tables = false; } else { // everything's okay, emit parser. if (print_progress) System.err.println("Writing parser..."); open_files(); emit_parser(); did_output = true; } } /* fix up the times to make the summary easier */ emit_end = System.currentTimeMillis(); /* do requested dumps */ if (opt_dump_grammar) dump_grammar(); if (opt_dump_states) dump_machine(); if (opt_dump_tables) dump_tables(); dump_end = System.currentTimeMillis(); /* close input/output files */ if (print_progress) System.err.println("Closing files..."); close_files(); /* produce a summary if desired */ if (!no_summary) emit_summary(did_output); /* If there were errors during the run, * exit with non-zero status (makefile-friendliness). --CSA */ if (lexer.error_count != 0) System.exit(100); } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Print a "usage message" that described possible command line options, * then exit. * @param message a specific error message to preface the usage message by. */ protected static void usage(String message) { System.err.println(); System.err.println(message); System.err.println(); System.err.println("Usage: " + version.program_name + " [options]\n" +" and expects a specification file on standard input.\n" +" Legal options include:\n" +" -package name specify package generated classes go in [default none]\n" +" -parser name specify parser class name [default \"parser\"]\n" +" -symbols name specify name for symbol constant class [default \"sym\"]\n"+" -interface put symbols in an interface, rather than a class\n" +" -nonterms put non terminals in symbol constant class\n" + " -expect # number of conflicts expected/allowed [default 0]\n" + " -compact_red compact tables by defaulting to most frequent reduce\n" +" -nowarn don't warn about useless productions, etc.\n" +" -nosummary don't print the usual summary of parse states, etc.\n" +" -nopositions don't propagate the left and right token position values\n" +" -progress print messages to indicate progress of the system\n" +" -time print time usage summary\n" +" -dump_grammar produce a human readable dump of the symbols and grammar\n"+" -dump_states produce a dump of parse state machine\n"+" -dump_tables produce a dump of the parse tables\n"+" -dump produce a dump of all of the above\n" ); System.exit(1); } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Parse command line options and arguments to set various user-option * flags and variables. * @param argv the command line arguments to be parsed. */ protected static void parse_args(String argv[]) { int len = argv.length; int i; /* parse the options */ for (i=0; i<len; i++) { /* try to get the various options */ if (argv[i].equals("-package")) { /* must have an arg */ if (++i >= len || argv[i].startsWith("-") || argv[i].endsWith(".cup")) usage("-package must have a name argument"); /* record the name */ emit.package_name = argv[i]; } else if (argv[i].equals("-parser")) { /* must have an arg */ if (++i >= len || argv[i].startsWith("-") || argv[i].endsWith(".cup")) usage("-parser must have a name argument"); /* record the name */ emit.parser_class_name = argv[i]; } else if (argv[i].equals("-symbols")) { /* must have an arg */ if (++i >= len || argv[i].startsWith("-") || argv[i].endsWith(".cup")) usage("-symbols must have a name argument"); /* record the name */ emit.symbol_const_class_name = argv[i]; } else if (argv[i].equals("-nonterms")) { include_non_terms = true; } else if (argv[i].equals("-expect")) { /* must have an arg */ if (++i >= len || argv[i].startsWith("-") || argv[i].endsWith(".cup")) usage("-expect must have a name argument"); /* record the number */ try { expect_conflicts = Integer.parseInt(argv[i]); } catch (NumberFormatException e) { usage("-expect must be followed by a decimal integer"); } } else if (argv[i].equals("-compact_red")) opt_compact_red = true; else if (argv[i].equals("-nosummary")) no_summary = true; else if (argv[i].equals("-nowarn")) emit.nowarn = true; else if (argv[i].equals("-dump_states")) opt_dump_states = true; else if (argv[i].equals("-dump_tables")) opt_dump_tables = true; else if (argv[i].equals("-progress")) print_progress = true; else if (argv[i].equals("-dump_grammar")) opt_dump_grammar = true; else if (argv[i].equals("-dump")) opt_dump_states = opt_dump_tables = opt_dump_grammar = true; else if (argv[i].equals("-time")) opt_show_timing = true; else if (argv[i].equals("-debug")) opt_do_debug = true; /* frankf 6/18/96 */ else if (argv[i].equals("-nopositions")) lr_values = false; /* CSA 12/21/97 */ else if (argv[i].equals("-interface")) sym_interface = true; else { usage("Unrecognized option \"" + argv[i] + "\""); } } } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /*-------*/ /* Files */ /*-------*/ /** Input file. This is a buffered version of System.in. */ protected static BufferedInputStream input_file; /** Output file for the parser class. */ protected static PrintWriter parser_class_file; /** Output file for the symbol constant class. */ protected static PrintWriter symbol_class_file; /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Open various files used by the system. */ protected static void open_files() { File fil; String out_name; /* open each of the output files */ /* parser class */ out_name = emit.parser_class_name + ".java"; fil = new File(out_name); try { parser_class_file = new PrintWriter( new BufferedOutputStream(new FileOutputStream(fil), 4096)); } catch(Exception e) { System.err.println("Can't open \"" + out_name + "\" for output"); System.exit(3); } /* symbol constants class */ out_name = emit.symbol_const_class_name + ".java"; fil = new File(out_name); try { symbol_class_file = new PrintWriter( new BufferedOutputStream(new FileOutputStream(fil), 4096)); } catch(Exception e) { System.err.println("Can't open \"" + out_name + "\" for output"); System.exit(4); } } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Close various files used by the system. */ protected static void close_files() throws java.io.IOException { if (input_file != null) input_file.close(); if (parser_class_file != null) parser_class_file.close(); if (symbol_class_file != null) symbol_class_file.close(); } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Parse the grammar specification from standard input. This produces * sets of terminal, non-terminals, and productions which can be accessed * via static variables of the respective classes, as well as the setting * of various variables (mostly in the emit class) for small user supplied * items such as the code to scan with. */ protected static void parse_grammar_spec() throws java.lang.Exception { parser parser_obj; /* create a parser and parse with it */ parser_obj = new parser(); try { if (opt_do_debug) parser_obj.debug_parse(); else parser_obj.parse(); } catch (Exception e)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -