[antlr-interest] Having trouble with creating a parser for my desired grammar. Running afoul of multiple alternatives warnings

Jarrod Roberson jarrod at vertigrated.com
Mon Nov 14 20:47:10 PST 2011


I am trying to write a parser for the following syntax

hypotenuse(a,b) ->
  sqr(x) -> x * x,
  sqr(sqr(b) + sqr(b)).

print(hypotenuse(2,3)).

Where , and . are my statement separator and statement eol respectively.

I am having an impossible time trying to figure out how to specify the
function rule to allow me to nest functions inside of other functions
without running afoul of ambiguities warnings.

23:37:47] warning(200): funcy.g:10:11: Decision can match input such as
"ID" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
[23:37:47] error(201): funcy.g:10:11: The following alternatives can never
be matched: 2


I really want to be able to use the above syntax without having to pepper
the code with keywords like `func` or `var` etc.

Here is my grammar, are there any ways to resolve these ambiguities with
predicates of some sort that I haven't been able to figure out?

I have read up on Google about them, but I can't get them to work with the
parser rules to remove the ambiguities.

grammar funcy;

options {
    output = AST;
    language = Java;
}
program : (statement'.')* ;

statement : expression
          | assignment
          ;

assignment : ID '->' expression
           | ATOM '->' ( string | number )
           | function '->' statement ((','statement)=> ',' statement)* ;

args : expression (',' expression)*;

function : ID '(' args ')' ;

string : UNICODE_STRING;
number : HEX_NUMBER
       | (INTEGER '.' INTEGER)=> INTEGER '.' INTEGER
       | INTEGER;

// expressions

term : '(' expression ')'
     | number
     | string
     | function
     | ID
     | ATOM
     ;

negation : '!'* term;

unary : ('+'|'-')* negation;

mult : unary (('*' | '/' | ('%'|'mod') ) unary)*;

add : mult (('+' | '-') mult)*;

relation : add (('=' | '!=' | '<' | '<=' | '>=' | '>') add)*;
expression : relation (('&&' | '||') relation)*;

// LEXER ================================================================

HEX_NUMBER : '0x' HEX_DIGIT+;

INTEGER : DIGIT+;

UNICODE_STRING : '"' ( ESC | ~('\u0000'..'\u001f' | '\\' | '\"' ) )* '"'
                ;

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

fragment
ESC : '\\' ( UNI_ESC |'b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\' );

fragment
UNI_ESC : 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT;

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

fragment
DIGIT : ('0'..'9');

ATOM : (('A'..'Z'|'_')+)=> ('A'..'Z'|'0'..'9'|'_')+;

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

COMMENT : '/*' .* '*/' {$channel = HIDDEN;};


More information about the antlr-interest mailing list