[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 8640]

This commit is contained in:
parrt 2011-06-15 18:36:21 -08:00
parent c186d5ad76
commit a13068c7c2
12 changed files with 1065 additions and 0 deletions

View File

@ -0,0 +1,136 @@
package org.antlr.v4;
import org.antlr.v4.tool.*;
import java.util.*;
public class Tool {
public String VERSION = "4.0-"+new Date();
public static enum OptionArgType { NONE, STRING, INT }
public static class Option {
String name;
OptionArgType argType;
Object defaultArgValue;
String description;
public Option(String name, String description) {
this(name, OptionArgType.NONE, null, description);
}
public Option(String name, OptionArgType argType, String description) {
this(name, argType, null, description);
}
public Option(String name, OptionArgType argType, Object defaultArgValue, String description) {
this.name = name;
this.argType = argType;
this.defaultArgValue = defaultArgValue;
this.description = description;
}
}
public static Option[] optionDefs = {
new Option("o", OptionArgType.STRING, ".", "specify output directory where all output is generated"),
new Option("fo", OptionArgType.STRING, "same as -o but force even files with relative paths to dir"),
new Option("lib", "specify location of .token files"),
new Option("report", "print out a report about the grammar(s) processed"),
new Option("print", "print out the grammar without actions"),
new Option("debug", "generate a parser that emits debugging events"),
new Option("profile", "generate a parser that computes profiling information"),
new Option("atn", "generate rule augmented transition networks"),
new Option("message-format", OptionArgType.STRING, "specify output style for messages"),
new Option("version", "print the version of ANTLR and exit"),
new Option("savelexer", "save temp lexer file created for combined grammars"),
new Option("dbgST", "launch StringTemplate visualizer on generated code"),
};
protected Map<String, Object> options = new HashMap<String, Object>();
protected String[] args;
public ErrorManager errMgr = new ErrorManager(this);
List<ANTLRToolListener> listeners =
Collections.synchronizedList(new ArrayList<ANTLRToolListener>());
/** Track separately so if someone adds a listener, it's the only one
* instead of it and the default stderr listener.
*/
DefaultToolListener defaultListener = new DefaultToolListener(this);
public static void main(String[] args) {
Tool antlr = new Tool(args);
antlr.help();
antlr.processGrammarsOnCommandLine();
if (antlr.errMgr.getNumErrors() > 0) {
antlr.exit(1);
}
antlr.exit(0);
// if (!exitNow) {
// antlr.processGrammarsOnCommandLine();
// if ( return_dont_exit ) return;
// }
}
public Tool() { this(null); }
public Tool(String[] args) {
this.args = args;
}
public void processGrammarsOnCommandLine() {
}
public void help() {
info("ANTLR Parser Generator Version " + new Tool().VERSION);
for (Option o : optionDefs) {
String name = o.name + (o.argType!=OptionArgType.NONE? " ___" : "");
String s = String.format(" -%-19s %s", name, o.description);
info(s);
}
}
public void addListener(ANTLRToolListener tl) {
if ( tl!=null ) listeners.add(tl);
}
public void removeListener(ANTLRToolListener tl) { listeners.remove(tl); }
public void removeListeners() { listeners.clear(); }
public List<ANTLRToolListener> getListeners() { return listeners; }
public void info(String msg) {
if ( listeners.size()==0 ) {
defaultListener.info(msg);
return;
}
for (ANTLRToolListener l : listeners) l.info(msg);
}
public void error(ANTLRMessage msg) {
if ( listeners.size()==0 ) {
defaultListener.error(msg);
return;
}
for (ANTLRToolListener l : listeners) l.error(msg);
}
public void warning(ANTLRMessage msg) {
if ( listeners.size()==0 ) {
defaultListener.warning(msg);
return;
}
for (ANTLRToolListener l : listeners) l.warning(msg);
}
public void version() {
info("ANTLR Parser Generator Version " + new Tool().VERSION);
}
public void exit(int e) { System.exit(e); }
public void panic() { throw new Error("ANTLR panic"); }
}

View File

@ -0,0 +1,43 @@
package org.antlr.v4.tool;
import java.util.Arrays;
public class ANTLRMessage {
public ErrorType errorType;
public Object[] args;
public Throwable e;
// used for location template
public String fileName;
public int line = -1;
public int charPosition = -1;
public ANTLRMessage() {
}
public ANTLRMessage(ErrorType errorType) {
this.errorType = errorType;
}
public ANTLRMessage(ErrorType errorType, Object... args) {
this(errorType);
this.args = args;
}
public ANTLRMessage(ErrorType errorType, Throwable e, Object... args) {
this(errorType, args);
this.e = e;
}
@Override
public String toString() {
return "Message{" +
"errorType=" + errorType +
", args=" + (args == null ? null : Arrays.asList(args)) +
", e=" + e +
", fileName='" + fileName + '\'' +
", line=" + line +
", charPosition=" + charPosition +
'}';
}
}

View File

@ -0,0 +1,14 @@
package org.antlr.v4.tool;
/** Defines behavior of object able to handle error messages from ANTLR including
* both tool errors like "can't write file" and grammar ambiguity warnings.
* To avoid having to change tools that use ANTLR (like GUIs), I am
* wrapping error data in Message objects and passing them to the listener.
* In this way, users of this interface are less sensitive to changes in
* the info I need for error messages.
*/
public interface ANTLRToolListener {
public void info(String msg);
public void error(ANTLRMessage msg);
public void warning(ANTLRMessage msg);
}

View File

@ -0,0 +1,36 @@
package org.antlr.v4.tool;
import org.antlr.v4.Tool;
import org.stringtemplate.v4.ST;
/** */
public class DefaultToolListener implements ANTLRToolListener {
public Tool tool;
public DefaultToolListener(Tool tool) { this.tool = tool; }
public void info(String msg) {
if (tool.errMgr.formatWantsSingleLineMessage()) {
msg = msg.replaceAll("\n", " ");
}
System.out.println(msg);
}
public void error(ANTLRMessage msg) {
ST msgST = tool.errMgr.getMessageTemplate(msg);
String outputMsg = msgST.render();
if (tool.errMgr.formatWantsSingleLineMessage()) {
outputMsg = outputMsg.replaceAll("\n", " ");
}
System.err.println(outputMsg);
}
public void warning(ANTLRMessage msg) {
ST msgST = tool.errMgr.getMessageTemplate(msg);
String outputMsg = msgST.render();
if (tool.errMgr.formatWantsSingleLineMessage()) {
outputMsg = outputMsg.replaceAll("\n", " ");
}
System.err.println(outputMsg);
}
}

View File

@ -0,0 +1,413 @@
package org.antlr.v4.tool;
import org.antlr.runtime.Token;
import org.antlr.v4.Tool;
import org.stringtemplate.v4.ST;
import org.stringtemplate.v4.STErrorListener;
import org.stringtemplate.v4.STGroup;
import org.stringtemplate.v4.STGroupFile;
import org.stringtemplate.v4.misc.ErrorBuffer;
import org.stringtemplate.v4.misc.STMessage;
import java.net.URL;
import java.util.Collection;
import java.util.Locale;
/** Defines all the errors ANTLR can generator for both the tool and for
* issues with a grammar.
*
* Here is a list of language names:
*
* http://ftp.ics.uci.edu/pub/ietf/http/related/iso639.txt
*
* Here is a list of country names:
*
* http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html
*
* I use constants not strings to identify messages as the compiler will
* find any errors/mismatches rather than leaving a mistyped string in
* the code to be found randomly in the future. Further, Intellij can
* do field name expansion to save me some typing. I have to map
* int constants to template names, however, which could introduce a mismatch.
* Someone could provide a .stg file that had a template name wrong. When
* I load the group, then, I must verify that all messages are there.
*
* This is essentially the functionality of the resource bundle stuff Java
* has, but I don't want to load a property file--I want to load a template
* group file and this is so simple, why mess with their junk.
*
* I use the default Locale as defined by java to compute a group file name
* in the org/antlr/tool/templates/messages dir called en_US.stg and so on.
*
* Normally we want to use the default locale, but often a message file will
* not exist for it so we must fall back on the US local.
*
* During initialization of this class, all errors go straight to System.err.
* There is no way around this. If I have not set up the error system, how
* can I do errors properly? For example, if the string template group file
* full of messages has an error, how could I print to anything but System.err?
*/
public class ErrorManager {
public static final String FORMATS_DIR = "org/antlr/v4/tool/templates/messages/formats/";
public static final String MESSAGES_DIR = "org/antlr/v4/tool/templates/messages/languages/";
public Tool tool;
public int errors;
public int warnings;
/** The group of templates that represent all possible ANTLR errors. */
STGroup messages;
/** The group of templates that represent the current message format. */
STGroup format;
/** Messages should be sensitive to the locale. */
Locale locale;
String formatName;
ErrorBuffer initSTListener = new ErrorBuffer();
STErrorListener theDefaultSTListener =
new STErrorListener() {
public void compileTimeError(STMessage msg) {
ErrorManager.internalError(msg.toString());
}
public void runTimeError(STMessage msg) {
ErrorManager.internalError(msg.toString());
}
public void IOError(STMessage msg) {
ErrorManager.internalError(msg.toString());
}
public void internalError(STMessage msg) {
ErrorManager.internalError(msg.toString());
}
};
public ErrorManager(Tool tool) {
this.tool = tool;
//org.stringtemplate.v4.misc.ErrorManager.setErrorListener(initSTListener);
// it is inefficient to set the default locale here if another
// piece of code is going to set the locale, but that would
// require that a user call an init() function or something. I prefer
// that this class be ready to go when loaded as I'm absentminded ;)
setLocale(Locale.getDefault());
// try to load the message format group
// the user might have specified one on the command line
// if not, or if the user has given an illegal value, we will fall back to "antlr"
setFormat("antlr");
//org.stringtemplate.v4.misc.ErrorManager.setErrorListener(theDefaultSTListener);
}
public void resetErrorState() {
errors = 0;
warnings = 0;
}
public ST getMessageTemplate(ANTLRMessage msg) {
ST messageST = getMessageTemplate(msg.errorType);
ST locationST = getLocationFormat();
ST reportST = getReportFormat(msg.errorType.getSeverity());
ST messageFormatST = getMessageFormat();
if ( msg.args!=null ) { // fill in arg1, arg2, ...
for (int i=0; i<msg.args.length; i++) {
if ( i==(msg.args.length-1) && msg.args[i]==null ) { // don't set last if null
continue;
}
String attr = "arg";
if ( i>0 ) attr += i + 1;
messageST.add(attr, msg.args[i]);
}
}
if ( msg.e!=null ) {
messageST.add("exception", msg.e);
messageST.add("stackTrace", msg.e.getStackTrace());
}
boolean locationValid = false;
if (msg.line != -1) {
locationST.add("line", msg.line);
locationValid = true;
}
if (msg.charPosition != -1) {
locationST.add("column", msg.charPosition);
locationValid = true;
}
if (msg.fileName != null) {
locationST.add("file", msg.fileName);
locationValid = true;
}
messageFormatST.add("id", msg.errorType.ordinal());
messageFormatST.add("text", messageST);
if (locationValid) reportST.add("location", locationST);
reportST.add("message", messageFormatST);
//((DebugST)reportST).inspect();
//reportST.impl.dump();
return reportST;
}
/** Return a StringTemplate that refers to the current format used for
* emitting messages.
*/
public ST getLocationFormat() {
return format.getInstanceOf("location");
}
public ST getReportFormat(ErrorSeverity severity) {
ST st = format.getInstanceOf("report");
ST type = messages.getInstanceOf(severity.toString());
st.add("type", type);
return st;
}
public ST getMessageFormat() {
return format.getInstanceOf("message");
}
public boolean formatWantsSingleLineMessage() {
return format.getInstanceOf("wantsSingleLineMessage").render().equals("true");
}
public ST getMessageTemplate(ErrorType etype) {
String msgName = etype.toString();
return messages.getInstanceOf(msgName);
}
public void info(String msg) { tool.info(msg); }
public void syntaxError(ErrorType etype,
String fileName,
org.antlr.runtime.Token token,
org.antlr.runtime.RecognitionException antlrException,
Object... args)
{
errors++;
ANTLRMessage msg = new GrammarSyntaxMessage(etype,fileName,token,antlrException,args);
tool.error(msg);
}
public static void fatalInternalError(String error, Throwable e) {
internalError(error, e);
throw new RuntimeException(error, e);
}
public static void internalError(String error, Throwable e) {
StackTraceElement location = getLastNonErrorManagerCodeLocation(e);
internalError("Exception "+e+"@"+location+": "+error);
}
public static void internalError(String error) {
StackTraceElement location =
getLastNonErrorManagerCodeLocation(new Exception());
String msg = location+": "+error;
System.err.println("internal error: "+msg);
}
/**
* Raise a predefined message with some number of paramters for the StringTemplate but for which there
* is no location information possible.
* @param errorType The Message Descriptor
* @param args The arguments to pass to the StringTemplate
*/
public void toolError(ErrorType errorType, Object... args) {
errors++;
tool.error(new ToolMessage(errorType, args));
}
public void grammarError(ErrorType etype,
String fileName,
org.antlr.runtime.Token token,
Object... args)
{
errors++;
ANTLRMessage msg = new GrammarSemanticsMessage(etype,fileName,token,args);
tool.error(msg);
}
public void grammarWarning(ErrorType etype,
String fileName,
Token token,
Object... args)
{
warnings++;
ANTLRMessage msg = new GrammarSemanticsMessage(etype,fileName,token,args);
tool.warning(msg);
}
public void leftRecursionCycles(String fileName, Collection cycles) {
errors++;
ANTLRMessage msg = new LeftRecursionCyclesMessage(fileName, cycles);
tool.error(msg);
}
public int getNumErrors() {
return errors;
}
/** Return first non ErrorManager code location for generating messages */
private static StackTraceElement getLastNonErrorManagerCodeLocation(Throwable e) {
StackTraceElement[] stack = e.getStackTrace();
int i = 0;
for (; i < stack.length; i++) {
StackTraceElement t = stack[i];
if ( t.toString().indexOf("ErrorManager")<0 ) {
break;
}
}
StackTraceElement location = stack[i];
return location;
}
// S U P P O R T C O D E
/** We really only need a single locale for entire running ANTLR code
* in a single VM. Only pay attention to the language, not the country
* so that French Canadians and French Frenchies all get the same
* template file, fr.stg. Just easier this way.
*/
public void setLocale(Locale locale) {
this.locale = locale;
String language = locale.getLanguage();
String fileName = MESSAGES_DIR +language+".stg";
ClassLoader cl = Thread.currentThread().getContextClassLoader();
URL url = cl.getResource(fileName);
if ( url==null ) {
cl = ErrorManager.class.getClassLoader();
url = cl.getResource(fileName);
}
if ( url==null && language.equals(Locale.US.getLanguage()) ) {
rawError("ANTLR installation corrupted; cannot find English messages file "+fileName);
panic();
}
else if ( url==null ) {
//rawError("no such locale file "+fileName+" retrying with English locale");
setLocale(Locale.US); // recurse on this rule, trying the US locale
return;
}
messages = new STGroupFile(fileName, "UTF-8");
messages.load();
if ( initSTListener.errors.size()>0 ) {
rawError("ANTLR installation corrupted; can't load messages format file:\n"+
initSTListener.toString());
panic();
}
boolean messagesOK = verifyMessages();
if ( !messagesOK && language.equals(Locale.US.getLanguage()) ) {
rawError("ANTLR installation corrupted; English messages file "+language+".stg incomplete");
panic();
}
else if ( !messagesOK ) {
setLocale(Locale.US); // try US to see if that will work
}
}
/** The format gets reset either from the Tool if the user supplied a command line option to that effect
* Otherwise we just use the default "antlr".
*/
public void setFormat(String formatName) {
this.formatName = formatName;
String fileName = FORMATS_DIR +formatName+".stg";
ClassLoader cl = Thread.currentThread().getContextClassLoader();
URL url = cl.getResource(fileName);
if ( url==null ) {
cl = ErrorManager.class.getClassLoader();
url = cl.getResource(fileName);
}
if ( url==null && formatName.equals("antlr") ) {
rawError("ANTLR installation corrupted; cannot find ANTLR messages format file "+fileName);
panic();
}
else if ( url==null ) {
rawError("no such message format file "+fileName+" retrying with default ANTLR format");
setFormat("antlr"); // recurse on this rule, trying the default message format
return;
}
format = new STGroupFile(fileName, "UTF-8");
format.load();
if ( initSTListener.errors.size()>0 ) {
rawError("ANTLR installation corrupted; can't load messages format file:\n"+
initSTListener.toString());
panic();
}
boolean formatOK = verifyFormat();
if ( !formatOK && formatName.equals("antlr") ) {
rawError("ANTLR installation corrupted; ANTLR messages format file "+formatName+".stg incomplete");
panic();
}
else if ( !formatOK ) {
setFormat("antlr"); // recurse on this rule, trying the default message format
}
}
/** Use reflection to find list of MSG_ fields and then verify a
* template exists for each one from the locale's group.
*/
protected boolean verifyMessages() {
boolean ok = true;
ErrorType[] errors = ErrorType.values();
for (int i = 0; i < errors.length; i++) {
ErrorType e = errors[i];
if ( !messages.isDefined(e.toString()) ) {
System.err.println("Message "+e.toString()+" in locale "+
locale+" not found");
ok = false;
}
}
// check for special templates
if (!messages.isDefined("WARNING")) {
System.err.println("Message template 'warning' not found in locale "+ locale);
ok = false;
}
if (!messages.isDefined("ERROR")) {
System.err.println("Message template 'error' not found in locale "+ locale);
ok = false;
}
return ok;
}
/** Verify the message format template group */
protected boolean verifyFormat() {
boolean ok = true;
if (!format.isDefined("location")) {
System.err.println("Format template 'location' not found in " + formatName);
ok = false;
}
if (!format.isDefined("message")) {
System.err.println("Format template 'message' not found in " + formatName);
ok = false;
}
if (!format.isDefined("report")) {
System.err.println("Format template 'report' not found in " + formatName);
ok = false;
}
return ok;
}
/** If there are errors during ErrorManager init, we have no choice
* but to go to System.err.
*/
static void rawError(String msg) {
System.err.println(msg);
}
static void rawError(String msg, Throwable e) {
rawError(msg);
e.printStackTrace(System.err);
}
public static void panic() {
// can't call tool.panic since there may be multiple tools; just
// one error manager
throw new Error("ANTLR ErrorManager panic");
}
}

View File

@ -0,0 +1,67 @@
/*
[The "BSD licence"]
Copyright (c) 2005-2008 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.antlr.v4.tool;
/**
* Abstracts away the definition of Message severity and the text that should
* display to represent that severity if there is no StringTemplate available
* to do it.
*
* @author Jim Idle - Temporal Wave LLC (jimi@temporal-wave.com)
*/
public enum ErrorSeverity {
INFO ("Info"),
WARNING ("Warning"),
ERROR ("Error"),
FATAL ("Fatal"), // TODO: add fatal for which phase? sync with ErrorManager
;
/**
* The text version of the ENUM value, used for display purposes
*/
private final String text;
/**
* Standard getter method for the text that should be displayed in order to
* represent the severity to humans and product modelers.
*
* @return The human readable string representing the severity level
*/
public String getText() { return text; }
/**
* Standard constructor to build an instance of the Enum entries
*
* @param text The human readable string representing the serverity level
*/
private ErrorSeverity(String text) { this.text = text; }
}

View File

@ -0,0 +1,243 @@
/*
[The "BSD licence"]
Copyright (c) 2005-2008 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.antlr.v4.tool;
/**
* A complex enumeration of all the error messages that the tool can issue.
*
* When adding error messages, also add a description of the message to the
* Wiki with a location under the Wiki page
* <a href="http://www.antlr.org/wiki/display/ANTLR3/Errors+Reported+by+the+ANTLR+Tool">Errors Reported by the ANTLR Tool</a>.
*
* TODO: add notion of single issuance of an error; some don't need to be repeated; AST_OP_IN_ALT_WITH_REWRITE and option issues
*
* @author Jim Idle <jimi@temporal-wave.com>
* @since 4.0
*/
public enum ErrorType {
INVALID(ErrorSeverity.ERROR,true,true),
// TODO: set all of the true, true appropriately
CANNOT_WRITE_FILE(ErrorSeverity.ERROR, true, true),
CANNOT_CLOSE_FILE(ErrorSeverity.ERROR, true, true),
CANNOT_FIND_TOKENS_FILE(ErrorSeverity.ERROR, true, true),
ERROR_READING_TOKENS_FILE(ErrorSeverity.ERROR, true, true),
DIR_NOT_FOUND(ErrorSeverity.ERROR, true, true),
OUTPUT_DIR_IS_FILE(ErrorSeverity.ERROR, true, true),
CANNOT_OPEN_FILE(ErrorSeverity.ERROR, true, true),
FILE_AND_GRAMMAR_NAME_DIFFER(ErrorSeverity.ERROR, true, true),
FILENAME_EXTENSION_ERROR(ErrorSeverity.ERROR, true, true),
INTERNAL_ERROR(ErrorSeverity.ERROR, true, true),
INTERNAL_WARNING(ErrorSeverity.ERROR, true, true),
TOKENS_FILE_SYNTAX_ERROR(ErrorSeverity.ERROR, true, true),
CANNOT_GEN_DOT_FILE(ErrorSeverity.ERROR, true, true),
// Code generation errors
MISSING_CODE_GEN_TEMPLATES(ErrorSeverity.ERROR, false, true),
CANNOT_CREATE_TARGET_GENERATOR(ErrorSeverity.ERROR, false, true),
CODE_TEMPLATE_ARG_ISSUE(ErrorSeverity.ERROR, false, true),
CODE_GEN_TEMPLATES_INCOMPLETE(ErrorSeverity.ERROR, false, true),
NO_MODEL_TO_TEMPLATE_MAPPING(ErrorSeverity.ERROR, false, true),
// Grammar errors
SYNTAX_ERROR(ErrorSeverity.ERROR, true, true),
RULE_REDEFINITION(ErrorSeverity.ERROR, true, true),
LEXER_RULES_NOT_ALLOWED(ErrorSeverity.ERROR, true, true),
PARSER_RULES_NOT_ALLOWED(ErrorSeverity.ERROR, true, true),
REPEATED_PREQUEL(ErrorSeverity.ERROR, true, true),
NO_TOKEN_DEFINITION(ErrorSeverity.ERROR, true, true),
UNDEFINED_RULE_REF(ErrorSeverity.ERROR, true, true),
LITERAL_NOT_ASSOCIATED_WITH_LEXER_RULE(ErrorSeverity.ERROR, true, true),
CANNOT_ALIAS_TOKENS(ErrorSeverity.ERROR, true, true),
TOKEN_NAMES_MUST_START_UPPER(ErrorSeverity.ERROR, true, true),
ATTRIBUTE_REF_NOT_IN_RULE(ErrorSeverity.ERROR, true, true),
INVALID_RULE_SCOPE_ATTRIBUTE_REF(ErrorSeverity.ERROR, true, true),
UNKNOWN_SIMPLE_ATTRIBUTE(ErrorSeverity.ERROR, true, true),
INVALID_RULE_PARAMETER_REF(ErrorSeverity.ERROR, true, true),
UNKNOWN_RULE_ATTRIBUTE(ErrorSeverity.ERROR, true, true),
UNKNOWN_ATTRIBUTE_IN_SCOPE(ErrorSeverity.ERROR, true, true),
ISOLATED_RULE_REF(ErrorSeverity.ERROR, true, true),
SYMBOL_CONFLICTS_WITH_GLOBAL_SCOPE(ErrorSeverity.ERROR, true, true),
LABEL_CONFLICTS_WITH_RULE(ErrorSeverity.ERROR, true, true),
LABEL_CONFLICTS_WITH_TOKEN(ErrorSeverity.ERROR, true, true),
LABEL_CONFLICTS_WITH_RULE_SCOPE_ATTRIBUTE(ErrorSeverity.ERROR, true, true),
LABEL_CONFLICTS_WITH_RULE_ARG_RETVAL(ErrorSeverity.ERROR, true, true),
ATTRIBUTE_CONFLICTS_WITH_RULE(ErrorSeverity.ERROR, true, true),
ATTRIBUTE_CONFLICTS_WITH_RULE_ARG_RETVAL(ErrorSeverity.ERROR, true, true),
LABEL_TYPE_CONFLICT(ErrorSeverity.ERROR, true, true),
ARG_RETVAL_CONFLICT(ErrorSeverity.ERROR, true, true),
NONUNIQUE_REF(ErrorSeverity.ERROR, true, true),
FORWARD_ELEMENT_REF(ErrorSeverity.ERROR, true, true),
MISSING_RULE_ARGS(ErrorSeverity.ERROR, true, true),
RULE_HAS_NO_ARGS(ErrorSeverity.ERROR, true, true),
ARGS_ON_TOKEN_REF(ErrorSeverity.ERROR, true, true),
RULE_REF_AMBIG_WITH_RULE_IN_ALT(ErrorSeverity.ERROR, true, true),
ILLEGAL_OPTION(ErrorSeverity.ERROR, true, true),
LIST_LABEL_INVALID_UNLESS_RETVAL_STRUCT(ErrorSeverity.ERROR, true, true),
REWRITE_ELEMENT_NOT_PRESENT_ON_LHS(ErrorSeverity.ERROR, true, true),
//UNDEFINED_TOKEN_REF_IN_REWRITE(ErrorSeverity.ERROR, true, true),
///UNDEFINED_LABEL_REF_IN_REWRITE(ErrorSeverity.ERROR, true, true), use previous
NO_GRAMMAR_START_RULE(ErrorSeverity.ERROR, true, true),
EMPTY_COMPLEMENT(ErrorSeverity.ERROR, true, true),
UNKNOWN_DYNAMIC_SCOPE(ErrorSeverity.ERROR, true, true),
UNKNOWN_DYNAMIC_SCOPE_ATTRIBUTE(ErrorSeverity.ERROR, true, true),
ISOLATED_RULE_ATTRIBUTE(ErrorSeverity.ERROR, true, true),
INVALID_ACTION_SCOPE(ErrorSeverity.ERROR, true, true),
ACTION_REDEFINITION(ErrorSeverity.ERROR, true, true),
SCOPE_REDEFINITION(ErrorSeverity.ERROR, true, true),
INVALID_TEMPLATE_ACTION(ErrorSeverity.ERROR, true, true),
ARG_INIT_VALUES_ILLEGAL(ErrorSeverity.ERROR, true, true),
REWRITE_OR_OP_WITH_NO_OUTPUT_OPTION(ErrorSeverity.ERROR, true, true),
NO_RULES(ErrorSeverity.ERROR, true, true),
WRITE_TO_READONLY_ATTR(ErrorSeverity.ERROR, true, true),
MISSING_AST_TYPE_IN_TREE_GRAMMAR(ErrorSeverity.ERROR, true, true),
REWRITE_FOR_MULTI_ELEMENT_ALT(ErrorSeverity.ERROR, true, true),
RULE_INVALID_SET(ErrorSeverity.ERROR, true, true),
HETERO_ILLEGAL_IN_REWRITE_ALT(ErrorSeverity.ERROR, true, true),
NO_SUCH_GRAMMAR_SCOPE(ErrorSeverity.ERROR, true, true),
NO_SUCH_RULE_IN_SCOPE(ErrorSeverity.ERROR, true, true),
TOKEN_ALIAS_CONFLICT(ErrorSeverity.ERROR, true, true),
TOKEN_ALIAS_REASSIGNMENT(ErrorSeverity.ERROR, true, true),
TOKEN_VOCAB_IN_DELEGATE(ErrorSeverity.ERROR, true, true),
TOKEN_ALIAS_IN_DELEGATE(ErrorSeverity.ERROR, true, true),
INVALID_IMPORT(ErrorSeverity.ERROR, true, true),
IMPORTED_TOKENS_RULE_EMPTY(ErrorSeverity.ERROR, true, true),
IMPORT_NAME_CLASH(ErrorSeverity.ERROR, true, true),
AST_OP_WITH_NON_AST_OUTPUT_OPTION(ErrorSeverity.ERROR, true, true),
AST_OP_IN_ALT_WITH_REWRITE(ErrorSeverity.ERROR, true, true),
WILDCARD_AS_ROOT(ErrorSeverity.ERROR, true, true),
CONFLICTING_OPTION_IN_TREE_FILTER(ErrorSeverity.ERROR, true, true),
AMBIGUITY(ErrorSeverity.ERROR, true, true),
UNREACHABLE_ALTS(ErrorSeverity.ERROR, true, true),
//MULTIPLE_RECURSIVE_ALTS(ErrorSeverity.ERROR, true, true),
INSUFFICIENT_PREDICATES(ErrorSeverity.ERROR, true, true),
// these next 3 can happen in recursion-limited LL(*)
//RECURSION_OVERFLOW(ErrorSeverity.ERROR, true, true),
LEFT_RECURSION_CYCLES(ErrorSeverity.ERROR, true, true),
ANALYSIS_TIMEOUT(ErrorSeverity.ERROR, true, true),
MODE_NOT_IN_LEXER(ErrorSeverity.ERROR, true, true),
/** Documentation comment is unterminated */
//UNTERMINATED_DOC_COMMENT(ErrorSeverity.ERROR, true, true),
// Dependency sorting errors
//
/** t1.g -> t2.g -> t3.g ->t1.g */
CIRCULAR_DEPENDENCY(ErrorSeverity.ERROR, true, true),
// Simple informational messages
//
/** A standby generic message that jsut spits out the arguments it is given */
// GENERIC_INFO(ErrorSeverity.INFO, false, false),
// /** How to print out the version of the ANTLR tool that we are */
// ANTLR_VERSION(ErrorSeverity.INFO, false, false),
//
// // Command line tool errors/warnings
// /** -fo option was incorrectly formed */
// MISSING_OUTPUT_FO(ErrorSeverity.WARNING, false, false),
// /** -lib option is missing a directory argument */
// MISSING_LIBDIR(ErrorSeverity.WARNING, false, false),
// /** -format option was not given the name of a message format */
// MISSING_FORMAT(ErrorSeverity.WARNING, false, false),
// /** Max state count missing from the option */
// MISSING_MAXSTATES(ErrorSeverity.WARNING, false, false),
// /** Max labels in a switch argument is missing */
// MISSING_MAXSWITCH(ErrorSeverity.WARNING, false, false),
// /** Min labels in a switch argument is missing */
// MISSING_MINSWITCH(ErrorSeverity.WARNING, false, false),
// /** Missing recursion limit argument */
// MISSING_MAXRECUR(ErrorSeverity.WARNING, false, false),
// /** Missing max edges argument */
// MISSING_MAXEDGE(ErrorSeverity.WARNING, false, false),
// /** Misng ms timeout argument */
// MISSING_MAXTIME(ErrorSeverity.WARNING, false, false),
//
// // Help messages
// HELP_USAGE(ErrorSeverity.INFO, false, false),
// HELP_EXTENDED(ErrorSeverity.INFO, false, false),
;
/**
* Local storage for the severity level of the message
*/
private ErrorSeverity severity;
/**
* Returns the severity level of this message
* @return
*/
public ErrorSeverity getSeverity() {
return severity;
}
/**
* Internal storage for the flag that indicates whether this particular message
* should abort the analysis phase or not.
*/
private Boolean abortsAnalysis;
/**
* Indicates whether the raising of this error messsage should abort the
* analysis phase (or prevent it from starting).
*
* @return true if this message should abort the analysis phase
*/
public Boolean abortsAnalysis() {
return abortsAnalysis;
}
/**
* Indicates whether the raising of this error message aborts code
* generation or not.
*/
private Boolean abortsCodegen;
/**
* Indicates whether the raising of this error message aborts code
* generation or not.
*
* @return true if this message should abort code generation
*/
public Boolean abortsCodegen() {
return abortsCodegen;
}
/**
* Local constructor produces an instance of the entries in this Enum
*/
private ErrorType(ErrorSeverity severity, boolean abortsAnalysis, boolean abortsCodegen) {
this.severity = severity;
this.abortsAnalysis = abortsAnalysis;
}
}

View File

@ -0,0 +1,4 @@
package org.antlr.v4.tool;
public class Grammar {
}

View File

@ -0,0 +1,45 @@
package org.antlr.v4.tool;
import org.antlr.runtime.Token;
/** A problem with the symbols and/or meaning of a grammar such as rule
* redefinition.
*/
public class GrammarSemanticsMessage extends ANTLRMessage {
public Grammar g;
/** Most of the time, we'll have a token such as an undefined rule ref
* and so this will be set.
*/
public Token offendingToken;
/*
public GrammarSemanticsMessage(ErrorType etype,
Grammar g,
Token offendingToken,
Object... args)
{
super(etype,args);
this.g = g;
if ( g!=null ) fileName = g.fileName;
this.offendingToken = offendingToken;
if ( offendingToken!=null ) {
line = offendingToken.getLine();
charPosition = offendingToken.getCharPositionInLine();
}
}
*/
public GrammarSemanticsMessage(ErrorType etype,
String fileName,
Token offendingToken,
Object... args)
{
super(etype,args);
this.fileName = fileName;
this.offendingToken = offendingToken;
if ( offendingToken!=null ) {
line = offendingToken.getLine();
charPosition = offendingToken.getCharPositionInLine();
}
}
}

View File

@ -0,0 +1,30 @@
package org.antlr.v4.tool;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.Token;
/** A problem with the syntax of your antlr grammar such as
* "The '{' came as a complete surprise to me at this point in your program"
*/
public class GrammarSyntaxMessage extends ANTLRMessage {
public Grammar g;
/** Most of the time, we'll have a token and so this will be set. */
public Token offendingToken;
public RecognitionException antlrException;
public GrammarSyntaxMessage(ErrorType etype,
String fileName,
Token offendingToken,
RecognitionException antlrException,
Object... args)
{
super(etype,args);
this.fileName = fileName;
this.offendingToken = offendingToken;
this.antlrException = antlrException;
if ( offendingToken!=null ) {
line = offendingToken.getLine();
charPosition = offendingToken.getCharPositionInLine();
}
}
}

View File

@ -0,0 +1,13 @@
package org.antlr.v4.tool;
import java.util.Collection;
public class LeftRecursionCyclesMessage extends ANTLRMessage {
public Collection cycles;
public LeftRecursionCyclesMessage(String fileName, Collection cycles) {
super(ErrorType.LEFT_RECURSION_CYCLES, cycles);
this.cycles = cycles;
this.fileName = fileName;
}
}

View File

@ -0,0 +1,21 @@
package org.antlr.v4.tool;
/** A generic message from the tool such as "file not found" type errors; there
* is no reason to create a special object for each error unlike the grammar
* errors, which may be rather complex.
*
* Sometimes you need to pass in a filename or something to say it is "bad".
* Allow a generic object to be passed in and the string template can deal
* with just printing it or pulling a property out of it.
*/
public class ToolMessage extends ANTLRMessage {
public ToolMessage(ErrorType errorType) {
super(errorType);
}
public ToolMessage(ErrorType errorType, Object... args) {
super(errorType, null, args);
}
public ToolMessage(ErrorType errorType, Throwable e, Object... args) {
super(errorType, e, args);
}
}