finished LABEL_TYPE_CONFLICT

[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6676]
This commit is contained in:
parrt 2010-02-07 15:22:46 -08:00
parent 8d0d3e1c94
commit 795df39aaa
8 changed files with 439 additions and 117 deletions

View File

@ -0,0 +1,222 @@
/*
[The "BSD license"]
Copyright (c) 2005-2009 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.antlr.v4.runtime.tree;
import org.antlr.runtime.Token;
import org.antlr.runtime.tree.BaseTree;
import org.antlr.runtime.tree.Tree;
import org.antlr.v4.runtime.tree.gui.ASTViewer;
import java.util.BitSet;
/** A tree node that is wrapper for a Token object. After 3.0 release
* while building tree rewrite stuff, it became clear that computing
* parent and child index is very difficult and cumbersome. Better to
* spend the space in every tree node. If you don't want these extra
* fields, it's easy to cut them out in your own BaseTree subclass.
*/
public class CommonTree extends BaseTree {
/** A single token is the payload */
public Token token;
/** What token indexes bracket all tokens associated with this node
* and below?
*/
protected int startIndex=-1, stopIndex=-1;
/** Who is the parent node of this node; if null, implies node is root */
public CommonTree parent;
/** What index is this node in the child list? Range: 0..n-1 */
public int childIndex = -1;
public CommonTree() { }
public CommonTree(CommonTree node) {
super(node);
this.token = node.token;
this.startIndex = node.startIndex;
this.stopIndex = node.stopIndex;
}
public CommonTree(Token t) {
this.token = t;
}
public Token getToken() {
return token;
}
public Tree dupNode() {
return new CommonTree(this);
}
public boolean isNil() {
return token==null;
}
public int getType() {
if ( token==null ) {
return Token.INVALID_TOKEN_TYPE;
}
return token.getType();
}
public String getText() {
if ( token==null ) {
return null;
}
return token.getText();
}
public int getLine() {
if ( token==null || token.getLine()==0 ) {
if ( getChildCount()>0 ) {
return getChild(0).getLine();
}
return 0;
}
return token.getLine();
}
public int getCharPositionInLine() {
if ( token==null || token.getCharPositionInLine()==-1 ) {
if ( getChildCount()>0 ) {
return getChild(0).getCharPositionInLine();
}
return 0;
}
return token.getCharPositionInLine();
}
public int getTokenStartIndex() {
if ( startIndex==-1 && token!=null ) {
return token.getTokenIndex();
}
return startIndex;
}
public void setTokenStartIndex(int index) {
startIndex = index;
}
public int getTokenStopIndex() {
if ( stopIndex==-1 && token!=null ) {
return token.getTokenIndex();
}
return stopIndex;
}
public void setTokenStopIndex(int index) {
stopIndex = index;
}
/** For every node in this subtree, make sure it's start/stop token's
* are set. Walk depth first, visit bottom up. Only updates nodes
* with at least one token index < 0.
*/
public void setUnknownTokenBoundaries() {
if ( children==null ) {
if ( startIndex<0 || stopIndex<0 ) {
startIndex = stopIndex = token.getTokenIndex();
}
return;
}
for (int i=0; i<children.size(); i++) {
((CommonTree)children.get(i)).setUnknownTokenBoundaries();
}
if ( startIndex>=0 && stopIndex>=0 ) return; // already set
if ( children.size() > 0 ) {
CommonTree firstChild = (CommonTree)children.get(0);
CommonTree lastChild = (CommonTree)children.get(children.size()-1);
startIndex = firstChild.getTokenStartIndex();
stopIndex = lastChild.getTokenStopIndex();
}
}
public int getChildIndex() {
return childIndex;
}
public Tree getParent() {
return parent;
}
public void setParent(Tree t) {
this.parent = (CommonTree)t;
}
public void setChildIndex(int index) {
this.childIndex = index;
}
// TODO: move to basetree when i settle on how runtime works
public void inspect() {
ASTViewer viewer = new ASTViewer(this);
viewer.open();
}
// TODO: move to basetree when i settle on how runtime works
/** include this node */
public CommonTree getFirstDescendantWithType(int type) {
if ( getType()==type ) return this;
if ( children==null ) return null;
for (Object c : children) {
CommonTree t = (CommonTree)c;
if ( t.getType()==type ) return t;
CommonTree d = t.getFirstDescendantWithType(type);
if ( d!=null ) return d;
}
return null;
}
public CommonTree getFirstDescendantWithType(BitSet types) {
if ( types.get(getType()) ) return this;
if ( children==null ) return null;
for (Object c : children) {
CommonTree t = (CommonTree)c;
if ( types.get(t.getType()) ) return t;
CommonTree d = t.getFirstDescendantWithType(types);
if ( d!=null ) return d;
}
return null;
}
public String toString() {
if ( isNil() ) {
return "nil";
}
if ( getType()==Token.INVALID_TOKEN_TYPE ) {
return "<errornode>";
}
if ( token==null ) {
return null;
}
return token.getText();
}
}

View File

@ -1,4 +1,4 @@
// $ANTLR 3.2.1-SNAPSHOT Jan 26, 2010 15:12:28 BasicSemanticTriggers.g 2010-02-07 14:03:15
// $ANTLR 3.2.1-SNAPSHOT Jan 26, 2010 15:12:28 BasicSemanticTriggers.g 2010-02-07 15:09:46
/*
[The "BSD license"]

View File

@ -67,6 +67,7 @@ package org.antlr.v4.semantics;
import org.antlr.v4.tool.*;
import java.util.Set;
import java.util.HashSet;
import org.stringtemplate.v4.misc.MultiMap;
}
@members {
@ -79,6 +80,8 @@ public List<GrammarAST> strings = new ArrayList<GrammarAST>();
public List<GrammarAST> tokensDefs = new ArrayList<GrammarAST>();
public List<GrammarAST> scopes = new ArrayList<GrammarAST>();
public List<GrammarAST> actions = new ArrayList<GrammarAST>();
public MultiMap<String, LabelElementPair> ruleToLabelSpace =
new MultiMap<String, LabelElementPair>();
Grammar g; // which grammar are we checking
public CollectSymbols(TreeNodeStream input, Grammar g) {
this(input);
@ -150,8 +153,12 @@ ruleScopeSpec
;
labeledElement
: ^(ASSIGN ID e=.) {currentRule.labelNameSpace.put($ID.text, $start);}
| ^(PLUS_ASSIGN ID e=.) {currentRule.labelNameSpace.put($ID.text, $start);}
@after {
LabelElementPair lp = new LabelElementPair(g, $id, $e, $start.getType());
ruleToLabelSpace.map(currentRule.name, lp);
}
: ^(ASSIGN id=ID e=.)
| ^(PLUS_ASSIGN id=ID e=.)
;
terminal

View File

@ -1,4 +1,4 @@
// $ANTLR 3.2.1-SNAPSHOT Jan 26, 2010 15:12:28 CollectSymbols.g 2010-02-07 14:03:14
// $ANTLR 3.2.1-SNAPSHOT Jan 26, 2010 15:12:28 CollectSymbols.g 2010-02-07 15:09:46
/*
[The "BSD license"]
@ -30,10 +30,8 @@ package org.antlr.v4.semantics;
import org.antlr.runtime.*;
import org.antlr.runtime.tree.TreeNodeStream;
import org.antlr.runtime.tree.TreeRuleReturnScope;
import org.antlr.v4.tool.Grammar;
import org.antlr.v4.tool.GrammarAST;
import org.antlr.v4.tool.GrammarASTWithOptions;
import org.antlr.v4.tool.Rule;
import org.antlr.v4.tool.*;
import org.stringtemplate.v4.misc.MultiMap;
import java.util.ArrayList;
import java.util.List;
@ -170,6 +168,8 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
public List<GrammarAST> tokensDefs = new ArrayList<GrammarAST>();
public List<GrammarAST> scopes = new ArrayList<GrammarAST>();
public List<GrammarAST> actions = new ArrayList<GrammarAST>();
public MultiMap<String, LabelElementPair> ruleToLabelSpace =
new MultiMap<String, LabelElementPair>();
Grammar g; // which grammar are we checking
public CollectSymbols(TreeNodeStream input, Grammar g) {
this(input);
@ -179,15 +179,15 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
// $ANTLR start "topdown"
// CollectSymbols.g:89:1: topdown : ( globalScope | action | tokensSection | rule | ruleArg | ruleReturns | ruleScopeSpec | ruleref | terminal | labeledElement );
// CollectSymbols.g:92:1: topdown : ( globalScope | action | tokensSection | rule | ruleArg | ruleReturns | ruleScopeSpec | ruleref | terminal | labeledElement );
public final void topdown() throws RecognitionException {
try {
// CollectSymbols.g:90:5: ( globalScope | action | tokensSection | rule | ruleArg | ruleReturns | ruleScopeSpec | ruleref | terminal | labeledElement )
// CollectSymbols.g:93:5: ( globalScope | action | tokensSection | rule | ruleArg | ruleReturns | ruleScopeSpec | ruleref | terminal | labeledElement )
int alt1=10;
alt1 = dfa1.predict(input);
switch (alt1) {
case 1 :
// CollectSymbols.g:90:7: globalScope
// CollectSymbols.g:93:7: globalScope
{
pushFollow(FOLLOW_globalScope_in_topdown96);
globalScope();
@ -198,7 +198,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
}
break;
case 2 :
// CollectSymbols.g:91:7: action
// CollectSymbols.g:94:7: action
{
pushFollow(FOLLOW_action_in_topdown104);
action();
@ -209,7 +209,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
}
break;
case 3 :
// CollectSymbols.g:92:7: tokensSection
// CollectSymbols.g:95:7: tokensSection
{
pushFollow(FOLLOW_tokensSection_in_topdown112);
tokensSection();
@ -220,7 +220,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
}
break;
case 4 :
// CollectSymbols.g:93:7: rule
// CollectSymbols.g:96:7: rule
{
pushFollow(FOLLOW_rule_in_topdown120);
rule();
@ -231,7 +231,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
}
break;
case 5 :
// CollectSymbols.g:94:7: ruleArg
// CollectSymbols.g:97:7: ruleArg
{
pushFollow(FOLLOW_ruleArg_in_topdown128);
ruleArg();
@ -242,7 +242,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
}
break;
case 6 :
// CollectSymbols.g:95:7: ruleReturns
// CollectSymbols.g:98:7: ruleReturns
{
pushFollow(FOLLOW_ruleReturns_in_topdown136);
ruleReturns();
@ -253,7 +253,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
}
break;
case 7 :
// CollectSymbols.g:96:7: ruleScopeSpec
// CollectSymbols.g:99:7: ruleScopeSpec
{
pushFollow(FOLLOW_ruleScopeSpec_in_topdown144);
ruleScopeSpec();
@ -264,7 +264,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
}
break;
case 8 :
// CollectSymbols.g:97:7: ruleref
// CollectSymbols.g:100:7: ruleref
{
pushFollow(FOLLOW_ruleref_in_topdown152);
ruleref();
@ -275,7 +275,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
}
break;
case 9 :
// CollectSymbols.g:98:7: terminal
// CollectSymbols.g:101:7: terminal
{
pushFollow(FOLLOW_terminal_in_topdown160);
terminal();
@ -286,7 +286,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
}
break;
case 10 :
// CollectSymbols.g:99:7: labeledElement
// CollectSymbols.g:102:7: labeledElement
{
pushFollow(FOLLOW_labeledElement_in_topdown168);
labeledElement();
@ -311,11 +311,11 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
// $ANTLR start "bottomup"
// CollectSymbols.g:102:1: bottomup : finishRule ;
// CollectSymbols.g:105:1: bottomup : finishRule ;
public final void bottomup() throws RecognitionException {
try {
// CollectSymbols.g:103:2: ( finishRule )
// CollectSymbols.g:103:4: finishRule
// CollectSymbols.g:106:2: ( finishRule )
// CollectSymbols.g:106:4: finishRule
{
pushFollow(FOLLOW_finishRule_in_bottomup179);
finishRule();
@ -338,13 +338,13 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
// $ANTLR start "globalScope"
// CollectSymbols.g:106:1: globalScope : {...}? ^( SCOPE ID ACTION ) ;
// CollectSymbols.g:109:1: globalScope : {...}? ^( SCOPE ID ACTION ) ;
public final void globalScope() throws RecognitionException {
GrammarAST SCOPE1=null;
try {
// CollectSymbols.g:107:2: ({...}? ^( SCOPE ID ACTION ) )
// CollectSymbols.g:107:4: {...}? ^( SCOPE ID ACTION )
// CollectSymbols.g:110:2: ({...}? ^( SCOPE ID ACTION ) )
// CollectSymbols.g:110:4: {...}? ^( SCOPE ID ACTION )
{
if ( !((inContext("GRAMMAR"))) ) {
if (state.backtracking>0) {state.failed=true; return ;}
@ -376,13 +376,13 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
// $ANTLR start "action"
// CollectSymbols.g:110:1: action : {...}? ^( AT ( ID )? ID ACTION ) ;
// CollectSymbols.g:113:1: action : {...}? ^( AT ( ID )? ID ACTION ) ;
public final void action() throws RecognitionException {
GrammarAST AT2=null;
try {
// CollectSymbols.g:111:2: ({...}? ^( AT ( ID )? ID ACTION ) )
// CollectSymbols.g:111:4: {...}? ^( AT ( ID )? ID ACTION )
// CollectSymbols.g:114:2: ({...}? ^( AT ( ID )? ID ACTION ) )
// CollectSymbols.g:114:4: {...}? ^( AT ( ID )? ID ACTION )
{
if ( !((inContext("GRAMMAR"))) ) {
if (state.backtracking>0) {state.failed=true; return ;}
@ -391,7 +391,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
AT2=(GrammarAST)match(input,AT,FOLLOW_AT_in_action214); if (state.failed) return ;
match(input, Token.DOWN, null); if (state.failed) return ;
// CollectSymbols.g:111:33: ( ID )?
// CollectSymbols.g:114:33: ( ID )?
int alt2=2;
int LA2_0 = input.LA(1);
@ -404,7 +404,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
}
switch (alt2) {
case 1 :
// CollectSymbols.g:111:33: ID
// CollectSymbols.g:114:33: ID
{
match(input,ID,FOLLOW_ID_in_action216); if (state.failed) return ;
@ -436,21 +436,21 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
// $ANTLR start "tokensSection"
// CollectSymbols.g:115:1: tokensSection : {...}? ( ^( ASSIGN t= ID STRING_LITERAL ) | t= ID ) ;
// CollectSymbols.g:118:1: tokensSection : {...}? ( ^( ASSIGN t= ID STRING_LITERAL ) | t= ID ) ;
public final void tokensSection() throws RecognitionException {
GrammarAST t=null;
GrammarAST ASSIGN3=null;
GrammarAST STRING_LITERAL4=null;
try {
// CollectSymbols.g:116:2: ({...}? ( ^( ASSIGN t= ID STRING_LITERAL ) | t= ID ) )
// CollectSymbols.g:116:4: {...}? ( ^( ASSIGN t= ID STRING_LITERAL ) | t= ID )
// CollectSymbols.g:119:2: ({...}? ( ^( ASSIGN t= ID STRING_LITERAL ) | t= ID ) )
// CollectSymbols.g:119:4: {...}? ( ^( ASSIGN t= ID STRING_LITERAL ) | t= ID )
{
if ( !((inContext("TOKENS"))) ) {
if (state.backtracking>0) {state.failed=true; return ;}
throw new FailedPredicateException(input, "tokensSection", "inContext(\"TOKENS\")");
}
// CollectSymbols.g:117:3: ( ^( ASSIGN t= ID STRING_LITERAL ) | t= ID )
// CollectSymbols.g:120:3: ( ^( ASSIGN t= ID STRING_LITERAL ) | t= ID )
int alt3=2;
int LA3_0 = input.LA(1);
@ -469,7 +469,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
}
switch (alt3) {
case 1 :
// CollectSymbols.g:117:5: ^( ASSIGN t= ID STRING_LITERAL )
// CollectSymbols.g:120:5: ^( ASSIGN t= ID STRING_LITERAL )
{
ASSIGN3=(GrammarAST)match(input,ASSIGN,FOLLOW_ASSIGN_in_tokensSection244); if (state.failed) return ;
@ -486,7 +486,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
}
break;
case 2 :
// CollectSymbols.g:120:5: t= ID
// CollectSymbols.g:123:5: t= ID
{
t=(GrammarAST)match(input,ID,FOLLOW_ID_in_tokensSection264); if (state.failed) return ;
if ( state.backtracking==1 ) {
@ -514,20 +514,20 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
// $ANTLR start "rule"
// CollectSymbols.g:125:1: rule : ^( RULE name= ID ( . )+ ) ;
// CollectSymbols.g:128:1: rule : ^( RULE name= ID ( . )+ ) ;
public final void rule() throws RecognitionException {
GrammarAST name=null;
GrammarAST RULE5=null;
try {
// CollectSymbols.g:125:5: ( ^( RULE name= ID ( . )+ ) )
// CollectSymbols.g:125:9: ^( RULE name= ID ( . )+ )
// CollectSymbols.g:128:5: ( ^( RULE name= ID ( . )+ ) )
// CollectSymbols.g:128:9: ^( RULE name= ID ( . )+ )
{
RULE5=(GrammarAST)match(input,RULE,FOLLOW_RULE_in_rule286); if (state.failed) return ;
match(input, Token.DOWN, null); if (state.failed) return ;
name=(GrammarAST)match(input,ID,FOLLOW_ID_in_rule290); if (state.failed) return ;
// CollectSymbols.g:125:25: ( . )+
// CollectSymbols.g:128:25: ( . )+
int cnt4=0;
loop4:
do {
@ -544,7 +544,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
switch (alt4) {
case 1 :
// CollectSymbols.g:125:25: .
// CollectSymbols.g:128:25: .
{
matchAny(input); if (state.failed) return ;
@ -586,11 +586,11 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
// $ANTLR start "finishRule"
// CollectSymbols.g:133:1: finishRule : RULE ;
// CollectSymbols.g:136:1: finishRule : RULE ;
public final void finishRule() throws RecognitionException {
try {
// CollectSymbols.g:134:2: ( RULE )
// CollectSymbols.g:134:4: RULE
// CollectSymbols.g:137:2: ( RULE )
// CollectSymbols.g:137:4: RULE
{
match(input,RULE,FOLLOW_RULE_in_finishRule312); if (state.failed) return ;
if ( state.backtracking==1 ) {
@ -612,13 +612,13 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
// $ANTLR start "ruleArg"
// CollectSymbols.g:137:1: ruleArg : {...}? ARG_ACTION ;
// CollectSymbols.g:140:1: ruleArg : {...}? ARG_ACTION ;
public final void ruleArg() throws RecognitionException {
GrammarAST ARG_ACTION6=null;
try {
// CollectSymbols.g:138:2: ({...}? ARG_ACTION )
// CollectSymbols.g:138:4: {...}? ARG_ACTION
// CollectSymbols.g:141:2: ({...}? ARG_ACTION )
// CollectSymbols.g:141:4: {...}? ARG_ACTION
{
if ( !((inContext("RULE"))) ) {
if (state.backtracking>0) {state.failed=true; return ;}
@ -644,13 +644,13 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
// $ANTLR start "ruleReturns"
// CollectSymbols.g:141:1: ruleReturns : ^( RETURNS ARG_ACTION ) ;
// CollectSymbols.g:144:1: ruleReturns : ^( RETURNS ARG_ACTION ) ;
public final void ruleReturns() throws RecognitionException {
GrammarAST ARG_ACTION7=null;
try {
// CollectSymbols.g:142:2: ( ^( RETURNS ARG_ACTION ) )
// CollectSymbols.g:142:4: ^( RETURNS ARG_ACTION )
// CollectSymbols.g:145:2: ( ^( RETURNS ARG_ACTION ) )
// CollectSymbols.g:145:4: ^( RETURNS ARG_ACTION )
{
match(input,RETURNS,FOLLOW_RETURNS_in_ruleReturns342); if (state.failed) return ;
@ -677,17 +677,17 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
// $ANTLR start "ruleScopeSpec"
// CollectSymbols.g:145:1: ruleScopeSpec : {...}? ( ^( SCOPE ACTION ) | ^( SCOPE ( ID )+ ) ) ;
// CollectSymbols.g:148:1: ruleScopeSpec : {...}? ( ^( SCOPE ACTION ) | ^( SCOPE ( ID )+ ) ) ;
public final void ruleScopeSpec() throws RecognitionException {
try {
// CollectSymbols.g:146:2: ({...}? ( ^( SCOPE ACTION ) | ^( SCOPE ( ID )+ ) ) )
// CollectSymbols.g:146:4: {...}? ( ^( SCOPE ACTION ) | ^( SCOPE ( ID )+ ) )
// CollectSymbols.g:149:2: ({...}? ( ^( SCOPE ACTION ) | ^( SCOPE ( ID )+ ) ) )
// CollectSymbols.g:149:4: {...}? ( ^( SCOPE ACTION ) | ^( SCOPE ( ID )+ ) )
{
if ( !((inContext("RULE"))) ) {
if (state.backtracking>0) {state.failed=true; return ;}
throw new FailedPredicateException(input, "ruleScopeSpec", "inContext(\"RULE\")");
}
// CollectSymbols.g:147:3: ( ^( SCOPE ACTION ) | ^( SCOPE ( ID )+ ) )
// CollectSymbols.g:150:3: ( ^( SCOPE ACTION ) | ^( SCOPE ( ID )+ ) )
int alt6=2;
int LA6_0 = input.LA(1);
@ -728,7 +728,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
}
switch (alt6) {
case 1 :
// CollectSymbols.g:147:5: ^( SCOPE ACTION )
// CollectSymbols.g:150:5: ^( SCOPE ACTION )
{
match(input,SCOPE,FOLLOW_SCOPE_in_ruleScopeSpec365); if (state.failed) return ;
@ -740,12 +740,12 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
}
break;
case 2 :
// CollectSymbols.g:148:5: ^( SCOPE ( ID )+ )
// CollectSymbols.g:151:5: ^( SCOPE ( ID )+ )
{
match(input,SCOPE,FOLLOW_SCOPE_in_ruleScopeSpec375); if (state.failed) return ;
match(input, Token.DOWN, null); if (state.failed) return ;
// CollectSymbols.g:148:13: ( ID )+
// CollectSymbols.g:151:13: ( ID )+
int cnt5=0;
loop5:
do {
@ -759,7 +759,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
switch (alt5) {
case 1 :
// CollectSymbols.g:148:13: ID
// CollectSymbols.g:151:13: ID
{
match(input,ID,FOLLOW_ID_in_ruleScopeSpec377); if (state.failed) return ;
@ -802,17 +802,16 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
};
// $ANTLR start "labeledElement"
// CollectSymbols.g:152:1: labeledElement : ( ^( ASSIGN ID e= . ) | ^( PLUS_ASSIGN ID e= . ) );
// CollectSymbols.g:155:1: labeledElement : ( ^( ASSIGN id= ID e= . ) | ^( PLUS_ASSIGN id= ID e= . ) );
public final CollectSymbols.labeledElement_return labeledElement() throws RecognitionException {
CollectSymbols.labeledElement_return retval = new CollectSymbols.labeledElement_return();
retval.start = input.LT(1);
GrammarAST ID8=null;
GrammarAST ID9=null;
GrammarAST id=null;
GrammarAST e=null;
try {
// CollectSymbols.g:153:2: ( ^( ASSIGN ID e= . ) | ^( PLUS_ASSIGN ID e= . ) )
// CollectSymbols.g:160:2: ( ^( ASSIGN id= ID e= . ) | ^( PLUS_ASSIGN id= ID e= . ) )
int alt7=2;
int LA7_0 = input.LA(1);
@ -831,41 +830,41 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
}
switch (alt7) {
case 1 :
// CollectSymbols.g:153:4: ^( ASSIGN ID e= . )
// CollectSymbols.g:160:4: ^( ASSIGN id= ID e= . )
{
match(input,ASSIGN,FOLLOW_ASSIGN_in_labeledElement395); if (state.failed) return retval;
match(input,ASSIGN,FOLLOW_ASSIGN_in_labeledElement400); if (state.failed) return retval;
match(input, Token.DOWN, null); if (state.failed) return retval;
ID8=(GrammarAST)match(input,ID,FOLLOW_ID_in_labeledElement397); if (state.failed) return retval;
id=(GrammarAST)match(input,ID,FOLLOW_ID_in_labeledElement404); if (state.failed) return retval;
e=(GrammarAST)input.LT(1);
matchAny(input); if (state.failed) return retval;
match(input, Token.UP, null); if (state.failed) return retval;
if ( state.backtracking==1 ) {
currentRule.labelNameSpace.put((ID8!=null?ID8.getText():null), ((GrammarAST)retval.start));
}
}
break;
case 2 :
// CollectSymbols.g:154:4: ^( PLUS_ASSIGN ID e= . )
// CollectSymbols.g:161:4: ^( PLUS_ASSIGN id= ID e= . )
{
match(input,PLUS_ASSIGN,FOLLOW_PLUS_ASSIGN_in_labeledElement411); if (state.failed) return retval;
match(input,PLUS_ASSIGN,FOLLOW_PLUS_ASSIGN_in_labeledElement415); if (state.failed) return retval;
match(input, Token.DOWN, null); if (state.failed) return retval;
ID9=(GrammarAST)match(input,ID,FOLLOW_ID_in_labeledElement413); if (state.failed) return retval;
id=(GrammarAST)match(input,ID,FOLLOW_ID_in_labeledElement419); if (state.failed) return retval;
e=(GrammarAST)input.LT(1);
matchAny(input); if (state.failed) return retval;
match(input, Token.UP, null); if (state.failed) return retval;
if ( state.backtracking==1 ) {
currentRule.labelNameSpace.put((ID9!=null?ID9.getText():null), ((GrammarAST)retval.start));
}
}
break;
}
if ( state.backtracking==1 ) {
LabelElementPair lp = new LabelElementPair(g, id, e, ((GrammarAST)retval.start).getType());
ruleToLabelSpace.map(currentRule.name, lp);
}
}
catch (RecognitionException re) {
reportError(re);
@ -881,16 +880,16 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
};
// $ANTLR start "terminal"
// CollectSymbols.g:157:1: terminal : ({...}? STRING_LITERAL | TOKEN_REF );
// CollectSymbols.g:164:1: terminal : ({...}? STRING_LITERAL | TOKEN_REF );
public final CollectSymbols.terminal_return terminal() throws RecognitionException {
CollectSymbols.terminal_return retval = new CollectSymbols.terminal_return();
retval.start = input.LT(1);
GrammarAST STRING_LITERAL10=null;
GrammarAST TOKEN_REF11=null;
GrammarAST STRING_LITERAL8=null;
GrammarAST TOKEN_REF9=null;
try {
// CollectSymbols.g:158:5: ({...}? STRING_LITERAL | TOKEN_REF )
// CollectSymbols.g:165:5: ({...}? STRING_LITERAL | TOKEN_REF )
int alt8=2;
int LA8_0 = input.LA(1);
@ -909,26 +908,26 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
}
switch (alt8) {
case 1 :
// CollectSymbols.g:158:7: {...}? STRING_LITERAL
// CollectSymbols.g:165:7: {...}? STRING_LITERAL
{
if ( !((!inContext("TOKENS ASSIGN"))) ) {
if (state.backtracking>0) {state.failed=true; return retval;}
throw new FailedPredicateException(input, "terminal", "!inContext(\"TOKENS ASSIGN\")");
}
STRING_LITERAL10=(GrammarAST)match(input,STRING_LITERAL,FOLLOW_STRING_LITERAL_in_terminal437); if (state.failed) return retval;
STRING_LITERAL8=(GrammarAST)match(input,STRING_LITERAL,FOLLOW_STRING_LITERAL_in_terminal441); if (state.failed) return retval;
if ( state.backtracking==1 ) {
terminals.add(((GrammarAST)retval.start));
strings.add(STRING_LITERAL10);
strings.add(STRING_LITERAL8);
}
}
break;
case 2 :
// CollectSymbols.g:160:7: TOKEN_REF
// CollectSymbols.g:167:7: TOKEN_REF
{
TOKEN_REF11=(GrammarAST)match(input,TOKEN_REF,FOLLOW_TOKEN_REF_in_terminal447); if (state.failed) return retval;
TOKEN_REF9=(GrammarAST)match(input,TOKEN_REF,FOLLOW_TOKEN_REF_in_terminal451); if (state.failed) return retval;
if ( state.backtracking==1 ) {
terminals.add(((GrammarAST)retval.start)); tokenIDRefs.add(TOKEN_REF11);
terminals.add(((GrammarAST)retval.start)); tokenIDRefs.add(TOKEN_REF9);
}
}
@ -948,19 +947,19 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
// $ANTLR start "ruleref"
// CollectSymbols.g:163:1: ruleref : ^( RULE_REF ( ARG_ACTION )? ) ;
// CollectSymbols.g:170:1: ruleref : ^( RULE_REF ( ARG_ACTION )? ) ;
public final void ruleref() throws RecognitionException {
GrammarAST RULE_REF12=null;
GrammarAST RULE_REF10=null;
try {
// CollectSymbols.g:164:5: ( ^( RULE_REF ( ARG_ACTION )? ) )
// CollectSymbols.g:164:7: ^( RULE_REF ( ARG_ACTION )? )
// CollectSymbols.g:171:5: ( ^( RULE_REF ( ARG_ACTION )? ) )
// CollectSymbols.g:171:7: ^( RULE_REF ( ARG_ACTION )? )
{
RULE_REF12=(GrammarAST)match(input,RULE_REF,FOLLOW_RULE_REF_in_ruleref467); if (state.failed) return ;
RULE_REF10=(GrammarAST)match(input,RULE_REF,FOLLOW_RULE_REF_in_ruleref471); if (state.failed) return ;
if ( input.LA(1)==Token.DOWN ) {
match(input, Token.DOWN, null); if (state.failed) return ;
// CollectSymbols.g:164:18: ( ARG_ACTION )?
// CollectSymbols.g:171:18: ( ARG_ACTION )?
int alt9=2;
int LA9_0 = input.LA(1);
@ -969,9 +968,9 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
}
switch (alt9) {
case 1 :
// CollectSymbols.g:164:18: ARG_ACTION
// CollectSymbols.g:171:18: ARG_ACTION
{
match(input,ARG_ACTION,FOLLOW_ARG_ACTION_in_ruleref469); if (state.failed) return ;
match(input,ARG_ACTION,FOLLOW_ARG_ACTION_in_ruleref473); if (state.failed) return ;
}
break;
@ -982,7 +981,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
match(input, Token.UP, null); if (state.failed) return ;
}
if ( state.backtracking==1 ) {
rulerefs.add(RULE_REF12);
rulerefs.add(RULE_REF10);
}
}
@ -1070,7 +1069,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
this.transition = DFA1_transition;
}
public String getDescription() {
return "89:1: topdown : ( globalScope | action | tokensSection | rule | ruleArg | ruleReturns | ruleScopeSpec | ruleref | terminal | labeledElement );";
return "92:1: topdown : ( globalScope | action | tokensSection | rule | ruleArg | ruleReturns | ruleScopeSpec | ruleref | terminal | labeledElement );";
}
public int specialStateTransition(int s, IntStream _input) throws NoViableAltException {
TreeNodeStream input = (TreeNodeStream)_input;
@ -1133,13 +1132,13 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
public static final BitSet FOLLOW_ACTION_in_ruleScopeSpec367 = new BitSet(new long[]{0x0000000000000008L});
public static final BitSet FOLLOW_SCOPE_in_ruleScopeSpec375 = new BitSet(new long[]{0x0000000000000004L});
public static final BitSet FOLLOW_ID_in_ruleScopeSpec377 = new BitSet(new long[]{0x0000000000000008L,0x0000000000800000L});
public static final BitSet FOLLOW_ASSIGN_in_labeledElement395 = new BitSet(new long[]{0x0000000000000004L});
public static final BitSet FOLLOW_ID_in_labeledElement397 = new BitSet(new long[]{0xFFFFFFFFFFFFFFF0L,0x0000003FFFFFFFFFL});
public static final BitSet FOLLOW_PLUS_ASSIGN_in_labeledElement411 = new BitSet(new long[]{0x0000000000000004L});
public static final BitSet FOLLOW_ID_in_labeledElement413 = new BitSet(new long[]{0xFFFFFFFFFFFFFFF0L,0x0000003FFFFFFFFFL});
public static final BitSet FOLLOW_STRING_LITERAL_in_terminal437 = new BitSet(new long[]{0x0000000000000002L});
public static final BitSet FOLLOW_TOKEN_REF_in_terminal447 = new BitSet(new long[]{0x0000000000000002L});
public static final BitSet FOLLOW_RULE_REF_in_ruleref467 = new BitSet(new long[]{0x0000000000000004L});
public static final BitSet FOLLOW_ARG_ACTION_in_ruleref469 = new BitSet(new long[]{0x0000000000000008L});
public static final BitSet FOLLOW_ASSIGN_in_labeledElement400 = new BitSet(new long[]{0x0000000000000004L});
public static final BitSet FOLLOW_ID_in_labeledElement404 = new BitSet(new long[]{0xFFFFFFFFFFFFFFF0L,0x0000003FFFFFFFFFL});
public static final BitSet FOLLOW_PLUS_ASSIGN_in_labeledElement415 = new BitSet(new long[]{0x0000000000000004L});
public static final BitSet FOLLOW_ID_in_labeledElement419 = new BitSet(new long[]{0xFFFFFFFFFFFFFFF0L,0x0000003FFFFFFFFFL});
public static final BitSet FOLLOW_STRING_LITERAL_in_terminal441 = new BitSet(new long[]{0x0000000000000002L});
public static final BitSet FOLLOW_TOKEN_REF_in_terminal451 = new BitSet(new long[]{0x0000000000000002L});
public static final BitSet FOLLOW_RULE_REF_in_ruleref471 = new BitSet(new long[]{0x0000000000000004L});
public static final BitSet FOLLOW_ARG_ACTION_in_ruleref473 = new BitSet(new long[]{0x0000000000000008L});
}

View File

@ -3,6 +3,7 @@ package org.antlr.v4.semantics;
import org.antlr.runtime.Token;
import org.antlr.v4.parse.ANTLRParser;
import org.antlr.v4.tool.*;
import org.stringtemplate.v4.misc.MultiMap;
import java.util.*;
@ -11,16 +12,17 @@ import java.util.*;
* of code that actually defines symbols etc...
*/
public class SymbolChecks {
Grammar g;
CollectSymbols collector;
Map<String, Rule> nameToRuleMap = new HashMap<String, Rule>();
Set<String> tokenIDs = new HashSet<String>();
Set<String> globalScopeNames = new HashSet<String>();
Map<String, Set<String>> actionScopeToActionNames = new HashMap<String, Set<String>>();
protected Grammar g;
protected CollectSymbols collector;
protected Map<String, Rule> nameToRuleMap = new HashMap<String, Rule>();
protected Set<String> tokenIDs = new HashSet<String>();
protected Set<String> globalScopeNames = new HashSet<String>();
protected Map<String, Set<String>> actionScopeToActionNames = new HashMap<String, Set<String>>();
public SymbolChecks(Grammar g, CollectSymbols collector) {
this.g = g;
this.collector = collector;
/*
System.out.println("rules="+collector.rules);
System.out.println("rulerefs="+collector.rulerefs);
System.out.println("tokenIDRefs="+collector.tokenIDRefs);
@ -29,6 +31,7 @@ public class SymbolChecks {
System.out.println("tokensDef="+collector.tokensDefs);
System.out.println("actions="+collector.actions);
System.out.println("scopes="+collector.scopes);
*/
}
public void examine() {
@ -40,7 +43,7 @@ public class SymbolChecks {
checkTokenAliasRedefinitions(collector.tokensDefs);
checkRuleArgs(collector.rulerefs);
checkForTokenConflicts(collector.tokenIDRefs); // sets tokenIDs
checkForLabelConflicts(collector.rules);
checkForLabelConflicts(collector.ruleToLabelSpace, collector.rules);
}
public void checkForRuleConflicts(List<Rule> rules) {
@ -168,18 +171,43 @@ public class SymbolChecks {
* return values, parameters, and rule-scope dynamic attributes
* defined in surrounding rule.
*/
public void checkForLabelConflicts(List<Rule> rules) {
public void checkForLabelConflicts(MultiMap<String, LabelElementPair> ruleToLabelSpace,
List<Rule> rules) {
for (Rule r : rules) {
for (GrammarAST label : r.labelNameSpace.values()) {
checkForLabelConflict(r, label);
Map<String, LabelElementPair> labelNameSpace =
new HashMap<String, LabelElementPair>();
List<LabelElementPair> pairs = ruleToLabelSpace.get(r.name);
if ( pairs==null ) continue;
for (LabelElementPair labelPair : pairs) {
checkForLabelConflict(r, labelPair.label);
String name = labelPair.label.getText();
LabelElementPair prevLabelPair = labelNameSpace.get(name);
if ( prevLabelPair==null ) {
labelNameSpace.put(name, labelPair);
}
else {
// label already defined; if same type, no problem
if ( prevLabelPair.type != labelPair.type ) {
String typeMismatchExpr = labelPair.type+"!="+prevLabelPair.type;
ErrorManager.grammarError(
ErrorType.LABEL_TYPE_CONFLICT,
g.fileName,
labelPair.label.token,
name,
typeMismatchExpr);
}
}
}
}
}
public void checkForLabelConflict(Rule r, GrammarAST labelAssign) {
public void checkForLabelConflict(Rule r, GrammarAST labelID) {
ErrorType etype = ErrorType.INVALID;
Object arg2 = null;
String name = labelAssign.getChild(0).getText();
String name = labelID.getText();
if ( globalScopeNames.contains(name) ) {
etype = ErrorType.SYMBOL_CONFLICTS_WITH_GLOBAL_SCOPE;
}
@ -189,6 +217,7 @@ public class SymbolChecks {
else if ( tokenIDs.contains(name) ) {
etype = ErrorType.LABEL_CONFLICTS_WITH_TOKEN;
}
// else if ( r.ruleScope!=null && r.ruleScope.getAttribute(label.getText())!=null ) {
// etype = ErrorType.LABEL_CONFLICTS_WITH_RULE_SCOPE_ATTRIBUTE;
// arg2 = r.name;
@ -200,7 +229,7 @@ public class SymbolChecks {
// arg2 = r.name;
// }
if ( etype!=ErrorType.INVALID ) {
ErrorManager.grammarError(etype,g,labelAssign.token,name,arg2);
ErrorManager.grammarError(etype,g,labelID.token,name,arg2);
}
}
}

View File

@ -0,0 +1,49 @@
package org.antlr.v4.tool;
import org.antlr.v4.parse.ANTLRParser;
import java.util.BitSet;
public class LabelElementPair {
public static final BitSet tokenTypeForTokens = new BitSet();
static {
tokenTypeForTokens.set(ANTLRParser.TOKEN_REF);
tokenTypeForTokens.set(ANTLRParser.STRING_LITERAL);
tokenTypeForTokens.set(ANTLRParser.WILDCARD);
}
public GrammarAST label;
public GrammarAST element;
public LabelType type;
public LabelElementPair(Grammar g, GrammarAST label, GrammarAST element, int labelOp) {
this.label = label;
this.element = element;
// compute general case for label type
if ( element.getFirstDescendantWithType(tokenTypeForTokens)!=null ) {
if ( labelOp==ANTLRParser.ASSIGN ) type = LabelType.TOKEN_LABEL;
else type = LabelType.TOKEN_LIST_LABEL;
}
else if ( element.getFirstDescendantWithType(ANTLRParser.RULE_REF)!=null ) {
if ( labelOp==ANTLRParser.ASSIGN ) type = LabelType.RULE_LABEL;
else type = LabelType.RULE_LIST_LABEL;
}
// now reset if lexer and string
if ( g.getType() == ANTLRParser.LEXER ) {
if ( element.getFirstDescendantWithType(ANTLRParser.STRING_LITERAL)!=null ) {
if ( labelOp==ANTLRParser.ASSIGN ) type = LabelType.CHAR_LABEL;
}
}
else if ( g.getType() == ANTLRParser.TREE ) {
if ( element.getFirstDescendantWithType(ANTLRParser.WILDCARD)!=null ) {
if ( labelOp==ANTLRParser.ASSIGN ) type = LabelType.WILDCARD_TREE_LABEL;
else type = LabelType.WILDCARD_TREE_LIST_LABEL;
}
}
}
public String toString() {
return label.getText()+" "+type+" "+element.toString();
}
}

View File

@ -0,0 +1,15 @@
package org.antlr.v4.tool;
/** the various kinds of labels. t=type, id=ID, types+=type ids+=ID */
public enum LabelType {
RULE_LABEL,
TOKEN_LABEL,
RULE_LIST_LABEL,
TOKEN_LIST_LABEL,
CHAR_LABEL, // used in lexer for x='a'
SUBRULE_LABEL, // x=(...)
SUBRULE_LIST_LABEL, // x+=(...)
WILDCARD_TREE_LABEL, // Used in tree grammar x=.
WILDCARD_TREE_LIST_LABEL // Used in tree grammar x+=.
;
}

View File

@ -12,7 +12,8 @@ public class Rule {
/** All labels go in here (TODO: plus being split per the above lists) to
* catch dup label and label type mismatches.
*/
public Map<String, GrammarAST> labelNameSpace = new HashMap<String, GrammarAST>();
public Map<String, LabelElementPair> labelNameSpace =
new HashMap<String, LabelElementPair>();
public Rule(String name, GrammarASTWithOptions ast) {
this.name = name;