got basic test harness for grammar errors
[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6659]
This commit is contained in:
parent
6829fc9e47
commit
81bcfe56dc
|
@ -1,10 +1,14 @@
|
||||||
package org.antlr.v4;
|
package org.antlr.v4;
|
||||||
|
|
||||||
import org.antlr.runtime.*;
|
import org.antlr.runtime.*;
|
||||||
import org.antlr.runtime.tree.*;
|
import org.antlr.v4.parse.ANTLRLexer;
|
||||||
import org.antlr.v4.parse.*;
|
import org.antlr.v4.parse.ANTLRParser;
|
||||||
|
import org.antlr.v4.parse.GrammarASTAdaptor;
|
||||||
import org.antlr.v4.semantics.SemanticsPipeline;
|
import org.antlr.v4.semantics.SemanticsPipeline;
|
||||||
import org.antlr.v4.tool.*;
|
import org.antlr.v4.tool.ErrorManager;
|
||||||
|
import org.antlr.v4.tool.ErrorType;
|
||||||
|
import org.antlr.v4.tool.Grammar;
|
||||||
|
import org.antlr.v4.tool.GrammarRootAST;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -291,24 +295,34 @@ public class Tool {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Grammar load(String fileName) {
|
public Grammar load(String fileName) {
|
||||||
Grammar g = null;
|
ANTLRFileStream in = null;
|
||||||
try {
|
try {
|
||||||
ANTLRFileStream in = new ANTLRFileStream(fileName);
|
in = new ANTLRFileStream(fileName);
|
||||||
ANTLRLexer lexer = new ANTLRLexer(in);
|
|
||||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
|
||||||
ANTLRParser p = new ANTLRParser(tokens);
|
|
||||||
|
|
||||||
p.setTreeAdaptor(new GrammarASTAdaptor(in));
|
|
||||||
ParserRuleReturnScope r = p.grammarSpec();
|
|
||||||
GrammarRootAST t = (GrammarRootAST) r.getTree();
|
|
||||||
if ( internalOption_PrintGrammarTree ) System.out.println(t.toStringTree());
|
|
||||||
g = new Grammar(this, t);
|
|
||||||
g.fileName = fileName;
|
|
||||||
grammars.put(g.name, g);
|
|
||||||
}
|
}
|
||||||
catch (IOException ioe) {
|
catch (IOException ioe) {
|
||||||
ErrorManager.toolError(ErrorType.CANNOT_OPEN_FILE, fileName, ioe);
|
ErrorManager.toolError(ErrorType.CANNOT_OPEN_FILE, fileName, ioe);
|
||||||
}
|
}
|
||||||
|
Grammar g = load(in);
|
||||||
|
g.fileName = fileName;
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Grammar loadFromString(String grammar) {
|
||||||
|
Grammar g = load(new ANTLRStringStream(grammar));
|
||||||
|
g.fileName = "<string>";
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Grammar load(CharStream in) {
|
||||||
|
Grammar g = null;
|
||||||
|
try {
|
||||||
|
ANTLRLexer lexer = new ANTLRLexer(in);
|
||||||
|
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||||
|
ANTLRParser p = new ANTLRParser(tokens);
|
||||||
|
p.setTreeAdaptor(new GrammarASTAdaptor(in));
|
||||||
|
ParserRuleReturnScope r = p.grammarSpec();
|
||||||
|
g = new Grammar(this, (GrammarRootAST)r.getTree());
|
||||||
|
}
|
||||||
catch (RecognitionException re) {
|
catch (RecognitionException re) {
|
||||||
// TODO: do we gen errors now?
|
// TODO: do we gen errors now?
|
||||||
ErrorManager.internalError("can't generate this message at moment; antlr recovers");
|
ErrorManager.internalError("can't generate this message at moment; antlr recovers");
|
||||||
|
@ -319,7 +333,9 @@ public class Tool {
|
||||||
public void process() {
|
public void process() {
|
||||||
// testing parser
|
// testing parser
|
||||||
Grammar g = load(grammarFileNames.get(0));
|
Grammar g = load(grammarFileNames.get(0));
|
||||||
|
grammars.put(g.name, g);
|
||||||
g.loadImportedGrammars();
|
g.loadImportedGrammars();
|
||||||
|
if ( g.ast!=null && internalOption_PrintGrammarTree ) System.out.println(g.ast.toStringTree());
|
||||||
//g.ast.inspect();
|
//g.ast.inspect();
|
||||||
SemanticsPipeline sem = new SemanticsPipeline();
|
SemanticsPipeline sem = new SemanticsPipeline();
|
||||||
sem.process(g);
|
sem.process(g);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package org.antlr.v4.misc;
|
package org.antlr.v4.misc;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
public class Utils {
|
public class Utils {
|
||||||
public static String stripFileExtension(String name) {
|
public static String stripFileExtension(String name) {
|
||||||
|
@ -8,4 +10,16 @@ public class Utils {
|
||||||
if ( lastDot<0 ) return name;
|
if ( lastDot<0 ) return name;
|
||||||
return name.substring(0, lastDot);
|
return name.substring(0, lastDot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Seriously: why isn't this built in to java? ugh!
|
||||||
|
public static String join(Iterator iter, String separator) {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
while ( iter.hasNext() ) {
|
||||||
|
buf.append(iter.next());
|
||||||
|
if ( iter.hasNext() ) {
|
||||||
|
buf.append(separator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// $ANTLR 3.2.1-SNAPSHOT Jan 26, 2010 15:12:28 ANTLRLexer.g 2010-02-03 11:08:45
|
// $ANTLR 3.2.1-SNAPSHOT Jan 26, 2010 15:12:28 ANTLRLexer.g 2010-02-03 15:37:27
|
||||||
|
|
||||||
/*
|
/*
|
||||||
[The "BSD licence"]
|
[The "BSD licence"]
|
||||||
|
@ -31,11 +31,6 @@ package org.antlr.v4.parse;
|
||||||
|
|
||||||
|
|
||||||
import org.antlr.runtime.*;
|
import org.antlr.runtime.*;
|
||||||
import java.util.Stack;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.HashMap;
|
|
||||||
/** Read in an ANTLR grammar and build an AST. Try not to do
|
/** Read in an ANTLR grammar and build an AST. Try not to do
|
||||||
* any actions, just build the tree.
|
* any actions, just build the tree.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// $ANTLR 3.2.1-SNAPSHOT Jan 26, 2010 15:12:28 ANTLRParser.g 2010-02-03 11:08:48
|
// $ANTLR 3.2.1-SNAPSHOT Jan 26, 2010 15:12:28 ANTLRParser.g 2010-02-03 15:37:30
|
||||||
|
|
||||||
/*
|
/*
|
||||||
[The "BSD licence"]
|
[The "BSD licence"]
|
||||||
|
@ -29,17 +29,12 @@
|
||||||
*/
|
*/
|
||||||
package org.antlr.v4.parse;
|
package org.antlr.v4.parse;
|
||||||
|
|
||||||
|
import org.antlr.runtime.*;
|
||||||
|
import org.antlr.runtime.tree.*;
|
||||||
import org.antlr.v4.tool.*;
|
import org.antlr.v4.tool.*;
|
||||||
|
|
||||||
|
|
||||||
import org.antlr.runtime.*;
|
|
||||||
import java.util.Stack;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Map;
|
import java.util.List;
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
import org.antlr.runtime.tree.*;
|
|
||||||
|
|
||||||
/** The definitive ANTLR v3 grammar to parse ANTLR v4 grammars.
|
/** The definitive ANTLR v3 grammar to parse ANTLR v4 grammars.
|
||||||
* The grammar builds ASTs that are sniffed by subsequent stages.
|
* The grammar builds ASTs that are sniffed by subsequent stages.
|
||||||
|
@ -288,7 +283,7 @@ public class ANTLRParser extends Parser {
|
||||||
|
|
||||||
|
|
||||||
// AST REWRITE
|
// AST REWRITE
|
||||||
// elements: id, rules, grammarType, prequelConstruct, DOC_COMMENT
|
// elements: id, DOC_COMMENT, rules, prequelConstruct, grammarType
|
||||||
// token labels:
|
// token labels:
|
||||||
// rule labels: retval
|
// rule labels: retval
|
||||||
// token list labels:
|
// token list labels:
|
||||||
|
@ -1127,7 +1122,7 @@ public class ANTLRParser extends Parser {
|
||||||
|
|
||||||
|
|
||||||
// AST REWRITE
|
// AST REWRITE
|
||||||
// elements: delegateGrammar, IMPORT
|
// elements: IMPORT, delegateGrammar
|
||||||
// token labels:
|
// token labels:
|
||||||
// rule labels: retval
|
// rule labels: retval
|
||||||
// token list labels:
|
// token list labels:
|
||||||
|
@ -1408,7 +1403,7 @@ public class ANTLRParser extends Parser {
|
||||||
|
|
||||||
|
|
||||||
// AST REWRITE
|
// AST REWRITE
|
||||||
// elements: TOKENS, tokenSpec
|
// elements: tokenSpec, TOKENS
|
||||||
// token labels:
|
// token labels:
|
||||||
// rule labels: retval
|
// rule labels: retval
|
||||||
// token list labels:
|
// token list labels:
|
||||||
|
@ -1563,7 +1558,7 @@ public class ANTLRParser extends Parser {
|
||||||
|
|
||||||
|
|
||||||
// AST REWRITE
|
// AST REWRITE
|
||||||
// elements: STRING_LITERAL, ASSIGN, id
|
// elements: id, STRING_LITERAL, ASSIGN
|
||||||
// token labels:
|
// token labels:
|
||||||
// rule labels: retval
|
// rule labels: retval
|
||||||
// token list labels:
|
// token list labels:
|
||||||
|
@ -1703,7 +1698,7 @@ public class ANTLRParser extends Parser {
|
||||||
|
|
||||||
|
|
||||||
// AST REWRITE
|
// AST REWRITE
|
||||||
// elements: ACTION, SCOPE, id
|
// elements: id, SCOPE, ACTION
|
||||||
// token labels:
|
// token labels:
|
||||||
// rule labels: retval
|
// rule labels: retval
|
||||||
// token list labels:
|
// token list labels:
|
||||||
|
@ -1857,7 +1852,7 @@ public class ANTLRParser extends Parser {
|
||||||
|
|
||||||
|
|
||||||
// AST REWRITE
|
// AST REWRITE
|
||||||
// elements: ACTION, AT, id, actionScopeName
|
// elements: actionScopeName, AT, ACTION, id
|
||||||
// token labels:
|
// token labels:
|
||||||
// rule labels: retval
|
// rule labels: retval
|
||||||
// token list labels:
|
// token list labels:
|
||||||
|
@ -2357,7 +2352,7 @@ public class ANTLRParser extends Parser {
|
||||||
|
|
||||||
|
|
||||||
// AST REWRITE
|
// AST REWRITE
|
||||||
// elements: ARG_ACTION, id, altListAsBlock, exceptionGroup, ruleReturns, DOC_COMMENT, rulePrequel, ruleModifiers
|
// elements: altListAsBlock, ruleReturns, ARG_ACTION, id, ruleModifiers, DOC_COMMENT, exceptionGroup, rulePrequel
|
||||||
// token labels:
|
// token labels:
|
||||||
// rule labels: retval
|
// rule labels: retval
|
||||||
// token list labels:
|
// token list labels:
|
||||||
|
@ -2583,7 +2578,7 @@ public class ANTLRParser extends Parser {
|
||||||
|
|
||||||
|
|
||||||
// AST REWRITE
|
// AST REWRITE
|
||||||
// elements: CATCH, ARG_ACTION, ACTION
|
// elements: ARG_ACTION, ACTION, CATCH
|
||||||
// token labels:
|
// token labels:
|
||||||
// rule labels: retval
|
// rule labels: retval
|
||||||
// token list labels:
|
// token list labels:
|
||||||
|
@ -2666,7 +2661,7 @@ public class ANTLRParser extends Parser {
|
||||||
|
|
||||||
|
|
||||||
// AST REWRITE
|
// AST REWRITE
|
||||||
// elements: FINALLY, ACTION
|
// elements: ACTION, FINALLY
|
||||||
// token labels:
|
// token labels:
|
||||||
// rule labels: retval
|
// rule labels: retval
|
||||||
// token list labels:
|
// token list labels:
|
||||||
|
@ -3288,7 +3283,7 @@ public class ANTLRParser extends Parser {
|
||||||
|
|
||||||
|
|
||||||
// AST REWRITE
|
// AST REWRITE
|
||||||
// elements: AT, id, ACTION
|
// elements: id, AT, ACTION
|
||||||
// token labels:
|
// token labels:
|
||||||
// rule labels: retval
|
// rule labels: retval
|
||||||
// token list labels:
|
// token list labels:
|
||||||
|
@ -3804,7 +3799,7 @@ public class ANTLRParser extends Parser {
|
||||||
|
|
||||||
|
|
||||||
// AST REWRITE
|
// AST REWRITE
|
||||||
// elements: elements, rewrite
|
// elements: rewrite, elements
|
||||||
// token labels:
|
// token labels:
|
||||||
// rule labels: retval
|
// rule labels: retval
|
||||||
// token list labels:
|
// token list labels:
|
||||||
|
@ -4948,7 +4943,7 @@ public class ANTLRParser extends Parser {
|
||||||
|
|
||||||
|
|
||||||
// AST REWRITE
|
// AST REWRITE
|
||||||
// elements: block, blockSuffixe
|
// elements: blockSuffixe, block
|
||||||
// token labels:
|
// token labels:
|
||||||
// rule labels: retval
|
// rule labels: retval
|
||||||
// token list labels:
|
// token list labels:
|
||||||
|
@ -5454,7 +5449,7 @@ public class ANTLRParser extends Parser {
|
||||||
|
|
||||||
|
|
||||||
// AST REWRITE
|
// AST REWRITE
|
||||||
// elements: id, ruleref, DOT
|
// elements: DOT, id, ruleref
|
||||||
// token labels:
|
// token labels:
|
||||||
// rule labels: retval
|
// rule labels: retval
|
||||||
// token list labels:
|
// token list labels:
|
||||||
|
@ -5512,7 +5507,7 @@ public class ANTLRParser extends Parser {
|
||||||
|
|
||||||
|
|
||||||
// AST REWRITE
|
// AST REWRITE
|
||||||
// elements: DOT, terminal, id
|
// elements: DOT, id, terminal
|
||||||
// token labels:
|
// token labels:
|
||||||
// rule labels: retval
|
// rule labels: retval
|
||||||
// token list labels:
|
// token list labels:
|
||||||
|
@ -5711,7 +5706,7 @@ public class ANTLRParser extends Parser {
|
||||||
|
|
||||||
|
|
||||||
// AST REWRITE
|
// AST REWRITE
|
||||||
// elements: notTerminal, NOT
|
// elements: NOT, notTerminal
|
||||||
// token labels:
|
// token labels:
|
||||||
// rule labels: retval
|
// rule labels: retval
|
||||||
// token list labels:
|
// token list labels:
|
||||||
|
@ -5754,7 +5749,7 @@ public class ANTLRParser extends Parser {
|
||||||
|
|
||||||
|
|
||||||
// AST REWRITE
|
// AST REWRITE
|
||||||
// elements: NOT, block
|
// elements: block, NOT
|
||||||
// token labels:
|
// token labels:
|
||||||
// rule labels: retval
|
// rule labels: retval
|
||||||
// token list labels:
|
// token list labels:
|
||||||
|
@ -6018,7 +6013,7 @@ public class ANTLRParser extends Parser {
|
||||||
|
|
||||||
|
|
||||||
// AST REWRITE
|
// AST REWRITE
|
||||||
// elements: altList, ACTION, optionsSpec, ra
|
// elements: ra, ACTION, altList, optionsSpec
|
||||||
// token labels:
|
// token labels:
|
||||||
// rule labels: retval
|
// rule labels: retval
|
||||||
// token list labels:
|
// token list labels:
|
||||||
|
@ -6199,7 +6194,7 @@ public class ANTLRParser extends Parser {
|
||||||
|
|
||||||
|
|
||||||
// AST REWRITE
|
// AST REWRITE
|
||||||
// elements: RULE_REF, ARG_ACTION, op
|
// elements: op, RULE_REF, ARG_ACTION
|
||||||
// token labels: op
|
// token labels: op
|
||||||
// rule labels: retval
|
// rule labels: retval
|
||||||
// token list labels:
|
// token list labels:
|
||||||
|
@ -6616,7 +6611,7 @@ public class ANTLRParser extends Parser {
|
||||||
|
|
||||||
|
|
||||||
// AST REWRITE
|
// AST REWRITE
|
||||||
// elements: elementOptions, STRING_LITERAL
|
// elements: STRING_LITERAL, elementOptions
|
||||||
// token labels:
|
// token labels:
|
||||||
// rule labels: retval
|
// rule labels: retval
|
||||||
// token list labels:
|
// token list labels:
|
||||||
|
@ -7226,7 +7221,7 @@ public class ANTLRParser extends Parser {
|
||||||
|
|
||||||
|
|
||||||
// AST REWRITE
|
// AST REWRITE
|
||||||
// elements: nakedRewrite, predicatedRewrite
|
// elements: predicatedRewrite, nakedRewrite
|
||||||
// token labels:
|
// token labels:
|
||||||
// rule labels: retval
|
// rule labels: retval
|
||||||
// token list labels:
|
// token list labels:
|
||||||
|
@ -7314,7 +7309,7 @@ public class ANTLRParser extends Parser {
|
||||||
|
|
||||||
|
|
||||||
// AST REWRITE
|
// AST REWRITE
|
||||||
// elements: rewriteAlt, SEMPRED, SEMPRED, rewriteAlt
|
// elements: rewriteAlt, SEMPRED, rewriteAlt, SEMPRED
|
||||||
// token labels:
|
// token labels:
|
||||||
// rule labels: retval
|
// rule labels: retval
|
||||||
// token list labels:
|
// token list labels:
|
||||||
|
@ -8066,7 +8061,7 @@ public class ANTLRParser extends Parser {
|
||||||
|
|
||||||
|
|
||||||
// AST REWRITE
|
// AST REWRITE
|
||||||
// elements: TOKEN_REF, ARG_ACTION
|
// elements: ARG_ACTION, TOKEN_REF
|
||||||
// token labels:
|
// token labels:
|
||||||
// rule labels: retval
|
// rule labels: retval
|
||||||
// token list labels:
|
// token list labels:
|
||||||
|
@ -8249,7 +8244,7 @@ public class ANTLRParser extends Parser {
|
||||||
|
|
||||||
|
|
||||||
// AST REWRITE
|
// AST REWRITE
|
||||||
// elements: rewriteTreeAlt, ebnfSuffix
|
// elements: ebnfSuffix, rewriteTreeAlt
|
||||||
// token labels:
|
// token labels:
|
||||||
// rule labels: retval
|
// rule labels: retval
|
||||||
// token list labels:
|
// token list labels:
|
||||||
|
@ -8386,7 +8381,7 @@ public class ANTLRParser extends Parser {
|
||||||
|
|
||||||
|
|
||||||
// AST REWRITE
|
// AST REWRITE
|
||||||
// elements: rewriteTreeElement, rewriteTreeAtom, TREE_BEGIN
|
// elements: TREE_BEGIN, rewriteTreeElement, rewriteTreeAtom
|
||||||
// token labels:
|
// token labels:
|
||||||
// rule labels: retval
|
// rule labels: retval
|
||||||
// token list labels:
|
// token list labels:
|
||||||
|
@ -8541,7 +8536,7 @@ public class ANTLRParser extends Parser {
|
||||||
|
|
||||||
|
|
||||||
// AST REWRITE
|
// AST REWRITE
|
||||||
// elements: str, rewriteTemplateArgs, TEMPLATE
|
// elements: str, TEMPLATE, rewriteTemplateArgs
|
||||||
// token labels: str
|
// token labels: str
|
||||||
// rule labels: retval
|
// rule labels: retval
|
||||||
// token list labels:
|
// token list labels:
|
||||||
|
@ -8802,7 +8797,7 @@ public class ANTLRParser extends Parser {
|
||||||
|
|
||||||
|
|
||||||
// AST REWRITE
|
// AST REWRITE
|
||||||
// elements: rewriteTemplateArgs, ACTION
|
// elements: ACTION, rewriteTemplateArgs
|
||||||
// token labels:
|
// token labels:
|
||||||
// rule labels: retval
|
// rule labels: retval
|
||||||
// token list labels:
|
// token list labels:
|
||||||
|
@ -9048,7 +9043,7 @@ public class ANTLRParser extends Parser {
|
||||||
|
|
||||||
|
|
||||||
// AST REWRITE
|
// AST REWRITE
|
||||||
// elements: ACTION, id
|
// elements: id, ACTION
|
||||||
// token labels:
|
// token labels:
|
||||||
// rule labels: retval
|
// rule labels: retval
|
||||||
// token list labels:
|
// token list labels:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// $ANTLR 3.2.1-SNAPSHOT Jan 26, 2010 15:12:28 ASTVerifier.g 2010-02-03 11:08:48
|
// $ANTLR 3.2.1-SNAPSHOT Jan 26, 2010 15:12:28 ASTVerifier.g 2010-02-03 15:37:30
|
||||||
|
|
||||||
/*
|
/*
|
||||||
[The "BSD license"]
|
[The "BSD license"]
|
||||||
|
@ -26,14 +26,15 @@
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package org.antlr.v4.parse;
|
package org.antlr.v4.parse;
|
||||||
import org.antlr.v4.tool.*;
|
|
||||||
import org.antlr.v4.runtime.tree.CommonTree; // use updated v4 one not v3
|
|
||||||
|
|
||||||
|
|
||||||
import org.antlr.runtime.*;
|
import org.antlr.runtime.*;
|
||||||
import org.antlr.runtime.tree.*;import java.util.Stack;
|
import org.antlr.runtime.tree.TreeNodeStream;
|
||||||
|
import org.antlr.runtime.tree.TreeParser;
|
||||||
|
import org.antlr.runtime.tree.TreeRuleReturnScope;
|
||||||
|
import org.antlr.v4.runtime.tree.CommonTree;
|
||||||
|
import org.antlr.v4.tool.GrammarAST;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
/** The definitive ANTLR v3 tree grammar to parse ANTLR v4 grammars.
|
/** The definitive ANTLR v3 tree grammar to parse ANTLR v4 grammars.
|
||||||
* Parses trees created in ANTLRParser.g.
|
* Parses trees created in ANTLRParser.g.
|
||||||
|
|
|
@ -2,17 +2,35 @@ package org.antlr.v4.semantics;
|
||||||
|
|
||||||
import org.antlr.misc.MultiMap;
|
import org.antlr.misc.MultiMap;
|
||||||
import org.antlr.runtime.Token;
|
import org.antlr.runtime.Token;
|
||||||
import org.antlr.tool.*;
|
|
||||||
import org.antlr.v4.misc.Utils;
|
import org.antlr.v4.misc.Utils;
|
||||||
import org.antlr.v4.parse.ANTLRParser;
|
import org.antlr.v4.parse.ANTLRParser;
|
||||||
import org.antlr.v4.tool.*;
|
import org.antlr.v4.tool.*;
|
||||||
import org.antlr.v4.tool.ErrorManager;
|
|
||||||
import org.antlr.v4.tool.Grammar;
|
|
||||||
import org.antlr.v4.tool.GrammarAST;
|
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/** No side-effects */
|
/** No side-effects; BasicSemanticTriggers.g invokes check rules for these:
|
||||||
|
*
|
||||||
|
* FILE_AND_GRAMMAR_NAME_DIFFER
|
||||||
|
* LEXER_RULES_NOT_ALLOWED
|
||||||
|
* PARSER_RULES_NOT_ALLOWED
|
||||||
|
* CANNOT_ALIAS_TOKENS_IN_LEXER
|
||||||
|
* ARGS_ON_TOKEN_REF
|
||||||
|
* ILLEGAL_OPTION
|
||||||
|
* REWRITE_OR_OP_WITH_NO_OUTPUT_OPTION
|
||||||
|
* NO_RULES
|
||||||
|
* REWRITE_FOR_MULTI_ELEMENT_ALT
|
||||||
|
* HETERO_ILLEGAL_IN_REWRITE_ALT
|
||||||
|
* AST_OP_WITH_NON_AST_OUTPUT_OPTION
|
||||||
|
* AST_OP_IN_ALT_WITH_REWRITE
|
||||||
|
* CONFLICTING_OPTION_IN_TREE_FILTER
|
||||||
|
* WILDCARD_AS_ROOT
|
||||||
|
* INVALID_IMPORT
|
||||||
|
* TOKEN_VOCAB_IN_DELEGATE
|
||||||
|
* IMPORT_NAME_CLASH
|
||||||
|
* REPEATED_PREQUEL
|
||||||
|
* TOKEN_NAMES_MUST_START_UPPER
|
||||||
|
*/
|
||||||
public class BasicSemanticChecks {
|
public class BasicSemanticChecks {
|
||||||
public static final Set legalLexerOptions =
|
public static final Set legalLexerOptions =
|
||||||
new HashSet() {
|
new HashSet() {
|
||||||
|
@ -99,7 +117,9 @@ public class BasicSemanticChecks {
|
||||||
// TODO: track errors?
|
// TODO: track errors?
|
||||||
|
|
||||||
protected static void checkGrammarName(Token nameToken) {
|
protected static void checkGrammarName(Token nameToken) {
|
||||||
String fileName = nameToken.getInputStream().getSourceName();
|
String fullyQualifiedName = nameToken.getInputStream().getSourceName();
|
||||||
|
File f = new File(fullyQualifiedName);
|
||||||
|
String fileName = f.getName();
|
||||||
if ( !Utils.stripFileExtension(fileName).equals(nameToken.getText()) ) {
|
if ( !Utils.stripFileExtension(fileName).equals(nameToken.getText()) ) {
|
||||||
ErrorManager.grammarError(ErrorType.FILE_AND_GRAMMAR_NAME_DIFFER,
|
ErrorManager.grammarError(ErrorType.FILE_AND_GRAMMAR_NAME_DIFFER,
|
||||||
fileName, nameToken, nameToken.getText(), fileName);
|
fileName, nameToken, nameToken.getText(), fileName);
|
||||||
|
@ -384,8 +404,4 @@ public class BasicSemanticChecks {
|
||||||
g, delegate);
|
g, delegate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void checkFOO(int gtype, Token ID) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// $ANTLR 3.2.1-SNAPSHOT Jan 26, 2010 15:12:28 BasicSemanticTriggers.g 2010-02-03 13:08:25
|
// $ANTLR 3.2.1-SNAPSHOT Jan 26, 2010 15:12:28 BasicSemanticTriggers.g 2010-02-03 15:37:39
|
||||||
|
|
||||||
/*
|
/*
|
||||||
[The "BSD license"]
|
[The "BSD license"]
|
||||||
|
@ -26,15 +26,14 @@
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package org.antlr.v4.semantics;
|
package org.antlr.v4.semantics;
|
||||||
import org.antlr.v4.tool.*;
|
|
||||||
|
|
||||||
|
|
||||||
import org.antlr.runtime.*;
|
import org.antlr.runtime.*;
|
||||||
import org.antlr.runtime.tree.*;import java.util.Stack;
|
import org.antlr.runtime.tree.TreeNodeStream;
|
||||||
import java.util.List;
|
import org.antlr.runtime.tree.TreeRuleReturnScope;
|
||||||
|
import org.antlr.v4.tool.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Map;
|
import java.util.List;
|
||||||
import java.util.HashMap;
|
|
||||||
/** Triggers for the basic semantics of the input. Side-effects:
|
/** Triggers for the basic semantics of the input. Side-effects:
|
||||||
* Set token, block, rule options in the tree. Load field option
|
* Set token, block, rule options in the tree. Load field option
|
||||||
* with grammar options. Only legal options are set.
|
* with grammar options. Only legal options are set.
|
||||||
|
|
|
@ -1,18 +1,11 @@
|
||||||
package org.antlr.v4.semantics;
|
package org.antlr.v4.semantics;
|
||||||
|
|
||||||
import org.antlr.runtime.RecognitionException;
|
import org.antlr.runtime.RecognitionException;
|
||||||
import org.antlr.runtime.Token;
|
|
||||||
import org.antlr.runtime.tree.BufferedTreeNodeStream;
|
import org.antlr.runtime.tree.BufferedTreeNodeStream;
|
||||||
import org.antlr.runtime.tree.TreeVisitor;
|
|
||||||
import org.antlr.runtime.tree.TreeVisitorAction;
|
|
||||||
import org.antlr.v4.Tool;
|
|
||||||
import org.antlr.v4.parse.ANTLRParser;
|
|
||||||
import org.antlr.v4.parse.ASTVerifier;
|
import org.antlr.v4.parse.ASTVerifier;
|
||||||
import org.antlr.v4.parse.GrammarASTAdaptor;
|
import org.antlr.v4.parse.GrammarASTAdaptor;
|
||||||
import org.antlr.v4.tool.ErrorManager;
|
import org.antlr.v4.tool.ErrorManager;
|
||||||
import org.antlr.v4.tool.ErrorType;
|
|
||||||
import org.antlr.v4.tool.Grammar;
|
import org.antlr.v4.tool.Grammar;
|
||||||
import org.antlr.v4.tool.GrammarASTWithOptions;
|
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
public class SemanticsPipeline {
|
public class SemanticsPipeline {
|
||||||
|
@ -35,13 +28,17 @@ public class SemanticsPipeline {
|
||||||
BasicSemanticTriggers basics = new BasicSemanticTriggers(nodes,g);
|
BasicSemanticTriggers basics = new BasicSemanticTriggers(nodes,g);
|
||||||
basics.downup(g.ast);
|
basics.downup(g.ast);
|
||||||
|
|
||||||
// NOW DO DELEGATES (IF ANY)
|
// NOW DO BASIC / EASY SEMANTIC CHECKS FOR DELEGATES (IF ANY)
|
||||||
if ( g.getImportedGrammars()!=null ) {
|
if ( g.getImportedGrammars()!=null ) {
|
||||||
for (Grammar d : g.getImportedGrammars()) {
|
for (Grammar d : g.getImportedGrammars()) {
|
||||||
process(d);
|
process(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DEFINE SYMBOLS
|
||||||
|
|
||||||
|
// ASSIGN TOKEN TYPES
|
||||||
|
|
||||||
/* dump options
|
/* dump options
|
||||||
TreeVisitor v = new TreeVisitor(adaptor);
|
TreeVisitor v = new TreeVisitor(adaptor);
|
||||||
v.visit(g.ast,
|
v.visit(g.ast,
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.antlr.v4.tool;
|
package org.antlr.v4.tool;
|
||||||
|
|
||||||
import org.antlr.Tool;
|
|
||||||
import org.antlr.runtime.Token;
|
import org.antlr.runtime.Token;
|
||||||
import org.stringtemplate.v4.ST;
|
import org.stringtemplate.v4.ST;
|
||||||
import org.stringtemplate.v4.STErrorListener;
|
import org.stringtemplate.v4.STErrorListener;
|
||||||
|
@ -57,10 +56,6 @@ public class ErrorManager {
|
||||||
private static Locale locale;
|
private static Locale locale;
|
||||||
private static String formatName;
|
private static String formatName;
|
||||||
|
|
||||||
// TODO: make thread local to hold this state
|
|
||||||
public static int errors;
|
|
||||||
public static int warnings;
|
|
||||||
|
|
||||||
static ANTLRErrorListener theDefaultErrorListener = new ANTLRErrorListener() {
|
static ANTLRErrorListener theDefaultErrorListener = new ANTLRErrorListener() {
|
||||||
public void info(String msg) {
|
public void info(String msg) {
|
||||||
if (formatWantsSingleLineMessage()) {
|
if (formatWantsSingleLineMessage()) {
|
||||||
|
@ -109,8 +104,18 @@ public class ErrorManager {
|
||||||
public static final String FORMATS_DIR = "org/antlr/v4/tool/templates/messages/formats/";
|
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 static final String MESSAGES_DIR = "org/antlr/v4/tool/templates/messages/languages/";
|
||||||
|
|
||||||
|
private static class ErrorState {
|
||||||
|
public ANTLRErrorListener listener;
|
||||||
|
public int errors;
|
||||||
|
public int warnings;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ThreadLocal<ErrorState> state = new ThreadLocal<ErrorState>();
|
||||||
|
|
||||||
// make sure that this class is ready to use after loading
|
// make sure that this class is ready to use after loading
|
||||||
static {
|
static {
|
||||||
|
state.set(new ErrorState());
|
||||||
|
setErrorListener(theDefaultErrorListener);
|
||||||
org.stringtemplate.v4.misc.ErrorManager.setErrorListener(initSTListener);
|
org.stringtemplate.v4.misc.ErrorManager.setErrorListener(initSTListener);
|
||||||
// it is inefficient to set the default locale here if another
|
// it is inefficient to set the default locale here if another
|
||||||
// piece of code is going to set the locale, but that would
|
// piece of code is going to set the locale, but that would
|
||||||
|
@ -123,9 +128,11 @@ public class ErrorManager {
|
||||||
setFormat("antlr");
|
setFormat("antlr");
|
||||||
org.stringtemplate.v4.misc.ErrorManager.setErrorListener(theDefaultSTListener);
|
org.stringtemplate.v4.misc.ErrorManager.setErrorListener(theDefaultSTListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static ANTLRErrorListener getErrorListener() {
|
public static ANTLRErrorListener getErrorListener() {
|
||||||
return theDefaultErrorListener;
|
return state.get().listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return a StringTemplate that refers to the current format used for
|
/** Return a StringTemplate that refers to the current format used for
|
||||||
|
@ -160,14 +167,14 @@ public class ErrorManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void internalError(String error, Throwable e) {
|
public static void internalError(String error, Throwable e) {
|
||||||
errors++;
|
state.get().errors++;
|
||||||
StackTraceElement location = getLastNonErrorManagerCodeLocation(e);
|
StackTraceElement location = getLastNonErrorManagerCodeLocation(e);
|
||||||
String msg = "Exception "+e+"@"+location+": "+error;
|
String msg = "Exception "+e+"@"+location+": "+error;
|
||||||
System.err.println("internal error: "+msg);
|
System.err.println("internal error: "+msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void internalError(String error) {
|
public static void internalError(String error) {
|
||||||
errors++;
|
state.get().errors++;
|
||||||
StackTraceElement location =
|
StackTraceElement location =
|
||||||
getLastNonErrorManagerCodeLocation(new Exception());
|
getLastNonErrorManagerCodeLocation(new Exception());
|
||||||
String msg = location+": "+error;
|
String msg = location+": "+error;
|
||||||
|
@ -181,8 +188,8 @@ public class ErrorManager {
|
||||||
* @param args The arguments to pass to the StringTemplate
|
* @param args The arguments to pass to the StringTemplate
|
||||||
*/
|
*/
|
||||||
public static void toolError(ErrorType errorType, Object... args) {
|
public static void toolError(ErrorType errorType, Object... args) {
|
||||||
errors++;
|
state.get().errors++;
|
||||||
theDefaultErrorListener.error(new ToolMessage(errorType, args));
|
state.get().listener.error(new ToolMessage(errorType, args));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -217,9 +224,9 @@ public class ErrorManager {
|
||||||
Token token,
|
Token token,
|
||||||
Object... args)
|
Object... args)
|
||||||
{
|
{
|
||||||
errors++;
|
state.get().errors++;
|
||||||
Message msg = new GrammarSemanticsMessage(etype,g,token,args);
|
Message msg = new GrammarSemanticsMessage(etype,g,token,args);
|
||||||
theDefaultErrorListener.error(msg);
|
state.get().listener.error(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void grammarError(ErrorType etype,
|
public static void grammarError(ErrorType etype,
|
||||||
|
@ -227,9 +234,9 @@ public class ErrorManager {
|
||||||
Token token,
|
Token token,
|
||||||
Object... args)
|
Object... args)
|
||||||
{
|
{
|
||||||
errors++;
|
state.get().errors++;
|
||||||
Message msg = new GrammarSemanticsMessage(etype,fileName,token,args);
|
Message msg = new GrammarSemanticsMessage(etype,fileName,token,args);
|
||||||
theDefaultErrorListener.error(msg);
|
state.get().listener.error(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void grammarWarning(ErrorType etype,
|
public static void grammarWarning(ErrorType etype,
|
||||||
|
@ -237,9 +244,9 @@ public class ErrorManager {
|
||||||
Token token,
|
Token token,
|
||||||
Object... args)
|
Object... args)
|
||||||
{
|
{
|
||||||
warnings++;
|
state.get().warnings++;
|
||||||
Message msg = new GrammarSemanticsMessage(etype,fileName,token,args);
|
Message msg = new GrammarSemanticsMessage(etype,fileName,token,args);
|
||||||
theDefaultErrorListener.warning(msg);
|
state.get().listener.warning(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Process a new message by sending it on to the error listener associated with the current thread
|
/** Process a new message by sending it on to the error listener associated with the current thread
|
||||||
|
@ -249,7 +256,7 @@ public class ErrorManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getNumErrors() {
|
public static int getNumErrors() {
|
||||||
return errors;
|
return state.get().errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return first non ErrorManager code location for generating messages */
|
/** Return first non ErrorManager code location for generating messages */
|
||||||
|
@ -266,6 +273,17 @@ public class ErrorManager {
|
||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** In general, you'll want all errors to go to a single spot.
|
||||||
|
* However, in a GUI, you might have two frames up with two
|
||||||
|
* different grammars. Two threads might launch to process the
|
||||||
|
* grammars--you would want errors to go to different objects
|
||||||
|
* depending on the thread. I store a single listener per
|
||||||
|
* thread.
|
||||||
|
*/
|
||||||
|
public static void setErrorListener(ANTLRErrorListener l) {
|
||||||
|
state.get().listener = l;
|
||||||
|
}
|
||||||
|
|
||||||
// S U P P O R T C O D E
|
// S U P P O R T C O D E
|
||||||
|
|
||||||
/** We really only need a single locale for entire running ANTLR code
|
/** We really only need a single locale for entire running ANTLR code
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
package org.antlr.v4.tool;
|
package org.antlr.v4.tool;
|
||||||
|
|
||||||
import org.antlr.runtime.*;
|
import org.antlr.runtime.ANTLRStringStream;
|
||||||
|
import org.antlr.runtime.CommonTokenStream;
|
||||||
|
import org.antlr.runtime.ParserRuleReturnScope;
|
||||||
|
import org.antlr.runtime.RecognitionException;
|
||||||
import org.antlr.v4.Tool;
|
import org.antlr.v4.Tool;
|
||||||
import org.antlr.v4.parse.ANTLRLexer;
|
import org.antlr.v4.parse.ANTLRLexer;
|
||||||
import org.antlr.v4.parse.ANTLRParser;
|
import org.antlr.v4.parse.ANTLRParser;
|
||||||
|
import org.antlr.v4.parse.GrammarASTAdaptor;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
@ -41,15 +45,18 @@ public class Grammar {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** For testing */
|
/** For testing */
|
||||||
public Grammar(String grammarText) throws RecognitionException {
|
public Grammar(String fileName, String grammarText) throws RecognitionException {
|
||||||
this.text = grammarText;
|
this.text = grammarText;
|
||||||
ANTLRStringStream in = new ANTLRStringStream(grammarText);
|
ANTLRStringStream in = new ANTLRStringStream(grammarText);
|
||||||
|
in.name = fileName;
|
||||||
ANTLRLexer lexer = new ANTLRLexer(in);
|
ANTLRLexer lexer = new ANTLRLexer(in);
|
||||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||||
ANTLRParser p = new ANTLRParser(tokens);
|
ANTLRParser p = new ANTLRParser(tokens);
|
||||||
|
p.setTreeAdaptor(new GrammarASTAdaptor(in));
|
||||||
ParserRuleReturnScope r = p.grammarSpec();
|
ParserRuleReturnScope r = p.grammarSpec();
|
||||||
ast = (GrammarRootAST) r.getTree();
|
ast = (GrammarRootAST)r.getTree();
|
||||||
System.out.println(ast.toStringTree());
|
this.name = ((GrammarAST)ast.getChild(0)).getText();
|
||||||
|
this.fileName = fileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadImportedGrammars() {
|
public void loadImportedGrammars() {
|
||||||
|
|
|
@ -27,17 +27,19 @@
|
||||||
*/
|
*/
|
||||||
package org.antlr.v4.test;
|
package org.antlr.v4.test;
|
||||||
|
|
||||||
import org.antlr.tool.ANTLRErrorListener;
|
import org.antlr.v4.misc.Utils;
|
||||||
import org.antlr.tool.Message;
|
import org.antlr.v4.tool.ANTLRErrorListener;
|
||||||
import org.antlr.tool.ToolMessage;
|
import org.antlr.v4.tool.Message;
|
||||||
|
import org.antlr.v4.tool.ToolMessage;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.LinkedList;
|
|
||||||
|
|
||||||
public class ErrorQueue implements ANTLRErrorListener {
|
public class ErrorQueue implements ANTLRErrorListener {
|
||||||
List infos = new LinkedList();
|
public List<String> infos = new ArrayList<String>();
|
||||||
List errors = new LinkedList();
|
public List<Message> errors = new ArrayList<Message>();
|
||||||
List warnings = new LinkedList();
|
public List<Message> warnings = new ArrayList<Message>();
|
||||||
|
public List<Message> all = new ArrayList<Message>();
|
||||||
|
|
||||||
public void info(String msg) {
|
public void info(String msg) {
|
||||||
infos.add(msg);
|
infos.add(msg);
|
||||||
|
@ -45,24 +47,23 @@ public class ErrorQueue implements ANTLRErrorListener {
|
||||||
|
|
||||||
public void error(Message msg) {
|
public void error(Message msg) {
|
||||||
errors.add(msg);
|
errors.add(msg);
|
||||||
|
all.add(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void warning(Message msg) {
|
public void warning(Message msg) {
|
||||||
warnings.add(msg);
|
warnings.add(msg);
|
||||||
|
all.add(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void error(ToolMessage msg) {
|
public void error(ToolMessage msg) {
|
||||||
errors.add(msg);
|
errors.add(msg);
|
||||||
|
all.add(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int size() {
|
public int size() {
|
||||||
return infos.size() + errors.size() + warnings.size();
|
return all.size() + infos.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() { return Utils.join(all.iterator(), "\n"); }
|
||||||
return "infos: "+infos+
|
|
||||||
"errors: "+errors+
|
|
||||||
"warnings: "+warnings;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
package org.antlr.v4.test;
|
||||||
|
|
||||||
|
import org.antlr.runtime.RecognitionException;
|
||||||
|
import org.antlr.v4.semantics.SemanticsPipeline;
|
||||||
|
import org.antlr.v4.tool.ErrorManager;
|
||||||
|
import org.antlr.v4.tool.Grammar;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class TestBasicSemanticErrors extends BaseTest {
|
||||||
|
public static class InOutPair { String in, out; }
|
||||||
|
static String[] pairs = {
|
||||||
|
// INPUT
|
||||||
|
"grammar A;\n" +
|
||||||
|
"\n" +
|
||||||
|
"options {\n" +
|
||||||
|
" output=template;\n" +
|
||||||
|
"}\n" +
|
||||||
|
"\n" +
|
||||||
|
"a : ID<Foo> -> ID ;\n" +
|
||||||
|
"\n" +
|
||||||
|
"b : A^ | ((B!|C)) -> ICK;",
|
||||||
|
// YIELDS
|
||||||
|
"error(68): A.g:7:7: alts with rewrites can't use heterogeneous types left of ->\n" +
|
||||||
|
"error(77): A.g:9:4: AST operator with non-AST output option: ^\n" +
|
||||||
|
"error(77): A.g:9:11: AST operator with non-AST output option: !\n" +
|
||||||
|
"error(78): A.g:9:11: rule b alt 2 uses rewrite syntax and also an AST operator",
|
||||||
|
|
||||||
|
// INPUT
|
||||||
|
"tree grammar B;\n" +
|
||||||
|
"options {\n" +
|
||||||
|
"\tfilter=true;\n" +
|
||||||
|
"\tbacktrack=false;\n" +
|
||||||
|
"\toutput=template;\n" +
|
||||||
|
"}\n" +
|
||||||
|
"\n" +
|
||||||
|
"a : A;\n" +
|
||||||
|
"\n" +
|
||||||
|
"b : ^(. A) ;",
|
||||||
|
// YIELDS
|
||||||
|
"error(79): B.g:10:6: Wildcard invalid as root; wildcard can itself be a tree\n" +
|
||||||
|
"error(80): B.g:1:5: option backtrack=false conflicts with tree grammar filter mode\n" +
|
||||||
|
"error(80): B.g:1:5: option output=template conflicts with tree grammar filter mode",
|
||||||
|
};
|
||||||
|
|
||||||
|
@Test public void testErrors() {
|
||||||
|
for (int i = 0; i < pairs.length; i+=2) {
|
||||||
|
String input = pairs[i];
|
||||||
|
String expect = pairs[i+1];
|
||||||
|
ErrorQueue equeue = new ErrorQueue();
|
||||||
|
ErrorManager.setErrorListener(equeue);
|
||||||
|
try {
|
||||||
|
String[] lines = input.split("\n");
|
||||||
|
int lastSpace = lines[0].lastIndexOf(' ');
|
||||||
|
int semi = lines[0].lastIndexOf(';');
|
||||||
|
String fileName = lines[0].substring(lastSpace+1, semi)+".g";
|
||||||
|
Grammar g = new Grammar(fileName, input);
|
||||||
|
g.loadImportedGrammars();
|
||||||
|
SemanticsPipeline sem = new SemanticsPipeline();
|
||||||
|
sem.process(g);
|
||||||
|
}
|
||||||
|
catch (RecognitionException re) {
|
||||||
|
re.printStackTrace(System.err);
|
||||||
|
}
|
||||||
|
String actual = equeue.toString();
|
||||||
|
assertEquals(expect,actual);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue