📄 grammatica.java
字号:
/* * Grammatica.java * * This work is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation; either version 2 of the License, * or (at your option) any later version. * * This work 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 * * As a special exception, the copyright holders of this library give * you permission to link this library with independent modules to * produce an executable, regardless of the license terms of these * independent modules, and to copy and distribute the resulting * executable under terms of your choice, provided that you also meet, * for each linked independent module, the terms and conditions of the * license of that module. An independent module is a module which is * not derived from or based on this library. If you modify this * library, you may extend this exception to your version of the * library, but you are not obligated to do so. If you do not wish to * do so, delete this exception statement from your version. * * Copyright (c) 2003 Per Cederberg. All rights reserved. */package net.percederberg.grammatica;import java.io.BufferedReader;import java.io.File;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;import net.percederberg.grammatica.output.CSharpParserGenerator;import net.percederberg.grammatica.output.JavaParserGenerator;import net.percederberg.grammatica.parser.Analyzer;import net.percederberg.grammatica.parser.Node;import net.percederberg.grammatica.parser.ParseException;import net.percederberg.grammatica.parser.Parser;import net.percederberg.grammatica.parser.ParserCreationException;import net.percederberg.grammatica.parser.ParserLogException;import net.percederberg.grammatica.parser.Token;import net.percederberg.grammatica.parser.Tokenizer;/** * The main application. This class provides the command-line * interface for invoking the application. See separate documentation * for information on usage and command-line parameters. * * @author Per Cederberg, <per at percederberg dot net> * @version 1.2 */public class Grammatica extends Object { /** * The command-line help output. */ private static final String COMMAND_HELP = "Generates source code for a C# or Java parser from a grammar\n" + "file. This program comes with ABSOLUTELY NO WARRANTY; for\n" + "details see the LICENSE.txt file.\n" + "\n" + "Syntax: Grammatica <grammarfile> <action> [<options>]\n" + "\n" + "Actions:\n" + " --debug\n" + " Debugs the grammar by validating it and printing the\n" + " internal representation.\n" + " --tokenize <file>\n" + " Debugs the grammar by using it to tokenize the specified\n" + " file. No code has to be generated for this.\n" + " --parse <file>\n" + " Debugs the grammar by using it to parse the specified\n" + " file. No code has to be generated for this.\n" + " --profile <file>\n" + " Profiles the grammar by using it to parse the specified\n" + " file and printing a statistic summary.\n" + " --csoutput <dir>\n" + " Creates a C# parser for the grammar (in source code).\n" + " The specified directory will be used as output directory\n" + " for the source code files.\n" + " --javaoutput <dir>\n" + " Creates a Java parser for the grammar (in source code).\n" + " The specified directory will be used as the base output\n" + " directory for the source code files.\n" + "\n" + "C# Output Options:\n" + " --csnamespace <package>\n" + " Sets the C# namespace to use in generated source code\n" + " files. By default no namespace declaration is included.\n" + " --csclassname <name>\n" + " Sets the C# class name prefix to use in generated source\n" + " code files. By default the grammar file name is used.\n" + " --cspublic\n" + " Sets public access for all C# types generated. By default\n" + " type access is internal.\n" + "\n" + "Java Output Options:\n" + " --javapackage <package>\n" + " Sets the Java package to use in generated source code\n" + " files. By default no package declaration is included.\n" + " --javaclassname <name>\n" + " Sets the Java class name prefix to use in generated source\n" + " code files. By default the grammar file name is used.\n" + " --javapublic\n" + " Sets public access for all Java types. By default type\n" + " access is package local."; /** * The internal error message. */ private static final String INTERNAL_ERROR = "INTERNAL ERROR: An internal error in Grammatica has been found.\n" + " Please report this error to the maintainers (see the web\n" + " site for instructions). Be sure to include the Grammatica\n" + " version number, as well as the information below:\n"; /** * The application entry point. * * @param args the command-line parameters */ public static void main(String[] args) { Grammar grammar = null; // Parse command-line arguments if (args.length == 1 && args[0].equals("--help")) { printHelp(null); System.exit(1); } if (args.length < 2) { printHelp("Missing grammar file and/or action"); System.exit(1); } // Read grammar file try { grammar = new Grammar(new File(args[0])); } catch (FileNotFoundException e) { printError(args[0], e); System.exit(1); } catch (ParserLogException e) { printError(args[0], e); System.exit(1); } catch (GrammarException e) { printError(e); System.exit(1); } catch (SecurityException e) { throw e; } catch (RuntimeException e) { printInternalError(e); System.exit(2); } // Check action parameter try { if (args[1].equals("--debug")) { debug(grammar); } else if (args.length < 3) { printHelp("missing action file parameter"); System.exit(1); } else if (args[1].equals("--tokenize")) { tokenize(grammar, new File(args[2])); } else if (args[1].equals("--parse")) { parse(grammar, new File(args[2])); } else if (args[1].equals("--profile")) { profile(grammar, new File(args[2])); } else if (args[1].equals("--javaoutput")) { writeJavaCode(args, grammar); } else if (args[1].equals("--csoutput")) { writeCSharpCode(args, grammar); } else { printHelp("unrecognized option: " + args[1]); System.exit(1); } } catch (SecurityException e) { throw e; } catch (RuntimeException e) { printInternalError(e); System.exit(2); } } /** * Prints command-line help information. * * @param error an optional error message, or null */ private static void printHelp(String error) { System.err.println(COMMAND_HELP); System.err.println(); if (error != null) { System.err.print("Error: "); System.err.println(error); System.err.println(); } } /** * Prints a general error message. * * @param e the detailed exception */ private static void printError(Exception e) { StringBuffer buffer = new StringBuffer(); buffer.append("Error: "); buffer.append(e.getMessage()); System.err.println(buffer.toString()); } /** * Prints a file not found error message. * * @param file the file name not found * @param e the detailed exception */ private static void printError(String file, FileNotFoundException e) { StringBuffer buffer = new StringBuffer(); buffer.append("Error: couldn't open file:"); buffer.append("\n "); buffer.append(file); System.err.println(buffer.toString()); } /** * Prints a parse error message. * * @param file the input file name * @param e the detailed exception */ private static void printError(String file, ParseException e) { StringBuffer buffer = new StringBuffer(); String line; // Handle normal parse error buffer.append("Error: in "); buffer.append(file); if (e.getLine() > 0) { buffer.append(": line "); buffer.append(e.getLine()); } buffer.append(":\n"); buffer.append(linebreakString(e.getErrorMessage(), " ", 70)); line = readLines(file, e.getLine(), e.getLine()); if (line != null) { buffer.append("\n\n"); buffer.append(line); for (int i = 1; i < e.getColumn(); i++) { if (line.charAt(i - 1) == '\t') { buffer.append("\t"); } else { buffer.append(" "); } } buffer.append("^"); } System.err.println(buffer.toString()); } /** * Prints a list of parse error messages. * * @param file the input file name * @param e the parser log exception */ private static void printError(String file, ParserLogException e) { for (int i = 0; i < e.getErrorCount(); i++) { printError(file, e.getError(i)); } } /** * Prints a grammar error message. * * @param e the detailed exception */ private static void printError(GrammarException e) { StringBuffer buffer = new StringBuffer(); String lines; buffer.append("Error: in "); buffer.append(e.getFile()); if (e.getStartLine() > 0) { if (e.getStartLine() == e.getEndLine()) { buffer.append(": line "); buffer.append(e.getStartLine()); } else { buffer.append(": lines "); buffer.append(e.getStartLine()); buffer.append("-"); buffer.append(e.getEndLine()); } } buffer.append(":\n"); buffer.append(linebreakString(e.getErrorMessage(), " ", 70)); lines = readLines(e.getFile(), e.getStartLine(), e.getEndLine()); if (lines != null) { buffer.append("\n\n"); buffer.append(lines); } System.err.println(buffer.toString()); } /** * Prints an internal error message. This type of error should * only be reported when run-time exceptions occur, such as null * pointer and the likes. All these error should be reported as * bugs to the program maintainers. * * @param e the exception to be reported
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -