Skip to content

Commit

Permalink
Fixes #670. Left recursive rules imported into a root grammar caused …
Browse files Browse the repository at this point in the history
…an error. All tests pass in all targets.
  • Loading branch information
parrt committed Jan 12, 2015
1 parent 64f6e19 commit 4f0f361
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 5 deletions.
Expand Up @@ -92,7 +92,6 @@ public void translateLeftRecursiveRules() {
for (Rule r : rules) {
if ( !Grammar.isTokenName(r.name) ) {
if ( LeftRecursiveRuleAnalyzer.hasImmediateRecursiveRuleRefs(r.ast, r.name) ) {
g.originalTokenStream = g.tokenStream;
boolean fitsPattern = translateLeftRecursiveRule(ast, (LeftRecursiveRule)r, language);
if ( fitsPattern ) leftRecursiveRuleNames.add(r.name);
}
Expand Down Expand Up @@ -131,11 +130,15 @@ public boolean translateLeftRecursiveRule(GrammarRootAST ast,
}
if ( !isLeftRec ) return false;

// replace old rule's AST
// replace old rule's AST; first create text of altered rule
GrammarAST RULES = (GrammarAST)ast.getFirstChildWithType(ANTLRParser.RULES);
String newRuleText = leftRecursiveRuleWalker.getArtificialOpPrecRule();
// System.out.println("created: "+newRuleText);
RuleAST t = parseArtificialRule(g, newRuleText);
// now parse within the context of the grammar that originally created
// the AST we are transforming. This could be an imported grammar so
// we cannot just reference this.g because the role might come from
// the imported grammar and not the root grammar (this.g)
RuleAST t = parseArtificialRule(prevRuleAST.g, newRuleText);

// reuse the name token from the original AST since it refers to the proper source location in the original grammar
((GrammarAST)t.getChild(0)).token = ((GrammarAST)prevRuleAST.getChild(0)).getToken();
Expand Down
15 changes: 13 additions & 2 deletions tool/src/org/antlr/v4/tool/Grammar.java
Expand Up @@ -155,10 +155,19 @@ public class Grammar implements AttributeResolver {

public String name;
public GrammarRootAST ast;
/** Track stream used to create this grammar */

/** Track token stream used to create this grammar */
@NotNull
public final org.antlr.runtime.TokenStream tokenStream;
/** If we transform grammar, track original unaltered token stream */

/** If we transform grammar, track original unaltered token stream.
* This is set to the same value as tokenStream when tokenStream is
* initially set.
*
* If this field differs from tokenStream, then we have transformed
* the grammar.
*/
@NotNull
public org.antlr.runtime.TokenStream originalTokenStream;

public String text; // testing only
Expand Down Expand Up @@ -288,6 +297,7 @@ public Grammar(Tool tool, @NotNull GrammarRootAST ast) {
this.ast = ast;
this.name = (ast.getChild(0)).getText();
this.tokenStream = ast.tokenStream;
this.originalTokenStream = this.tokenStream;

initTokenSymbolTables();
}
Expand Down Expand Up @@ -343,6 +353,7 @@ public Grammar(String fileName, String grammarText, Grammar tokenVocabSource, @N
}

this.tokenStream = ast.tokenStream;
this.originalTokenStream = this.tokenStream;

// ensure each node has pointer to surrounding grammar
final Grammar thiz = this;
Expand Down

0 comments on commit 4f0f361

Please sign in to comment.