1

The grammar below is failing to generate a parser with this error:

error(119): Sable.g4::: The following sets of rules are mutually left-recursive [expression]
1 error(s)

The error disappears when I comment out the embedded actions, but comes back when I make them effective.

Why are the actions bringing about such left-recursion that antlr4 cannot handle it?

grammar Sable;

options {}

@header {
    package org.sable.parser;
    import org.sable.parser.internal.*;
}

sourceFile              : statement* EOF;
statement               : expressionStatement (SEMICOLON | NEWLINE);
expressionStatement     : expression;

expression:
    {System.out.println("w");} expression '+' expression {System.out.println("tf?");}
    | IDENTIFIER
    ;

SEMICOLON               : ';';
RPARENTH                : '(';
LPARENTH                : ')';
NEWLINE:
    ('\u000D' '\u000A')
    | '\u000A'
    ;
WS                      : WhiteSpaceNotNewline -> channel(HIDDEN);
IDENTIFIER:
    (IdentifierHead IdentifierCharacter*)
    | ('`'(IdentifierHead IdentifierCharacter*)'`')
    ;

fragment DecimalDigit   :'0'..'9';

fragment IdentifierHead:
    'a'..'z'
    | 'A'..'Z'
    ;
fragment IdentifierCharacter:
    DecimalDigit
    | IdentifierHead
    ;
// Non-newline whitespaces are defined apart because they carry meaning in
// certain contexts, e.g. within space-aware operators.
fragment WhiteSpaceNotNewline    : [\u0020\u000C\u0009u000B\u000C];

UPDATE: the following workaround kind of solves this specific situation, but not the case when init/after-like actions are needed on a lesser scope - per choice, not per rule.

expression
    @init {
        enable(Token.HIDDEN_CHANNEL);
    }
    @after {
        disable(Token.HIDDEN_CHANNEL);  
    }:
    expression '+' expression
    | IDENTIFIER
    ;
  • 1
    It smells like [link](https://stackoverflow.com/questions/23626376/antlr4-mutual-left-recursion). If you submit a bug, I suggest that you reduce your grammar to the strict minimum necessary to focus on the problem, like : `grammar Sable; sourceFile : expression* EOF; expression : {System.out.println("w");} expression '+' expression {System.out.println("tf?");} | IDENTIFIER ; IDENTIFIER : [a-zA-Z]+ ; NEWLINE : '\r?' '\n' ; WS : [ \t] -> channel(HIDDEN); `. – BernardK Sep 27 '17 at 06:45
  • 1
    Thanks. I will try to reproduce it on an absolutely minimum grammar and submit a bug then. – AmazingWouldBeGreatBut Sep 27 '17 at 10:41

0 Answers0