Fixes #670. Left recursive rules imported into a root grammar caused an error. All tests pass in all targets.

This commit is contained in:
Terence Parr 2015-01-12 13:05:03 -08:00
parent 64f6e196b2
commit 4f0f361d93
2 changed files with 19 additions and 5 deletions

View File

@ -92,7 +92,6 @@ public class LeftRecursiveRuleTransformer {
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);
}
@ -131,11 +130,15 @@ public class LeftRecursiveRuleTransformer {
}
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();

View File

@ -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
@ -288,6 +297,7 @@ public class Grammar implements AttributeResolver {
this.ast = ast;
this.name = (ast.getChild(0)).getText();
this.tokenStream = ast.tokenStream;
this.originalTokenStream = this.tokenStream;
initTokenSymbolTables();
}
@ -343,6 +353,7 @@ public class Grammar implements AttributeResolver {
}
this.tokenStream = ast.tokenStream;
this.originalTokenStream = this.tokenStream;
// ensure each node has pointer to surrounding grammar
final Grammar thiz = this;