got error handling with v4 ST working; no error loops etc...
[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6641]
This commit is contained in:
parent
c9d6efc7c5
commit
08d8a0db23
|
@ -26,17 +26,15 @@
|
|||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
New style messages. This file contains the actual layout of the messages emitted by ANTLR.
|
||||
This file contains the actual layout of the messages emitted by ANTLR.
|
||||
The text itself is coming out of the languages/*stg files, according to the chosen locale.
|
||||
This file contains the default format ANTLR uses.
|
||||
*/
|
||||
|
||||
group antlr;
|
||||
|
||||
location(file, line, column) ::= "<file>:<line>:<column>:"
|
||||
|
||||
message(id, text) ::= "(<id>) <text>"
|
||||
|
||||
report(location, message, type) ::= "<type>(<message.id>): <location> <message.text>"
|
||||
|
||||
wantsSingleLineMessage() ::= "false"
|
||||
wantsSingleLineMessage() ::= "false"
|
||||
|
|
|
@ -26,17 +26,15 @@
|
|||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
New style messages. This file contains the actual layout of the messages emitted by ANTLR.
|
||||
This file contains the actual layout of the messages emitted by ANTLR.
|
||||
The text itself is coming out of the languages/*stg files, according to the chosen locale.
|
||||
This file contains the format that mimicks GCC output.
|
||||
*/
|
||||
|
||||
group gnu;
|
||||
|
||||
location(file, line, column) ::= "<file>:<line>:"
|
||||
|
||||
message(id, text) ::= "<text> (<id>)"
|
||||
|
||||
report(location, message, type) ::= "<location> <type>: <message>"
|
||||
|
||||
wantsSingleLineMessage() ::= "true"
|
||||
wantsSingleLineMessage() ::= "true"
|
||||
|
|
|
@ -26,13 +26,11 @@
|
|||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
New style messages. This file contains the actual layout of the messages emitted by ANTLR.
|
||||
This file contains the actual layout of the messages emitted by ANTLR.
|
||||
The text itself is coming out of the languages/*stg files, according to the chosen locale.
|
||||
This file contains the default format ANTLR uses.
|
||||
*/
|
||||
|
||||
group antlr;
|
||||
|
||||
location(file, line, column) ::= "<file>(<line>,<column>)"
|
||||
|
||||
message(id, text) ::= "error <id> : <text>"
|
||||
|
|
|
@ -26,13 +26,11 @@
|
|||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
New style messages. This file only contains the messages in English, but no
|
||||
This file only contains the messages in English, but no
|
||||
information about which file, line, or column it occurred in.
|
||||
The location and message ids are taken out of the formats directory.
|
||||
Kay Roepke
|
||||
*/
|
||||
group en_US;
|
||||
|
||||
// TOOL ERRORS
|
||||
// file errors
|
||||
CANNOT_WRITE_FILE(arg,exception,stackTrace) ::= <<
|
||||
|
@ -46,8 +44,8 @@ problem reading token vocabulary file <arg>: <exception>
|
|||
<stackTrace; separator="\n">
|
||||
>>
|
||||
DIR_NOT_FOUND(arg,exception,stackTrace) ::= "directory not found: <arg>"
|
||||
OUTPUT_DIR_IS_FILE(arg,exception,stackTrace) ::= "output directory is a file: <arg>"
|
||||
CANNOT_OPEN_FILE(arg,exception,stackTrace) ::= "cannot find or open file: <arg><if(exception)>; reason: <exception><endif>"
|
||||
OUTPUT_DIR_IS_FILE(arg,arg2) ::= "output directory is a file: <arg>"
|
||||
CANNOT_OPEN_FILE(arg,exception) ::= "cannot find or open file: <arg><if(exception)>; reason: <exception><endif>"
|
||||
CIRCULAR_DEPENDENCY() ::= "your grammars contain a circular dependency and cannot be sorted into a valid build order."
|
||||
|
||||
INTERNAL_ERROR(arg,arg2,exception,stackTrace) ::= <<
|
||||
|
|
|
@ -7,6 +7,7 @@ import org.antlr.v4.semantics.SemanticsPipeline;
|
|||
import org.antlr.v4.tool.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
public class Tool {
|
||||
|
@ -66,18 +67,18 @@ public class Tool {
|
|||
/** An adaptor that tells ANTLR to build CymbalAST nodes */
|
||||
public static TreeAdaptor astAdaptor = new GrammarASTAdaptor();
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
public static void main(String[] args) {
|
||||
Tool antlr = new Tool(args);
|
||||
|
||||
if (!exitNow) {
|
||||
antlr.process();
|
||||
if (ErrorManager.getNumErrors() > 0) {
|
||||
System.exit(1);
|
||||
antlr.exit(1);
|
||||
}
|
||||
// System.exit(0);
|
||||
antlr.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Tool() {
|
||||
}
|
||||
|
||||
|
@ -85,6 +86,14 @@ public class Tool {
|
|||
processArgs(args);
|
||||
}
|
||||
|
||||
public void exit(int e) {
|
||||
System.exit(e);
|
||||
}
|
||||
|
||||
public void panic() {
|
||||
throw new Error("ANTLR panic");
|
||||
}
|
||||
|
||||
public void processArgs(String[] args) {
|
||||
if (verbose) {
|
||||
ErrorManager.info("ANTLR Parser Generator Version " + VERSION);
|
||||
|
@ -114,7 +123,7 @@ public class Tool {
|
|||
File outDir = new File(outputDirectory);
|
||||
haveOutputDir = true;
|
||||
if (outDir.exists() && !outDir.isDirectory()) {
|
||||
ErrorManager.error(ErrorType.OUTPUT_DIR_IS_FILE, outputDirectory);
|
||||
ErrorManager.toolError(ErrorType.OUTPUT_DIR_IS_FILE, outputDirectory);
|
||||
libDirectory = ".";
|
||||
}
|
||||
}
|
||||
|
@ -132,7 +141,7 @@ public class Tool {
|
|||
}
|
||||
File outDir = new File(libDirectory);
|
||||
if (!outDir.exists()) {
|
||||
ErrorManager.error(ErrorType.DIR_NOT_FOUND, libDirectory);
|
||||
ErrorManager.toolError(ErrorType.DIR_NOT_FOUND, libDirectory);
|
||||
libDirectory = ".";
|
||||
}
|
||||
}
|
||||
|
@ -282,22 +291,32 @@ public class Tool {
|
|||
}
|
||||
}
|
||||
|
||||
public Grammar load(String fileName) throws Exception {
|
||||
ANTLRFileStream in = new ANTLRFileStream(fileName);
|
||||
ANTLRLexer lexer = new ANTLRLexer(in);
|
||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||
ANTLRParser p = new ANTLRParser(tokens);
|
||||
p.setTreeAdaptor(astAdaptor);
|
||||
ParserRuleReturnScope r = p.grammarSpec();
|
||||
GrammarAST t = (GrammarAST) r.getTree();
|
||||
System.out.println(t.toStringTree());
|
||||
Grammar g = new Grammar(this, t);
|
||||
g.fileName = fileName;
|
||||
grammars.put(g.name, g);
|
||||
public Grammar load(String fileName) {
|
||||
Grammar g = null;
|
||||
try {
|
||||
ANTLRFileStream in = new ANTLRFileStream(fileName);
|
||||
ANTLRLexer lexer = new ANTLRLexer(in);
|
||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||
ANTLRParser p = new ANTLRParser(tokens);
|
||||
p.setTreeAdaptor(astAdaptor);
|
||||
ParserRuleReturnScope r = p.grammarSpec();
|
||||
GrammarAST t = (GrammarAST) r.getTree();
|
||||
System.out.println(t.toStringTree());
|
||||
g = new Grammar(this, t);
|
||||
g.fileName = fileName;
|
||||
grammars.put(g.name, g);
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
ErrorManager.toolError(ErrorType.CANNOT_OPEN_FILE, fileName, ioe);
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
// TODO: do we gen errors now?
|
||||
ErrorManager.internalError("can't generate this message at moment; antlr recovers");
|
||||
}
|
||||
return g;
|
||||
}
|
||||
|
||||
public void process() throws Exception {
|
||||
|
||||
public void process() {
|
||||
// testing parser
|
||||
Grammar g = load(grammarFileNames.get(0));
|
||||
g.loadImportedGrammars();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// $ANTLR 3.2.1-SNAPSHOT Jan 26, 2010 15:12:28 ANTLRLexer.g 2010-01-30 14:28:45
|
||||
// $ANTLR 3.2.1-SNAPSHOT Jan 26, 2010 15:12:28 ANTLRLexer.g 2010-01-31 12:53:18
|
||||
|
||||
/*
|
||||
[The "BSD licence"]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// $ANTLR 3.2.1-SNAPSHOT Jan 26, 2010 15:12:28 ANTLRParser.g 2010-01-30 14:28:48
|
||||
// $ANTLR 3.2.1-SNAPSHOT Jan 26, 2010 15:12:28 ANTLRParser.g 2010-01-31 12:53:20
|
||||
|
||||
/*
|
||||
[The "BSD licence"]
|
||||
|
@ -292,7 +292,7 @@ public class ANTLRParser extends Parser {
|
|||
|
||||
|
||||
// AST REWRITE
|
||||
// elements: grammarType, DOC_COMMENT, prequelConstruct, rules, id
|
||||
// elements: rules, DOC_COMMENT, prequelConstruct, id, grammarType
|
||||
// token labels:
|
||||
// rule labels: retval
|
||||
// token list labels:
|
||||
|
@ -1396,7 +1396,7 @@ public class ANTLRParser extends Parser {
|
|||
|
||||
|
||||
// AST REWRITE
|
||||
// elements: TOKENS, tokenSpec
|
||||
// elements: tokenSpec, TOKENS
|
||||
// token labels:
|
||||
// rule labels: retval
|
||||
// token list labels:
|
||||
|
@ -1572,7 +1572,7 @@ public class ANTLRParser extends Parser {
|
|||
|
||||
|
||||
// AST REWRITE
|
||||
// elements: lit, ASSIGN, TOKEN_REF
|
||||
// elements: ASSIGN, lit, TOKEN_REF
|
||||
// token labels: lit
|
||||
// rule labels: retval
|
||||
// token list labels:
|
||||
|
@ -1713,7 +1713,7 @@ public class ANTLRParser extends Parser {
|
|||
|
||||
|
||||
// AST REWRITE
|
||||
// elements: ACTION, SCOPE, id
|
||||
// elements: ACTION, id, SCOPE
|
||||
// token labels:
|
||||
// rule labels: retval
|
||||
// token list labels:
|
||||
|
@ -1858,7 +1858,7 @@ public class ANTLRParser extends Parser {
|
|||
|
||||
|
||||
// AST REWRITE
|
||||
// elements: ACTION, id, actionScopeName, AT
|
||||
// elements: actionScopeName, ACTION, id, AT
|
||||
// token labels:
|
||||
// rule labels: retval
|
||||
// token list labels:
|
||||
|
@ -2357,7 +2357,7 @@ public class ANTLRParser extends Parser {
|
|||
|
||||
|
||||
// AST REWRITE
|
||||
// elements: ruleReturns, exceptionGroup, ruleModifiers, DOC_COMMENT, id, altListAsBlock, rulePrequel, ARG_ACTION
|
||||
// elements: rulePrequel, DOC_COMMENT, ARG_ACTION, ruleReturns, exceptionGroup, ruleModifiers, altListAsBlock, id
|
||||
// token labels:
|
||||
// rule labels: retval
|
||||
// token list labels:
|
||||
|
@ -2583,7 +2583,7 @@ public class ANTLRParser extends Parser {
|
|||
|
||||
|
||||
// AST REWRITE
|
||||
// elements: ACTION, ARG_ACTION, CATCH
|
||||
// elements: ACTION, CATCH, ARG_ACTION
|
||||
// token labels:
|
||||
// rule labels: retval
|
||||
// token list labels:
|
||||
|
@ -3189,7 +3189,7 @@ public class ANTLRParser extends Parser {
|
|||
|
||||
|
||||
// AST REWRITE
|
||||
// elements: SCOPE, id
|
||||
// elements: id, SCOPE
|
||||
// token labels:
|
||||
// rule labels: retval
|
||||
// token list labels:
|
||||
|
@ -3804,7 +3804,7 @@ public class ANTLRParser extends Parser {
|
|||
|
||||
|
||||
// AST REWRITE
|
||||
// elements: elements, rewrite
|
||||
// elements: rewrite, elements
|
||||
// token labels:
|
||||
// rule labels: retval
|
||||
// token list labels:
|
||||
|
@ -4357,7 +4357,7 @@ public class ANTLRParser extends Parser {
|
|||
|
||||
|
||||
// AST REWRITE
|
||||
// elements: ebnfSuffix, atom
|
||||
// elements: atom, ebnfSuffix
|
||||
// token labels:
|
||||
// rule labels: retval
|
||||
// token list labels:
|
||||
|
@ -4582,7 +4582,7 @@ public class ANTLRParser extends Parser {
|
|||
|
||||
|
||||
// AST REWRITE
|
||||
// elements: treeSpec, ebnfSuffix
|
||||
// elements: ebnfSuffix, treeSpec
|
||||
// token labels:
|
||||
// rule labels: retval
|
||||
// token list labels:
|
||||
|
@ -5022,7 +5022,7 @@ public class ANTLRParser extends Parser {
|
|||
|
||||
|
||||
// AST REWRITE
|
||||
// elements: blockSuffixe, block
|
||||
// elements: block, blockSuffixe
|
||||
// token labels:
|
||||
// rule labels: retval
|
||||
// token list labels:
|
||||
|
@ -5586,7 +5586,7 @@ public class ANTLRParser extends Parser {
|
|||
|
||||
|
||||
// AST REWRITE
|
||||
// elements: id, terminal
|
||||
// elements: terminal, id
|
||||
// token labels:
|
||||
// rule labels: retval
|
||||
// token list labels:
|
||||
|
@ -6092,7 +6092,7 @@ public class ANTLRParser extends Parser {
|
|||
|
||||
|
||||
// AST REWRITE
|
||||
// elements: optionsSpec, altList, ra, ACTION
|
||||
// elements: ra, optionsSpec, altList, ACTION
|
||||
// token labels:
|
||||
// rule labels: retval
|
||||
// token list labels:
|
||||
|
@ -6273,7 +6273,7 @@ public class ANTLRParser extends Parser {
|
|||
|
||||
|
||||
// AST REWRITE
|
||||
// elements: op, RULE_REF, ARG_ACTION
|
||||
// elements: RULE_REF, ARG_ACTION, op
|
||||
// token labels: op
|
||||
// rule labels: retval
|
||||
// token list labels:
|
||||
|
@ -6609,7 +6609,7 @@ public class ANTLRParser extends Parser {
|
|||
|
||||
|
||||
// AST REWRITE
|
||||
// elements: CHAR_LITERAL, elementOptions
|
||||
// elements: elementOptions, CHAR_LITERAL
|
||||
// token labels:
|
||||
// rule labels: retval
|
||||
// token list labels:
|
||||
|
@ -6694,7 +6694,7 @@ public class ANTLRParser extends Parser {
|
|||
|
||||
|
||||
// AST REWRITE
|
||||
// elements: elementOptions, ARG_ACTION, TOKEN_REF
|
||||
// elements: TOKEN_REF, elementOptions, ARG_ACTION
|
||||
// token labels:
|
||||
// rule labels: retval
|
||||
// token list labels:
|
||||
|
@ -6765,7 +6765,7 @@ public class ANTLRParser extends Parser {
|
|||
|
||||
|
||||
// AST REWRITE
|
||||
// elements: STRING_LITERAL, elementOptions
|
||||
// elements: elementOptions, STRING_LITERAL
|
||||
// token labels:
|
||||
// rule labels: retval
|
||||
// token list labels:
|
||||
|
@ -6886,7 +6886,7 @@ public class ANTLRParser extends Parser {
|
|||
|
||||
|
||||
// AST REWRITE
|
||||
// elements: terminal, ROOT
|
||||
// elements: ROOT, terminal
|
||||
// token labels:
|
||||
// rule labels: retval
|
||||
// token list labels:
|
||||
|
@ -7440,7 +7440,7 @@ public class ANTLRParser extends Parser {
|
|||
|
||||
|
||||
// AST REWRITE
|
||||
// elements: rewriteAlt, rewriteAlt, SEMPRED, SEMPRED
|
||||
// elements: rewriteAlt, SEMPRED, SEMPRED, rewriteAlt
|
||||
// token labels:
|
||||
// rule labels: retval
|
||||
// token list labels:
|
||||
|
@ -7982,7 +7982,7 @@ public class ANTLRParser extends Parser {
|
|||
|
||||
|
||||
// AST REWRITE
|
||||
// elements: rewriteTree, ebnfSuffix
|
||||
// elements: ebnfSuffix, rewriteTree
|
||||
// token labels:
|
||||
// rule labels: retval
|
||||
// token list labels:
|
||||
|
@ -8212,7 +8212,7 @@ public class ANTLRParser extends Parser {
|
|||
|
||||
|
||||
// AST REWRITE
|
||||
// elements: TOKEN_REF, ARG_ACTION
|
||||
// elements: ARG_ACTION, TOKEN_REF
|
||||
// token labels:
|
||||
// rule labels: retval
|
||||
// token list labels:
|
||||
|
@ -8532,7 +8532,7 @@ public class ANTLRParser extends Parser {
|
|||
|
||||
|
||||
// AST REWRITE
|
||||
// elements: TREE_BEGIN, rewriteTreeElement, rewriteTreeAtom
|
||||
// elements: rewriteTreeAtom, TREE_BEGIN, rewriteTreeElement
|
||||
// token labels:
|
||||
// rule labels: retval
|
||||
// token list labels:
|
||||
|
@ -8716,7 +8716,7 @@ public class ANTLRParser extends Parser {
|
|||
|
||||
|
||||
// AST REWRITE
|
||||
// elements: str, rewriteTemplateArgs, TEMPLATE
|
||||
// elements: rewriteTemplateArgs, str, TEMPLATE
|
||||
// token labels: str
|
||||
// rule labels: retval
|
||||
// token list labels:
|
||||
|
@ -8977,7 +8977,7 @@ public class ANTLRParser extends Parser {
|
|||
|
||||
|
||||
// AST REWRITE
|
||||
// elements: ACTION, rewriteTemplateArgs
|
||||
// elements: rewriteTemplateArgs, ACTION
|
||||
// token labels:
|
||||
// rule labels: retval
|
||||
// token list labels:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// $ANTLR 3.2.1-SNAPSHOT Jan 26, 2010 15:12:28 ASTVerifier.g 2010-01-30 14:28:48
|
||||
// $ANTLR 3.2.1-SNAPSHOT Jan 26, 2010 15:12:28 ASTVerifier.g 2010-01-31 12:53:21
|
||||
|
||||
/*
|
||||
[The "BSD license"]
|
||||
|
|
|
@ -102,6 +102,14 @@ package org.antlr.v4.semantics;
|
|||
import org.antlr.v4.tool.*;
|
||||
}
|
||||
|
||||
@members {
|
||||
Grammar g; // which grammar are we checking
|
||||
public BasicSemanticsChecker(TreeNodeStream input, Grammar g) {
|
||||
this(input);
|
||||
this.g = g;
|
||||
}
|
||||
}
|
||||
|
||||
topdown
|
||||
: grammarSpec
|
||||
| optionsSpec
|
||||
|
@ -111,7 +119,10 @@ topdown
|
|||
grammarSpec
|
||||
: ^(grammarType ID .*)
|
||||
{
|
||||
System.out.println("gname = "+$ID.text);
|
||||
if ( !g.fileName.equals($ID.text) ) {
|
||||
ErrorManager.grammarError(ErrorType.FILE_AND_GRAMMAR_NAME_DIFFER,
|
||||
g, $ID.token, $ID.text, g.fileName);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ import org.antlr.runtime.tree.BufferedTreeNodeStream;
|
|||
import org.antlr.v4.Tool;
|
||||
import org.antlr.v4.parse.ASTVerifier;
|
||||
import org.antlr.v4.tool.ErrorManager;
|
||||
import org.antlr.v4.tool.ErrorType;
|
||||
import org.antlr.v4.tool.Grammar;
|
||||
|
||||
/** */
|
||||
|
@ -14,17 +13,17 @@ public class SemanticsPipeline {
|
|||
// VALIDATE AST STRUCTURE
|
||||
// use buffered node stream as we will look around in stream
|
||||
// to give good error messages.
|
||||
// TODO: send errors to buffer not stderr
|
||||
// TODO: send parse errors to buffer not stderr
|
||||
BufferedTreeNodeStream nodes = new BufferedTreeNodeStream(Tool.astAdaptor,g.ast);
|
||||
ASTVerifier walker = new ASTVerifier(nodes);
|
||||
try {walker.grammarSpec();}
|
||||
catch (RecognitionException re) {
|
||||
ErrorManager.error(ErrorType.BAD_AST_STRUCTURE, re.toString());
|
||||
ErrorManager.internalError("bad grammar AST structure", re);
|
||||
}
|
||||
|
||||
// DO BASIC / EASY SEMANTIC CHECKS
|
||||
nodes.reset();
|
||||
BasicSemanticsChecker basics = new BasicSemanticsChecker(nodes);
|
||||
BasicSemanticsChecker basics = new BasicSemanticsChecker(nodes,g);
|
||||
basics.downup(g.ast);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
package org.antlr.v4.tool;
|
||||
|
||||
import org.antlr.runtime.CommonToken;
|
||||
import org.antlr.runtime.tree.CommonTree;
|
||||
import org.stringtemplate.ST;
|
||||
import org.stringtemplate.STGroup;
|
||||
import org.antlr.Tool;
|
||||
import org.antlr.runtime.Token;
|
||||
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.lang.reflect.Field;
|
||||
import java.net.URL;
|
||||
import java.util.Locale;
|
||||
|
||||
/** Defines all the errors ANTLR can generator for both the tool and for
|
||||
|
@ -53,11 +57,6 @@ public class ErrorManager {
|
|||
private static Locale locale;
|
||||
private static String formatName;
|
||||
|
||||
/** From a msgID how can I get the name of the template that describes
|
||||
* the error or warning?
|
||||
*/
|
||||
private static String[] idToMessageTemplateName = new String[ErrorType.values().length];
|
||||
|
||||
static ANTLRErrorListener theDefaultErrorListener = new ANTLRErrorListener() {
|
||||
public void info(String msg) {
|
||||
if (formatWantsSingleLineMessage()) {
|
||||
|
@ -83,6 +82,44 @@ public class ErrorManager {
|
|||
}
|
||||
};
|
||||
|
||||
static ErrorBuffer initSTListener = new ErrorBuffer();
|
||||
|
||||
static 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 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/";
|
||||
|
||||
// make sure that this class is ready to use after loading
|
||||
static {
|
||||
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 static ANTLRErrorListener getErrorListener() {
|
||||
return theDefaultErrorListener;
|
||||
}
|
||||
|
@ -103,7 +140,7 @@ public class ErrorManager {
|
|||
return format.getInstanceOf("wantsSingleLineMessage").toString().equals("true");
|
||||
}
|
||||
public static ST getMessageTemplate(ErrorType etype) {
|
||||
String msgName = idToMessageTemplateName[etype.ordinal()];
|
||||
String msgName = etype.toString();
|
||||
return messages.getInstanceOf(msgName);
|
||||
}
|
||||
|
||||
|
@ -117,24 +154,24 @@ public class ErrorManager {
|
|||
public static void internalError(String error, Throwable e) {
|
||||
StackTraceElement location = getLastNonErrorManagerCodeLocation(e);
|
||||
String msg = "Exception "+e+"@"+location+": "+error;
|
||||
theDefaultErrorListener.error(new ToolMessage(ErrorType.INTERNAL_ERROR, msg));
|
||||
System.err.println("internal error: "+msg);
|
||||
}
|
||||
|
||||
public static void internalError(String error) {
|
||||
StackTraceElement location =
|
||||
getLastNonErrorManagerCodeLocation(new Exception());
|
||||
String msg = location+": "+error;
|
||||
theDefaultErrorListener.error(new ToolMessage(ErrorType.INTERNAL_ERROR, msg));
|
||||
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 static void error(ErrorType errorType, Object... args) {
|
||||
public static void toolError(ErrorType errorType, Object... args) {
|
||||
theDefaultErrorListener.error(new ToolMessage(errorType, args));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -143,9 +180,9 @@ public class ErrorManager {
|
|||
*
|
||||
* @param errorType The Message Descriptor
|
||||
* @param args The arguments to pass to the StringTemplate
|
||||
*/
|
||||
public static void error(ErrorType errorType, int line, int column, int absOffset, int endLine, int endColumn, int endAbsOffset, Object... args) {
|
||||
public static void toolError(ErrorType errorType, int line, int column, int absOffset, int endLine, int endColumn, int endAbsOffset, Object... args) {
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Raise a predefined message with some number of paramters for the StringTemplate, for which there is a CommonToken
|
||||
|
@ -153,20 +190,25 @@ public class ErrorManager {
|
|||
* @param errorType The message descriptor.
|
||||
* @param t The token that contains our location information
|
||||
* @param args The varargs array of values that will be set in the StrngTemplate as arg0, arg1, ... argn
|
||||
*/
|
||||
public static void error(ErrorType errorType, CommonToken t, Object... args) {
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Construct a message when we have a node stream and AST node that we can extract location
|
||||
* from and possbily some arguments for the StringTemplate that will construct this message.
|
||||
*
|
||||
* @param errorType The message descriptor
|
||||
* @param node The node that gives us the information we need
|
||||
* @param args The varargs array of values that will be set in the StrngTemplate as arg0, arg1, ... argn
|
||||
*/
|
||||
public static void error(ErrorType errorType, CommonTree node, Object... args) {
|
||||
}
|
||||
*/
|
||||
|
||||
public static void grammarError(ErrorType etype,
|
||||
Grammar g,
|
||||
Token token,
|
||||
Object... args)
|
||||
{
|
||||
Message msg = new GrammarSemanticsMessage(etype,g,token,args);
|
||||
theDefaultErrorListener.error(msg);
|
||||
}
|
||||
|
||||
/** Process a new message by sending it on to the error listener associated with the current thread
|
||||
* and recording any information we need in the error state for the current thread.
|
||||
|
@ -194,35 +236,88 @@ public class ErrorManager {
|
|||
|
||||
// S U P P O R T C O D E
|
||||
|
||||
protected static boolean initIdToMessageNameMapping() {
|
||||
// make sure a message exists, even if it's just to indicate a problem
|
||||
for (int i = 0; i < idToMessageTemplateName.length; i++) {
|
||||
idToMessageTemplateName[i] = "INVALID MESSAGE ID: "+i;
|
||||
/** 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 static void setLocale(Locale locale) {
|
||||
ErrorManager.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);
|
||||
}
|
||||
// get list of fields and use it to fill in idToMessageTemplateName mapping
|
||||
Field[] fields = ErrorManager.class.getFields();
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
Field f = fields[i];
|
||||
String fieldName = f.getName();
|
||||
if ( !fieldName.startsWith("MSG_") ) {
|
||||
continue;
|
||||
}
|
||||
String templateName =
|
||||
fieldName.substring("MSG_".length(),fieldName.length());
|
||||
int msgID = 0;
|
||||
try {
|
||||
// get the constant value from this class object
|
||||
msgID = f.getInt(ErrorManager.class);
|
||||
}
|
||||
catch (IllegalAccessException iae) {
|
||||
System.err.println("cannot get const value for "+f.getName());
|
||||
continue;
|
||||
}
|
||||
if ( fieldName.startsWith("MSG_") ) {
|
||||
idToMessageTemplateName[msgID] = templateName;
|
||||
}
|
||||
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 static void setFormat(String formatName) {
|
||||
ErrorManager.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
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Use reflection to find list of MSG_ fields and then verify a
|
||||
|
@ -230,18 +325,13 @@ public class ErrorManager {
|
|||
*/
|
||||
protected static boolean verifyMessages() {
|
||||
boolean ok = true;
|
||||
Field[] fields = ErrorManager.class.getFields();
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
Field f = fields[i];
|
||||
String fieldName = f.getName();
|
||||
String templateName =
|
||||
fieldName.substring("MSG_".length(),fieldName.length());
|
||||
if ( fieldName.startsWith("MSG_") ) {
|
||||
if ( !messages.isDefined(templateName) ) {
|
||||
System.err.println("Message "+templateName+" in locale "+
|
||||
locale+" not found");
|
||||
ok = false;
|
||||
}
|
||||
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
|
||||
|
@ -287,6 +377,8 @@ public class ErrorManager {
|
|||
}
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,6 @@ public enum ErrorType {
|
|||
ERROR_CREATING_ARTIFICIAL_RULE(ErrorSeverity.ERROR, true, true),
|
||||
TOKENS_FILE_SYNTAX_ERROR(ErrorSeverity.ERROR, true, true),
|
||||
CANNOT_GEN_DOT_FILE(ErrorSeverity.ERROR, true, true),
|
||||
BAD_AST_STRUCTURE(ErrorSeverity.ERROR, true, true),
|
||||
|
||||
// Code generation errors
|
||||
MISSING_CODE_GEN_TEMPLATES(ErrorSeverity.ERROR, false, true),
|
||||
|
@ -125,7 +124,7 @@ public enum ErrorType {
|
|||
WILDCARD_AS_ROOT(ErrorSeverity.ERROR, true, true),
|
||||
CONFLICTING_OPTION_IN_TREE_FILTER(ErrorSeverity.ERROR, true, true),
|
||||
/** Documentation comment is unterminated */
|
||||
UNTERMINATED_DOC_COMMENT(ErrorSeverity.ERROR, true, true),
|
||||
//UNTERMINATED_DOC_COMMENT(ErrorSeverity.ERROR, true, true),
|
||||
|
||||
// Dependency sorting errors
|
||||
//
|
||||
|
@ -135,33 +134,33 @@ public enum ErrorType {
|
|||
// 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),
|
||||
// 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),
|
||||
|
||||
;
|
||||
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
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 Message {
|
||||
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 ) file = g.fileName;
|
||||
this.offendingToken = offendingToken;
|
||||
if ( offendingToken!=null ) {
|
||||
line = offendingToken.getLine();
|
||||
column = offendingToken.getCharPositionInLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,19 +1,12 @@
|
|||
package org.antlr.v4.tool;
|
||||
|
||||
import org.stringtemplate.ST;
|
||||
import org.stringtemplate.v4.ST;
|
||||
|
||||
/** */
|
||||
public class Message {
|
||||
// msgST is the actual text of the message
|
||||
public ST msgST;
|
||||
// these are for supporting different output formats
|
||||
public ST locationST;
|
||||
public ST reportST;
|
||||
public ST messageFormatST;
|
||||
|
||||
public ErrorType errorType;
|
||||
public Object[] args;
|
||||
public Throwable e;
|
||||
|
||||
// used for location template
|
||||
public String file;
|
||||
public int line = -1;
|
||||
|
@ -40,19 +33,16 @@ public class Message {
|
|||
* a Message.
|
||||
*/
|
||||
public ST getMessageTemplate() {
|
||||
return ErrorManager.getMessageTemplate(errorType);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
// setup the location
|
||||
locationST = ErrorManager.getLocationFormat();
|
||||
reportST = ErrorManager.getReportFormat();
|
||||
messageFormatST = ErrorManager.getMessageFormat();
|
||||
ST messageST = getMessageTemplate();
|
||||
ST messageST = ErrorManager.getMessageTemplate(errorType);
|
||||
ST locationST = ErrorManager.getLocationFormat();
|
||||
ST reportST = ErrorManager.getReportFormat();
|
||||
ST messageFormatST = ErrorManager.getMessageFormat();
|
||||
|
||||
if ( args!=null ) { // fill in arg1, arg2, ...
|
||||
for (int i=0; i<args.length; i++) {
|
||||
messageST.add("args"+(i+1), args[i]);
|
||||
String attr = "arg";
|
||||
if ( i>0 ) attr += i + 1;
|
||||
messageST.add(attr, args[i]);
|
||||
}
|
||||
}
|
||||
if ( e!=null ) {
|
||||
|
@ -82,8 +72,10 @@ public class Message {
|
|||
}
|
||||
reportST.add("message", messageFormatST);
|
||||
reportST.add("type", errorType.getSeverity());
|
||||
|
||||
return reportST.toString();
|
||||
return messageST;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getMessageTemplate().render();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ import org.antlr.v4.tool.Message;
|
|||
import org.junit.Before;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.stringtemplate.ST;
|
||||
import org.stringtemplate.v4.ST;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
|
Loading…
Reference in New Issue