summaryrefslogtreecommitdiff
path: root/tool
diff options
context:
space:
mode:
Diffstat (limited to 'tool')
-rw-r--r--tool/pom.xml9
-rw-r--r--tool/resources/org/antlr/v4/tool/templates/codegen/CSharp/CSharp.stg41
-rw-r--r--tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg7
-rw-r--r--tool/resources/org/antlr/v4/tool/templates/codegen/JavaScript/JavaScript.stg15
-rw-r--r--tool/resources/org/antlr/v4/tool/templates/codegen/Python2/Python2.stg7
-rw-r--r--tool/resources/org/antlr/v4/tool/templates/codegen/Python3/Python3.stg7
-rw-r--r--tool/src/org/antlr/v4/automata/LexerATNFactory.java31
-rw-r--r--tool/src/org/antlr/v4/codegen/ActionTranslator.java6
-rw-r--r--tool/src/org/antlr/v4/codegen/target/CSharpTarget.java2
-rw-r--r--tool/src/org/antlr/v4/codegen/target/JavaScriptTarget.java2
-rw-r--r--tool/src/org/antlr/v4/codegen/target/Python2Target.java2
-rw-r--r--tool/src/org/antlr/v4/codegen/target/Python3Target.java2
-rw-r--r--tool/src/org/antlr/v4/gui/TestRig.java5
-rw-r--r--tool/src/org/antlr/v4/gui/TreeViewer.java8
-rw-r--r--tool/src/org/antlr/v4/semantics/BasicSemanticChecks.java10
-rw-r--r--tool/src/org/antlr/v4/semantics/SemanticPipeline.java7
-rw-r--r--tool/src/org/antlr/v4/semantics/SymbolChecks.java22
-rw-r--r--tool/src/org/antlr/v4/tool/ErrorType.java54
18 files changed, 184 insertions, 53 deletions
diff --git a/tool/pom.xml b/tool/pom.xml
index 0ae4fa8..d762947 100644
--- a/tool/pom.xml
+++ b/tool/pom.xml
@@ -3,7 +3,7 @@
<parent>
<groupId>org.antlr</groupId>
<artifactId>antlr4-master</artifactId>
- <version>4.5.1</version>
+ <version>4.5.2-1</version>
</parent>
<artifactId>antlr4</artifactId>
<name>ANTLR 4 Tool</name>
@@ -98,6 +98,13 @@
<phase>package</phase>
<configuration>
<dependencyReducedPomLocation>${project.build.directory}/dependency-reduced-pom.xml</dependencyReducedPomLocation>
+ <transformers>
+ <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+ <manifestEntries>
+ <Main-Class>org.antlr.v4.Tool</Main-Class>
+ </manifestEntries>
+ </transformer>
+ </transformers>
</configuration>
<goals>
<goal>shade</goal>
diff --git a/tool/resources/org/antlr/v4/tool/templates/codegen/CSharp/CSharp.stg b/tool/resources/org/antlr/v4/tool/templates/codegen/CSharp/CSharp.stg
index 81eb912..0617385 100644
--- a/tool/resources/org/antlr/v4/tool/templates/codegen/CSharp/CSharp.stg
+++ b/tool/resources/org/antlr/v4/tool/templates/codegen/CSharp/CSharp.stg
@@ -119,13 +119,23 @@ using ParserRuleContext = Antlr4.Runtime.ParserRuleContext;
public partial class <file.grammarName>BaseListener : I<file.grammarName>Listener {
<file.listenerNames:{lname |
/// \<summary>
-/// Enter a parse tree produced by \<see cref="<csIdentifier.(file.parserName)>.<csIdentifier.(lname)>"/>.
+<if(file.listenerLabelRuleNames.(lname))>
+/// Enter a parse tree produced by the \<c><lname>\</c>
+/// labeled alternative in \<see cref="<file.parserName>.<file.listenerLabelRuleNames.(lname)>"/>.
+<else>
+/// Enter a parse tree produced by \<see cref="<file.parserName>.<lname>"/>.
+<endif>
/// \<para>The default implementation does nothing.\</para>
/// \</summary>
/// \<param name="context">The parse tree.\</param>
public virtual void Enter<lname; format="cap">([NotNull] <csIdentifier.(file.parserName)>.<lname; format="cap">Context context) { \}
/// \<summary>
-/// Exit a parse tree produced by \<see cref="<csIdentifier.(file.parserName)>.<csIdentifier.(lname)>"/>.
+<if(file.listenerLabelRuleNames.(lname))>
+/// Exit a parse tree produced by the \<c><lname>\</c>
+/// labeled alternative in \<see cref="<file.parserName>.<file.listenerLabelRuleNames.(lname)>"/>.
+<else>
+/// Exit a parse tree produced by \<see cref="<file.parserName>.<lname>"/>.
+<endif>
/// \<para>The default implementation does nothing.\</para>
/// \</summary>
/// \<param name="context">The parse tree.\</param>
@@ -207,7 +217,12 @@ using ParserRuleContext = Antlr4.Runtime.ParserRuleContext;
public partial class <file.grammarName>BaseVisitor\<Result> : AbstractParseTreeVisitor\<Result>, I<file.grammarName>Visitor\<Result> {
<file.visitorNames:{lname |
/// \<summary>
-/// Visit a parse tree produced by \<see cref="<csIdentifier.(file.parserName)>.<csIdentifier.(lname)>"/>.
+<if(file.visitorLabelRuleNames.(lname))>
+/// Visit a parse tree produced by the \<c><lname>\</c>
+/// labeled alternative in \<see cref="<file.parserName>.<file.visitorLabelRuleNames.(lname)>"/>.
+<else>
+/// Visit a parse tree produced by \<see cref="<file.parserName>.<lname>"/>.
+<endif>
/// \<para>
/// The default implementation returns the result of calling \<see cref="AbstractParseTreeVisitor{Result\}.VisitChildren(IRuleNode)"/>
/// on \<paramref name="context"/>.
@@ -241,6 +256,8 @@ fileHeader(grammarFileName, ANTLRVersion) ::= <<
#pragma warning disable 0219
// Missing XML comment for publicly visible type or member '...'
#pragma warning disable 1591
+// Ambiguous reference in cref attribute
+#pragma warning disable 419
>>
@@ -520,7 +537,6 @@ CodeBlockForAlt(currentAltCodeBlock, locals, preamble, ops) ::= <<
LL1AltBlock(choice, preamble, alts, error) ::= <<
State = <choice.stateNumber>;
-<!ErrorHandler.sync(this);!>
<if(choice.label)><labelref(choice.label)> = TokenStream.Lt(1);<endif>
<preamble; separator="\n">
switch (TokenStream.La(1)) {
@@ -534,7 +550,6 @@ default:
LL1OptionalBlock(choice, alts, error) ::= <<
State = <choice.stateNumber>;
-<!ErrorHandler.sync(this);!>
switch (TokenStream.La(1)) {
<choice.altLook,alts:{look,alt| <cases(ttypes=look)>
<alt>
@@ -546,7 +561,6 @@ default:
LL1OptionalBlockSingleAlt(choice, expr, alts, preamble, error, followExpr) ::= <<
State = <choice.stateNumber>;
-<!ErrorHandler.sync(this);!>
<preamble; separator="\n">
if (<expr>) {
<alts; separator="\n">
@@ -582,7 +596,7 @@ do {
AltBlock(choice, preamble, alts, error) ::= <<
State = <choice.stateNumber>;
-<!ErrorHandler.sync(this);!>
+ErrorHandler.Sync(this);
<if(choice.label)><labelref(choice.label)> = TokenStream.Lt(1);<endif>
<preamble; separator="\n">
switch ( Interpreter.AdaptivePredict(TokenStream,<choice.decision>,Context) ) {
@@ -595,7 +609,7 @@ case <i>:
OptionalBlock(choice, alts, error) ::= <<
State = <choice.stateNumber>;
-<!ErrorHandler.sync(this);!>
+ErrorHandler.Sync(this);
switch ( Interpreter.AdaptivePredict(TokenStream,<choice.decision>,Context) ) {
<alts:{alt |
case <i><if(!choice.ast.greedy)>+1<endif>:
@@ -931,6 +945,7 @@ namespace <file.genPackage> {
<endif>
<namedActions.header>
using System;
+using System.Text;
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
@@ -986,8 +1001,14 @@ public partial class <csIdentifier.(lexer.name)> : <superClass; null="Lexer"> {
SerializedATN(model) ::= <<
-public static readonly string _serializedATN =
- "<model.serialized; wrap={"+<\n><\t>"}>";
+private static string _serializedATN = _serializeATN();
+private static string _serializeATN()
+{
+ StringBuilder sb = new StringBuilder();
+ sb.Append("<model.serialized; wrap={");<\n><\t>sb.Append("}>");
+ return sb.ToString();
+}
+
public static readonly ATN _ATN =
new ATNDeserializer().Deserialize(_serializedATN.ToCharArray());
>>
diff --git a/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg b/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg
index 5bec6c5..8bd429a 100644
--- a/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg
+++ b/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg
@@ -469,7 +469,6 @@ CodeBlockForAlt(currentAltCodeBlock, locals, preamble, ops) ::= <<
LL1AltBlock(choice, preamble, alts, error) ::= <<
setState(<choice.stateNumber>);
-<!_errHandler.sync(this);!>
<if(choice.label)><labelref(choice.label)> = _input.LT(1);<endif>
<preamble; separator="\n">
switch (_input.LA(1)) {
@@ -483,7 +482,6 @@ default:
LL1OptionalBlock(choice, alts, error) ::= <<
setState(<choice.stateNumber>);
-<!_errHandler.sync(this);!>
switch (_input.LA(1)) {
<choice.altLook,alts:{look,alt| <cases(ttypes=look)>
<alt>
@@ -495,7 +493,6 @@ default:
LL1OptionalBlockSingleAlt(choice, expr, alts, preamble, error, followExpr) ::= <<
setState(<choice.stateNumber>);
-<!_errHandler.sync(this);!>
<preamble; separator="\n">
if (<expr>) {
<alts; separator="\n">
@@ -531,7 +528,7 @@ do {
AltBlock(choice, preamble, alts, error) ::= <<
setState(<choice.stateNumber>);
-<!_errHandler.sync(this);!>
+_errHandler.sync(this);
<if(choice.label)><labelref(choice.label)> = _input.LT(1);<endif>
<preamble; separator="\n">
switch ( getInterpreter().adaptivePredict(_input,<choice.decision>,_ctx) ) {
@@ -544,7 +541,7 @@ case <i>:
OptionalBlock(choice, alts, error) ::= <<
setState(<choice.stateNumber>);
-<!_errHandler.sync(this);!>
+_errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,<choice.decision>,_ctx) ) {
<alts:{alt |
case <i><if(!choice.ast.greedy)>+1<endif>:
diff --git a/tool/resources/org/antlr/v4/tool/templates/codegen/JavaScript/JavaScript.stg b/tool/resources/org/antlr/v4/tool/templates/codegen/JavaScript/JavaScript.stg
index a9cfef1..b015c0b 100644
--- a/tool/resources/org/antlr/v4/tool/templates/codegen/JavaScript/JavaScript.stg
+++ b/tool/resources/org/antlr/v4/tool/templates/codegen/JavaScript/JavaScript.stg
@@ -134,9 +134,9 @@ var decisionsToDFA = atn.decisionToState.map( function(ds, index) { return new a
var sharedContextCache = new antlr4.PredictionContextCache();
-var literalNames = [ <parser.literalNames:{t | <t>}; null="'null'", separator=", ", wrap, anchor> ];
+var literalNames = [ <parser.literalNames:{t | <t>}; null="null", separator=", ", wrap, anchor> ];
-var symbolicNames = [ <parser.symbolicNames:{t | <t>}; null="'null'", separator=", ", wrap, anchor> ];
+var symbolicNames = [ <parser.symbolicNames:{t | <t>}; null="null", separator=", ", wrap, anchor> ];
var ruleNames = [ <parser.ruleNames:{r | "<r>"}; separator=", ", wrap, anchor> ];
@@ -340,7 +340,6 @@ CodeBlockForAlt(currentAltCodeBlock, locals, preamble, ops) ::= <<
LL1AltBlock(choice, preamble, alts, error) ::= <<
this.state = <choice.stateNumber>;
-<!_errHandler.sync(this);!>
<if(choice.label)><labelref(choice.label)> = this._input.LT(1);<endif>
<preamble; separator="\n">
switch(this._input.LA(1)) {
@@ -354,7 +353,6 @@ default:
LL1OptionalBlock(choice, alts, error) ::= <<
this.state = <choice.stateNumber>;
-<!_errHandler.sync(this);!>
switch (this._input.LA(1)) {
<choice.altLook,alts:{look,alt| <cases(ttypes=look)>
<alt>
@@ -366,7 +364,6 @@ default:
LL1OptionalBlockSingleAlt(choice, expr, alts, preamble, error, followExpr) ::= <<
this.state = <choice.stateNumber>;
-<!_errHandler.sync(this);!>
<preamble; separator="\n">
if(<expr>) {
<alts; separator="\n">
@@ -402,7 +399,7 @@ do {
AltBlock(choice, preamble, alts, error) ::= <<
this.state = <choice.stateNumber>;
-<!_errHandler.sync(this);!>
+this._errHandler.sync(this);
<if(choice.label)><labelref(choice.label)> = _input.LT(1)<endif>
<preamble; separator="\n">
var la_ = this._interp.adaptivePredict(this._input,<choice.decision>,this._ctx);
@@ -417,7 +414,7 @@ case <i>:
OptionalBlock(choice, alts, error) ::= <<
this.state = <choice.stateNumber>;
-<!_errHandler.sync(this);!>
+this._errHandler.sync(this);
var la_ = this._interp.adaptivePredict(this._input,<choice.decision>,this._ctx);
<alts:{alt |
if(la_===<i><if(!choice.ast.greedy)>+1<endif>) {
@@ -825,9 +822,9 @@ function <lexer.name>(input) {
<lexer.name>.modeNames = [ <lexer.modes:{m| "<m>"}; separator=", ", wrap, anchor> ];
-<lexer.name>.literalNames = [ <lexer.literalNames:{t | <t>}; null="'null'", separator=", ", wrap, anchor> ];
+<lexer.name>.literalNames = [ <lexer.literalNames:{t | <t>}; null="null", separator=", ", wrap, anchor> ];
-<lexer.name>.symbolicNames = [ <lexer.symbolicNames:{t | <t>}; null="'null'", separator=", ", wrap, anchor> ];
+<lexer.name>.symbolicNames = [ <lexer.symbolicNames:{t | <t>}; null="null", separator=", ", wrap, anchor> ];
<lexer.name>.ruleNames = [ <lexer.ruleNames:{r | "<r>"}; separator=", ", wrap, anchor> ];
diff --git a/tool/resources/org/antlr/v4/tool/templates/codegen/Python2/Python2.stg b/tool/resources/org/antlr/v4/tool/templates/codegen/Python2/Python2.stg
index b4e66eb..66d84e6 100644
--- a/tool/resources/org/antlr/v4/tool/templates/codegen/Python2/Python2.stg
+++ b/tool/resources/org/antlr/v4/tool/templates/codegen/Python2/Python2.stg
@@ -314,7 +314,6 @@ CodeBlockForAlt(currentAltCodeBlock, locals, preamble, ops) ::= <<
LL1AltBlock(choice, preamble, alts, error) ::= <<
self.state = <choice.stateNumber>
-<!_errHandler.sync(this);!>
<if(choice.label)><labelref(choice.label)> = _input.LT(1)<endif>
<preamble; separator="\n">
token = self._input.LA(1)
@@ -328,7 +327,6 @@ else:
LL1OptionalBlock(choice, alts, error) ::= <<
self.state = <choice.stateNumber>
-<!_errHandler.sync(this);!>
token = self._input.LA(1)
<choice.altLook,alts:{look,alt| <cases(ttypes=look)>
<alt>
@@ -339,7 +337,6 @@ else:
LL1OptionalBlockSingleAlt(choice, expr, alts, preamble, error, followExpr) ::= <<
self.state = <choice.stateNumber>
-<!_errHandler.sync(this);!>
<preamble; separator="\n">
if <expr>:
<alts; separator="\n">
@@ -378,7 +375,7 @@ while True:
AltBlock(choice, preamble, alts, error) ::= <<
self.state = <choice.stateNumber>
-<!_errHandler.sync(this);!>
+self._errHandler.sync(self);
<if(choice.label)><labelref(choice.label)> = _input.LT(1)<endif>
<preamble; separator="\n">
la_ = self._interp.adaptivePredict(self._input,<choice.decision>,self._ctx)
@@ -392,7 +389,7 @@ if la_ == <i>:
OptionalBlock(choice, alts, error) ::= <<
self.state = <choice.stateNumber>
-<!_errHandler.sync(this);!>
+self._errHandler.sync(self);
la_ = self._interp.adaptivePredict(self._input,<choice.decision>,self._ctx)
<alts:{alt |
if la_ == <i><if(!choice.ast.greedy)>+1<endif>:
diff --git a/tool/resources/org/antlr/v4/tool/templates/codegen/Python3/Python3.stg b/tool/resources/org/antlr/v4/tool/templates/codegen/Python3/Python3.stg
index 4ba1e38..515cf65 100644
--- a/tool/resources/org/antlr/v4/tool/templates/codegen/Python3/Python3.stg
+++ b/tool/resources/org/antlr/v4/tool/templates/codegen/Python3/Python3.stg
@@ -322,7 +322,6 @@ CodeBlockForAlt(currentAltCodeBlock, locals, preamble, ops) ::= <<
LL1AltBlock(choice, preamble, alts, error) ::= <<
self.state = <choice.stateNumber>
-<!_errHandler.sync(this);!>
<if(choice.label)><labelref(choice.label)> = _input.LT(1)<endif>
<preamble; separator="\n">
token = self._input.LA(1)
@@ -336,7 +335,6 @@ else:
LL1OptionalBlock(choice, alts, error) ::= <<
self.state = <choice.stateNumber>
-<!_errHandler.sync(this);!>
token = self._input.LA(1)
<choice.altLook,alts:{look,alt| <cases(ttypes=look)>
<alt>
@@ -347,7 +345,6 @@ else:
LL1OptionalBlockSingleAlt(choice, expr, alts, preamble, error, followExpr) ::= <<
self.state = <choice.stateNumber>
-<!_errHandler.sync(this);!>
<preamble; separator="\n">
if <expr>:
<alts; separator="\n">
@@ -386,7 +383,7 @@ while True:
AltBlock(choice, preamble, alts, error) ::= <<
self.state = <choice.stateNumber>
-<!_errHandler.sync(this);!>
+self._errHandler.sync(self);
<if(choice.label)><labelref(choice.label)> = _input.LT(1)<endif>
<preamble; separator="\n">
la_ = self._interp.adaptivePredict(self._input,<choice.decision>,self._ctx)
@@ -400,7 +397,7 @@ if la_ == <i>:
OptionalBlock(choice, alts, error) ::= <<
self.state = <choice.stateNumber>
-<!_errHandler.sync(this);!>
+self._errHandler.sync(self);
la_ = self._interp.adaptivePredict(self._input,<choice.decision>,self._ctx)
<alts:{alt |
if la_ == <i><if(!choice.ast.greedy)>+1<endif>:
diff --git a/tool/src/org/antlr/v4/automata/LexerATNFactory.java b/tool/src/org/antlr/v4/automata/LexerATNFactory.java
index 4feff0a..a5e80e4 100644
--- a/tool/src/org/antlr/v4/automata/LexerATNFactory.java
+++ b/tool/src/org/antlr/v4/automata/LexerATNFactory.java
@@ -83,7 +83,7 @@ public class LexerATNFactory extends ParserATNFactory {
* actions, but are required during code generation for creating
* {@link LexerAction} instances that are usable by a lexer interpreter.
*/
- protected static final Map<String, Integer> COMMON_CONSTANTS = new HashMap<String, Integer>();
+ public static final Map<String, Integer> COMMON_CONSTANTS = new HashMap<String, Integer>();
static {
COMMON_CONSTANTS.put("HIDDEN", Lexer.HIDDEN);
COMMON_CONSTANTS.put("DEFAULT_TOKEN_CHANNEL", Lexer.DEFAULT_TOKEN_CHANNEL);
@@ -112,6 +112,10 @@ public class LexerATNFactory extends ParserATNFactory {
codegenTemplates = gen.getTemplates();
}
+ public static Set<String> getCommonConstants() {
+ return COMMON_CONSTANTS.keySet();
+ }
+
@Override
public ATN createATN() {
// BUILD ALL START STATES (ONE PER MODE)
@@ -243,8 +247,8 @@ public class LexerATNFactory extends ParserATNFactory {
// fall back to standard action generation for the command
ST cmdST = codegenTemplates.getInstanceOf("Lexer" +
- CharSupport.capitalize(ID.getText())+
- "Command");
+ CharSupport.capitalize(ID.getText()) +
+ "Command");
if (cmdST == null) {
g.tool.errMgr.grammarError(ErrorType.INVALID_LEXER_COMMAND, g.fileName, ID.token, ID.getText());
return epsilon(ID);
@@ -407,6 +411,7 @@ public class LexerATNFactory extends ParserATNFactory {
}
else if ("mode".equals(command) && arg != null) {
String modeName = arg.getText();
+ checkMode(modeName, arg.token);
Integer mode = getConstantValue(modeName, arg.getToken());
if (mode == null) {
return null;
@@ -416,6 +421,7 @@ public class LexerATNFactory extends ParserATNFactory {
}
else if ("pushMode".equals(command) && arg != null) {
String modeName = arg.getText();
+ checkMode(modeName, arg.token);
Integer mode = getConstantValue(modeName, arg.getToken());
if (mode == null) {
return null;
@@ -425,6 +431,7 @@ public class LexerATNFactory extends ParserATNFactory {
}
else if ("type".equals(command) && arg != null) {
String typeName = arg.getText();
+ checkToken(typeName, arg.token);
Integer type = getConstantValue(typeName, arg.getToken());
if (type == null) {
return null;
@@ -434,6 +441,7 @@ public class LexerATNFactory extends ParserATNFactory {
}
else if ("channel".equals(command) && arg != null) {
String channelName = arg.getText();
+ checkChannel(channelName, arg.token);
Integer channel = getConstantValue(channelName, arg.getToken());
if (channel == null) {
return null;
@@ -446,6 +454,23 @@ public class LexerATNFactory extends ParserATNFactory {
}
}
+ protected void checkMode(String modeName, Token token) {
+ if (!modeName.equals("DEFAULT_MODE") && COMMON_CONSTANTS.containsKey(modeName)) {
+ g.tool.errMgr.grammarError(ErrorType.MODE_CONFLICTS_WITH_COMMON_CONSTANTS, g.fileName, token, token.getText());
+ }
+ }
+
+ protected void checkToken(String tokenName, Token token) {
+ if (!tokenName.equals("EOF") && COMMON_CONSTANTS.containsKey(tokenName)) {
+ g.tool.errMgr.grammarError(ErrorType.TOKEN_CONFLICTS_WITH_COMMON_CONSTANTS, g.fileName, token, token.getText());
+ }
+ }
+
+ protected void checkChannel(String channelName, Token token) {
+ if (!channelName.equals("HIDDEN") && !channelName.equals("DEFAULT_TOKEN_CHANNEL") && COMMON_CONSTANTS.containsKey(channelName)) {
+ g.tool.errMgr.grammarError(ErrorType.CHANNEL_CONFLICTS_WITH_COMMON_CONSTANTS, g.fileName, token, token.getText());
+ }
+ }
protected Integer getConstantValue(String name, Token token) {
if (name == null) {
diff --git a/tool/src/org/antlr/v4/codegen/ActionTranslator.java b/tool/src/org/antlr/v4/codegen/ActionTranslator.java
index 2a12e8e..f1e5452 100644
--- a/tool/src/org/antlr/v4/codegen/ActionTranslator.java
+++ b/tool/src/org/antlr/v4/codegen/ActionTranslator.java
@@ -158,8 +158,10 @@ public class ActionTranslator implements ActionSplitterListener {
translator.rf = rf;
factory.getGrammar().tool.log("action-translator", "translate " + action);
String altLabel = node.getAltLabel();
- if ( rf!=null ) translator.nodeContext = rf.ruleCtx;
- if ( altLabel!=null ) translator.nodeContext = rf.altLabelCtxs.get(altLabel);
+ if ( rf!=null ) {
+ translator.nodeContext = rf.ruleCtx;
+ if ( altLabel!=null ) translator.nodeContext = rf.altLabelCtxs.get(altLabel);
+ }
ANTLRStringStream in = new ANTLRStringStream(action);
in.setLine(tokenWithinAction.getLine());
in.setCharPositionInLine(tokenWithinAction.getCharPositionInLine());
diff --git a/tool/src/org/antlr/v4/codegen/target/CSharpTarget.java b/tool/src/org/antlr/v4/codegen/target/CSharpTarget.java
index 09df962..bfebe4b 100644
--- a/tool/src/org/antlr/v4/codegen/target/CSharpTarget.java
+++ b/tool/src/org/antlr/v4/codegen/target/CSharpTarget.java
@@ -51,7 +51,7 @@ public class CSharpTarget extends Target {
@Override
public String getVersion() {
- return "4.5.1"; // crossing fingers that it's close enough.
+ return "4.5.2"; // crossing fingers that it's close enough.
}
@Override
diff --git a/tool/src/org/antlr/v4/codegen/target/JavaScriptTarget.java b/tool/src/org/antlr/v4/codegen/target/JavaScriptTarget.java
index 26fa4fe..71926ac 100644
--- a/tool/src/org/antlr/v4/codegen/target/JavaScriptTarget.java
+++ b/tool/src/org/antlr/v4/codegen/target/JavaScriptTarget.java
@@ -74,7 +74,7 @@ public class JavaScriptTarget extends Target {
@Override
public String getVersion() {
- return "4.5.1";
+ return "4.5.2";
}
public Set<String> getBadWords() {
diff --git a/tool/src/org/antlr/v4/codegen/target/Python2Target.java b/tool/src/org/antlr/v4/codegen/target/Python2Target.java
index 36249d5..efa5d2c 100644
--- a/tool/src/org/antlr/v4/codegen/target/Python2Target.java
+++ b/tool/src/org/antlr/v4/codegen/target/Python2Target.java
@@ -117,7 +117,7 @@ public class Python2Target extends Target {
@Override
public String getVersion() {
- return "4.5.2";
+ return "4.5.2.1";
}
public Set<String> getBadWords() {
diff --git a/tool/src/org/antlr/v4/codegen/target/Python3Target.java b/tool/src/org/antlr/v4/codegen/target/Python3Target.java
index d07247f..68d7a16 100644
--- a/tool/src/org/antlr/v4/codegen/target/Python3Target.java
+++ b/tool/src/org/antlr/v4/codegen/target/Python3Target.java
@@ -119,7 +119,7 @@ public class Python3Target extends Target {
@Override
public String getVersion() {
- return "4.5.2";
+ return "4.5.2.1";
}
/** Avoid grammar symbols in this set to prevent conflicts in gen'd code. */
diff --git a/tool/src/org/antlr/v4/gui/TestRig.java b/tool/src/org/antlr/v4/gui/TestRig.java
index 4812e5c..e81a54c 100644
--- a/tool/src/org/antlr/v4/gui/TestRig.java
+++ b/tool/src/org/antlr/v4/gui/TestRig.java
@@ -80,7 +80,7 @@ public class TestRig {
public TestRig(String[] args) throws Exception {
if ( args.length < 2 ) {
- System.err.println("java org.antlr.v4.runtime.misc.TestRig GrammarName startRuleName\n" +
+ System.err.println("java org.antlr.v4.gui.TestRig GrammarName startRuleName\n" +
" [-tokens] [-tree] [-gui] [-ps file.ps] [-encoding encodingname]\n" +
" [-trace] [-diagnostics] [-SLL]\n"+
" [input-filename(s)]");
@@ -172,9 +172,6 @@ public class TestRig {
if ( !startRuleName.equals(LEXER_START_RULE_NAME) ) {
String parserName = grammarName+"Parser";
parserClass = cl.loadClass(parserName).asSubclass(Parser.class);
- if ( parserClass==null ) {
- System.err.println("Can't load "+parserName);
- }
Constructor<? extends Parser> parserCtor = parserClass.getConstructor(TokenStream.class);
parser = parserCtor.newInstance((TokenStream)null);
}
diff --git a/tool/src/org/antlr/v4/gui/TreeViewer.java b/tool/src/org/antlr/v4/gui/TreeViewer.java
index 0ca15f3..3cfd5e5 100644
--- a/tool/src/org/antlr/v4/gui/TreeViewer.java
+++ b/tool/src/org/antlr/v4/gui/TreeViewer.java
@@ -372,10 +372,12 @@ public class TreeViewer extends JComponent {
JTree selectedTree = (JTree) e.getSource();
TreePath path = selectedTree.getSelectionPath();
- TreeNodeWrapper treeNode = (TreeNodeWrapper) path.getLastPathComponent();
+ if (path!=null) {
+ TreeNodeWrapper treeNode = (TreeNodeWrapper) path.getLastPathComponent();
- // Set the clicked AST.
- viewer.setTree((Tree) treeNode.getUserObject());
+ // Set the clicked AST.
+ viewer.setTree((Tree) treeNode.getUserObject());
+ }
}
});
diff --git a/tool/src/org/antlr/v4/semantics/BasicSemanticChecks.java b/tool/src/org/antlr/v4/semantics/BasicSemanticChecks.java
index a578a66..4853c37 100644
--- a/tool/src/org/antlr/v4/semantics/BasicSemanticChecks.java
+++ b/tool/src/org/antlr/v4/semantics/BasicSemanticChecks.java
@@ -349,7 +349,7 @@ public class BasicSemanticChecks extends GrammarTreeVisitor {
GrammarAST root = (GrammarAST)rulesNode.getParent();
GrammarAST IDNode = (GrammarAST)root.getChild(0);
g.tool.errMgr.grammarError(ErrorType.NO_RULES, g.fileName,
- null, IDNode.getText(), g);
+ null, IDNode.getText(), g);
}
}
@@ -491,6 +491,14 @@ public class BasicSemanticChecks extends GrammarTreeVisitor {
label.getText());
}
+ @Override
+ protected void enterTerminal(GrammarAST tree) {
+ String text = tree.getText();
+ if (text.equals("''")) {
+ g.tool.errMgr.grammarError(ErrorType.EMPTY_STRINGS_NOT_ALLOWED, g.fileName, tree.token);
+ }
+ }
+
/** Check option is appropriate for grammar, rule, subrule */
boolean checkOptions(GrammarAST parent,
Token optionID,
diff --git a/tool/src/org/antlr/v4/semantics/SemanticPipeline.java b/tool/src/org/antlr/v4/semantics/SemanticPipeline.java
index 3561f91..ada4324 100644
--- a/tool/src/org/antlr/v4/semantics/SemanticPipeline.java
+++ b/tool/src/org/antlr/v4/semantics/SemanticPipeline.java
@@ -31,6 +31,7 @@
package org.antlr.v4.semantics;
import org.antlr.v4.analysis.LeftRecursiveRuleTransformer;
+import org.antlr.v4.automata.LexerATNFactory;
import org.antlr.v4.parse.ANTLRParser;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.misc.Pair;
@@ -128,6 +129,8 @@ public class SemanticPipeline {
collector.tokenIDRefs, collector.terminals);
}
+ symcheck.checkForModeConflicts(g);
+
assignChannelTypes(g, collector.channelDefs);
// CHECK RULE REFS NOW (that we've defined rules in grammar)
@@ -287,6 +290,10 @@ public class SemanticPipeline {
g.tool.errMgr.grammarError(ErrorType.CHANNEL_CONFLICTS_WITH_TOKEN, g.fileName, channel.token, channelName);
}
+ if (LexerATNFactory.COMMON_CONSTANTS.containsKey(channelName)) {
+ g.tool.errMgr.grammarError(ErrorType.CHANNEL_CONFLICTS_WITH_COMMON_CONSTANTS, g.fileName, channel.token, channelName);
+ }
+
if (outermost instanceof LexerGrammar) {
LexerGrammar lexerGrammar = (LexerGrammar)outermost;
if (lexerGrammar.modes.containsKey(channelName)) {
diff --git a/tool/src/org/antlr/v4/semantics/SymbolChecks.java b/tool/src/org/antlr/v4/semantics/SymbolChecks.java
index b280f40..999d9f0 100644
--- a/tool/src/org/antlr/v4/semantics/SymbolChecks.java
+++ b/tool/src/org/antlr/v4/semantics/SymbolChecks.java
@@ -30,7 +30,9 @@
package org.antlr.v4.semantics;
+import org.antlr.v4.automata.LexerATNFactory;
import org.antlr.v4.parse.ANTLRParser;
+import org.antlr.v4.runtime.Token;
import org.antlr.v4.tool.Alternative;
import org.antlr.v4.tool.Attribute;
import org.antlr.v4.tool.AttributeDict;
@@ -38,6 +40,7 @@ import org.antlr.v4.tool.ErrorManager;
import org.antlr.v4.tool.ErrorType;
import org.antlr.v4.tool.Grammar;
import org.antlr.v4.tool.LabelElementPair;
+import org.antlr.v4.tool.LexerGrammar;
import org.antlr.v4.tool.Rule;
import org.antlr.v4.tool.ast.GrammarAST;
@@ -67,7 +70,7 @@ public class SymbolChecks {
protected final Set<String> reservedNames = new HashSet<String>();
{
- reservedNames.add("EOF");
+ reservedNames.addAll(LexerATNFactory.getCommonConstants());
}
public SymbolChecks(Grammar g, SymbolCollector collector) {
@@ -269,6 +272,23 @@ public class SymbolChecks {
}
}
+ public void checkForModeConflicts(Grammar g) {
+ if (g.isLexer()) {
+ LexerGrammar lexerGrammar = (LexerGrammar)g;
+ for (String modeName : lexerGrammar.modes.keySet()) {
+ if (!modeName.equals("DEFAULT_MODE") && reservedNames.contains(modeName)) {
+ Rule rule = lexerGrammar.modes.get(modeName).iterator().next();
+ g.tool.errMgr.grammarError(ErrorType.MODE_CONFLICTS_WITH_COMMON_CONSTANTS, g.fileName, rule.ast.parent.getToken(), modeName);
+ }
+
+ if (g.getTokenType(modeName) != Token.INVALID_TYPE) {
+ Rule rule = lexerGrammar.modes.get(modeName).iterator().next();
+ g.tool.errMgr.grammarError(ErrorType.MODE_CONFLICTS_WITH_TOKEN, g.fileName, rule.ast.parent.getToken(), modeName);
+ }
+ }
+ }
+ }
+
// CAN ONLY CALL THE TWO NEXT METHODS AFTER GRAMMAR HAS RULE DEFS (see semanticpipeline)
public void checkRuleArgs(Grammar g, List<GrammarAST> rulerefs) {
diff --git a/tool/src/org/antlr/v4/tool/ErrorType.java b/tool/src/org/antlr/v4/tool/ErrorType.java
index 4868931..0fedfc4 100644
--- a/tool/src/org/antlr/v4/tool/ErrorType.java
+++ b/tool/src/org/antlr/v4/tool/ErrorType.java
@@ -957,6 +957,60 @@ public enum ErrorType {
CHANNELS_BLOCK_IN_COMBINED_GRAMMAR(164, "custom channels are not supported in combined grammars", ErrorSeverity.ERROR),
NONCONFORMING_LR_RULE(169, "rule <arg> is left recursive but doesn't conform to a pattern ANTLR can handle", ErrorSeverity.ERROR),
+ /**
+ * Compiler Error 170.
+ *
+ * <pre>
+ * mode M1;
+ * A1: 'a'; // ok
+ * mode M2;
+ * A2: 'a'; // ok
+ * M1: 'b'; // error 170
+ * </pre>
+ *
+ * <p>mode <em>name</em> conflicts with token with same name</p>
+ */
+ MODE_CONFLICTS_WITH_TOKEN(170, "mode <arg> conflicts with token with same name", ErrorSeverity.ERROR),
+ /**
+ * Compiler Error 171.
+ *
+ * <p>can not use or declare token with reserved name</p>
+ *
+ * <p>Reserved names: HIDDEN, DEFAULT_TOKEN_CHANNEL, SKIP, MORE, MAX_CHAR_VALUE, MIN_CHAR_VALUE.
+ *
+ * <p>Can be used but cannot be declared: EOF</p>
+ */
+ TOKEN_CONFLICTS_WITH_COMMON_CONSTANTS(171, "cannot use or declare token with reserved name <arg>", ErrorSeverity.ERROR),
+ /**
+ * Compiler Error 172.
+ *
+ * <p>can not use or declare channel with reserved name</p>
+ *
+ * <p>Reserved names: DEFAULT_MODE, SKIP, MORE, EOF, MAX_CHAR_VALUE, MIN_CHAR_VALUE.
+ *
+ * <p>Can be used but cannot be declared: HIDDEN, DEFAULT_TOKEN_CHANNEL</p>
+ */
+ CHANNEL_CONFLICTS_WITH_COMMON_CONSTANTS(172, "cannot use or declare channel with reserved name <arg>", ErrorSeverity.ERROR),
+ /**
+ * Compiler Error 173.
+ *
+ * <p>can not use or declare mode with reserved name</p>
+ *
+ * <p>Reserved names: HIDDEN, DEFAULT_TOKEN_CHANNEL, SKIP, MORE, MAX_CHAR_VALUE, MIN_CHAR_VALUE.
+ *
+ * <p>Can be used and cannot declared: DEFAULT_MODE</p>
+ */
+ MODE_CONFLICTS_WITH_COMMON_CONSTANTS(173, "cannot use or declare mode with reserved name <arg>", ErrorSeverity.ERROR),
+ /**
+ * Compiler Error 174.
+ *
+ * <p>empty strings not allowed</p>
+ *
+ * <pre>A: '''test''';</pre>
+ * <pre>B: '';</pre>
+ * <pre>C: 'test' '';</pre>
+ */
+ EMPTY_STRINGS_NOT_ALLOWED(174, "string literals cannot be empty", ErrorSeverity.ERROR),
/*
* Backward incompatibility errors