forked from jasder/antlr
[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 8640]
This commit is contained in:
parent
c186d5ad76
commit
a13068c7c2
|
@ -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"); }
|
||||||
|
|
||||||
|
}
|
|
@ -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 +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
|
@ -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; }
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
package org.antlr.v4.tool;
|
||||||
|
|
||||||
|
public class Grammar {
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue