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