[antlr-interest] Puzzled

Brad Cox bradjcox at gmail.com
Mon Mar 26 16:59:30 PDT 2012


Could someone please explain why I'm getting this error? Or better yet, how
to fix it?

[19:39:46] error(211): XacmlPL.g:64:35: [fatal] rule boolean has non-LL(*)
decision due to recursive rule invocations reachable from alts 2,3.
 Resolve by left-factoring or using syntactic predicates or using
backtrack=true option.

Here's the grammar. Its a VERY rough first cut at a friendlier notation for
XACML than the XML razor wire defined by the standard. I included the whole
thing for completeness; the errors are in the very first rule (boolean).

grammar XacmlPL;

tokens
{
EQ='eq' ;
GE='ge' ;
 GT='gt' ;
LE='le' ;
LT='lt' ;
 NOF='nof' ;
NOT='not' ;
  ADD='add' ;
  ABS='abs' ;
  DBL='dbl' ;
  DIV='div' ;
  FLR='flr' ;
  INT='int' ;
  MOD='mod' ;
  MUL= 'mul' ;
  NLS='normalizeSpace' ;
  NLC='normalizeToLowerCase' ;
  RND='rnd' ;
  SUB= 'sub' ;
  QUOT='"' ;
ANYURI= 'anyUri';
 BASE64= 'base64';
BOOLEAN= 'boolean';
DATE= 'date';
 DATETIME= 'dateTime';
DAYTIMEDURATION= 'dayTimeDuration';
 DOUBLE= 'double';
HEX= 'hex';
INTEGER= 'integer';
 RFC822= 'rfc822';
STRING= 'string';
TIME= 'time';
 X500= 'x500';
YEARMONTHDURATION= 'yearMonthDuration';
}

@members
{
    public static void main(String[] args) throws Exception
    {
        SimpleCalcLexer lex = new SimpleCalcLexer(new
ANTLRFileStream(args[0]));
        CommonTokenStream tokens = new CommonTokenStream(lex);
        SimpleCalcParser parser = new SimpleCalcParser(tokens);
        try
        {
            parser.expr();
        }
        catch (RecognitionException e)
        {
            e.printStackTrace();
        }
    }
}
/*
| EQ date ',' date ')'
 | EQ dateTime ',' dateTime ')'
*/
boolean
: BOOLEAN_CONSTANT
 | ( EQ | GE | GT | LT | LE ) '(' ( (string ',' string) | (integer ','
integer) | (double ',' double) ) ')'
 | (NOF | NOT) '(' boolean ')'
  ;

integer
: INTEGER_CONSTANT
  | (ADD | SUB | MUL | DIV) '(' (integer ',' integer) ')'
  | (MOD | ABS) '(' integer ')'
//  | INT '(' double ')'
  ;

double
  : DOUBLE_CONSTANT
  | (ADD | SUB | MUL | DIV)  '(' ( double ',' double ) ')'
  | (ABS | RND | FLR) '(' double ')'
//  | DBL '(' integer ')'
  ;

string
: STRING_CONSTANT
  | (NLS | NLC) '(' string ')'
  ;

/*
dateTime
  : ADD dateTime ',' dayTimeDuration ')'
//  | ADD dateTime ',' yearMonthDuration ')'
  | SUB dateTime ',' dayTimeDuration ')'
  | SUB dateTime ',' yearMonthDuration ')'
  ;

date
  : ADD date ',' yearMonthDuration ')'
  | SUB date ',' yearMonthDuration ')'
  ;
*/
anyUriBag
: ANYURI STRING_LIST
;
base64Bag
 : BASE64 STRING_LIST
;
booleanBag
: BOOLEAN STRING_LIST
 ;
dateBag
: DATE STRING_LIST
;
dateTimeBag
: DATETIME STRING_LIST
;
dayTimeDurationBag
 : DAYTIMEDURATION STRING_LIST
;
doubleBag
: DOUBLE STRING_LIST
 ;
hexBag
: HEX STRING_LIST
;
integerBag
: INTEGER STRING_LIST
;
rfc822Bag
: RFC822 STRING_LIST
 ;
stringBag
: STRING STRING_LIST
;
timeBag
: TIME STRING_LIST
;
x500Bag
: X500 STRING_LIST
 ;
yearMonthDurationBag
: YEARMONTHDURATION STRING_LIST
;

time
: 'time()'
;
dayTimeDuration
 : 'dayTimeDuration()'
;
yearMonthDuration
: 'yearMonthDuration()'
 ;
anyUri
: 'anyUri()'
;
x500Name
: 'x500Name()'
;
rfc822Name
: 'rfc822Name()'
 ;
hexBinary
: 'hexBinary()'
;
base64
: 'base64()'
;

COMMENT
: '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
 | '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
;

WS
:( ' '
  | '\t'
  | '\r'
  | '\n'
  ) {$channel=HIDDEN;}
  ;

fragment BOOLEAN_CONSTANT
: 'true'
 | 'false'
;

fragment INTEGER_CONSTANT
: (DIGIT)+
  ;

DOUBLE_CONSTANT
  :  INTEGER_CONSTANT? '.' INTEGER_CONSTANT EXPONENT?
//  |  '.' INTEGER_CONSTANT + EXPONENT?
//  |   ('0'..'9')+ EXPONENT
  ;

STRING_CONSTANT
  :  '"' ( ESC_SEQ | ~('\\'|'"') )* '"'
  ;

STRING_LIST
: '(' STRING_CONSTANT ( ',' STRING_CONSTANT )* ')'
 ;

CHAR
:  '\'' ( ESC_SEQ | ~('\''|'\\') ) '\''
  ;

fragment DIGIT
: '0'..'9'
;
fragment EXPONENT
: ('e'|'E') ('+'|'-')? ('0'..'9')+
;

fragment HEX_DIGIT
: ('0'..'9'|'a'..'f'|'A'..'F')
;

fragment ESC_SEQ
    :   '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
    |   UNICODE_ESC
    |   OCTAL_ESC
    ;

fragment OCTAL_ESC
    :   '\\' ('0'..'3') ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7')
    ;

fragment UNICODE_ESC
    :   '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
    ;

fragment SIGN
    :   ('+'|'-')
    ;

NUMBER_OR_RANGEOP
    :   SIGN? DIGIT+
        (
            { input.LA(2) != '.' }? => '.' DIGIT* { $type = DECIMAL; }
            | { $type = INTEGER; }
        )
    |   SIGN '.' DIGIT+ { $type = DECIMAL; }
    |   '.'
        (
        DIGIT+ { $type = DECIMAL; }
        | '.' {$type = RANGEOP; }
        | {$type = DEREF; } )
    ;

/*
ID
: ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
    ;
*/


More information about the antlr-interest mailing list