[antlr-interest] Why does antlr not know alternative?

James Ladd james_ladd at hotmail.com
Mon Jan 9 14:46:07 PST 2012


I have a grammar I am working on (below) and when in ANTLRWorks I try
to interpret the following against the rule "statements" I get a NoViableAlternativeException.

^ 12.

I can see that NUMBER has a component of it that can be a '.' hence the grammar issue.
Is it the start of the decimal part of a number or the end of a statement.

Note: ^ 12.5. works as I would expect.

What I don't know is how to overcome this situation?
I would have thought that if there is no digit after the '.' that things would be ok.

Please can you suggest a fix / approach?

Rgs, James.

grammar Temp;

options {
  language = Java;
}
@header {
  package st.redline.compiler;
}
@lexer::header {
  package st.redline.compiler;
}
@lexer::members {
  List<RecognitionException> exceptions = new ArrayList<RecognitionException>();
  public List<RecognitionException> getExceptions() { return exceptions; }
  public void reportError(RecognitionException e) { super.reportError(e); exceptions.add(e); }
}

program
  : primary* EOF
  ;    

primary returns [Primary primary]
  : WHITESPACE? 
    ( IDENTIFIER {primary = new Identifier($IDENTIFIER.text, $IDENTIFIER.line);}
    | NUMBER {primary = new Number($NUMBER.text, $NUMBER.line);} 
    | symbol_constant {primary = $symbol_constant.symbolConstant;}
    | CHARACTER_CONSTANT {primary = new CharacterConstant($CHARACTER_CONSTANT.text.substring(1), $CHARACTER_CONSTANT.line);} 
    | STRING {primary = new StringConstant($STRING.text, $STRING.line);}
    | array_constant {primary = $array_constant.arrayConstant; }
    | block {primary = $block.block;}
    | '(' expression WHITESPACE? ')'
    ) 
  ;

statements returns [Statements statements]
  : non_empty_statements? { statements = $non_empty_statements.nonEmptyStatements; }
  ;

non_empty_statements returns [Statements statements]
  : WHITESPACE? a='^'  expression '.' {statements = new AnswerStatements($a.line, $expression.expression);}
  ;

expression returns [Expression expression]
  :  WHITESPACE? IDENTIFIER WHITESPACE? ':=' e=expression {expression = new AssignmentExpression($IDENTIFIER.text, $IDENTIFIER.line, $e.expression);}
  | simple_expression {expression = $simple_expression.simpleExpression;}
  ;

simple_expression returns [SimpleExpression simpleExpression]
  @init { simpleExpression = new SimpleExpression(); }
  : primary {simpleExpression.add($primary.primary);}
  ;

block returns [Block block]
  : o= '[' WHITESPACE? block_arguments? WHITESPACE? temporaries? ']' {block = new Block($o.line, $block_arguments.blockArguments, $temporaries.temporaries);}
  ;

temporaries returns [List<Identifier> temporaries]
  @init { temporaries = new ArrayList<Identifier>(); }
  : ('|' | '||' | '|' WHITESPACE? '|')  WHITESPACE? (IDENTIFIER WHITESPACE? {temporaries.add(new Identifier($IDENTIFIER.text, $IDENTIFIER.line));})+ '|' WHITESPACE?
  ;

block_arguments returns [List<BlockArgument> blockArguments]
  @init { blockArguments = new ArrayList<BlockArgument>(); }
  : (BLOCK_ARGUMENT WHITESPACE? {blockArguments.add(new BlockArgument($BLOCK_ARGUMENT.text.substring(1), $BLOCK_ARGUMENT.line));})+ '|'? WHITESPACE?
  ;
    
array_constant returns [ArrayConstant arrayConstant]
  : h='#' array {arrayConstant = new ArrayConstant($array.array, $h.line);}
  ;

array returns [Array array]
  @init { array = new Array(); }
  : '(' (array_element {array.add($array_element.arrayElement);})* ')'
  ;

array_element returns [ArrayElement arrayElement]
  : WHITESPACE
  | NUMBER{arrayElement = new Number($NUMBER.text, $NUMBER.line);}
  | symbol {arrayElement = $symbol.symbol;}
  | STRING {arrayElement = new StringConstant($STRING.text, $STRING.line);}
  | CHARACTER_CONSTANT {arrayElement = new CharacterConstant($CHARACTER_CONSTANT.text.substring(1), $CHARACTER_CONSTANT.line);} 
  | array {arrayElement = $array.array;}
  ;

symbol_constant returns [SymbolConstant symbolConstant]
  : '#' symbol {symbolConstant = new SymbolConstant($symbol.symbol.value(), $symbol.symbol.line());}
  ;

symbol returns [Symbol symbol]
  @init { symbol = new Symbol(); }
  :  IDENTIFIER {symbol.valueAndLine($IDENTIFIER.text, $IDENTIFIER.line); }
  | BINARY_SELECTOR {symbol.valueAndLine($BINARY_SELECTOR.text, $BINARY_SELECTOR.line);}
  | (KEYWORD {symbol.addValueAndLine($KEYWORD.text, $KEYWORD.line);} )+    // Decision can match input such as "KEYWORD" using multiple alternatives: 1, 2
  ;

WHITESPACE:        (' '|'\t'|'\r'|'\n')+;
COMMENT:        '"' .* '"' {$channel = HIDDEN;};
BINARY_SELECTOR:    ('-' (SPECIAL_CHAR)?) | (SPECIAL_CHAR)+;
KEYWORD:        IDENTIFIER ':';
BLOCK_ARGUMENT:    ':' IDENTIFIER;
IDENTIFIER:        LETTER (LETTER | DIGIT)*;
NUMBER:        ((NUMBER_LEFT)? ('-')? DIGITS (NUMBER_RIGHT_P1)? (NUMBER_RIGHT_P2)?);
CHARACTER_CONSTANT:    '$' ('\'' | '"' | SPECIAL_CHAR | NORMAL_CHAR | DIGIT | LETTER);
STRING:        '\'' (~'\''|'\'\'')* '\'';

fragment NUMBER_LEFT:        DIGITS 'r';
fragment NUMBER_RIGHT_P1:    '.' DIGITS;
fragment NUMBER_RIGHT_P2:    'e' ('-')? DIGITS; 
fragment LETTER:        ('a'..'z' | 'A'..'Z');
fragment DIGIT:        '0'..'9';
fragment DIGITS:        DIGIT+;
fragment SPECIAL_CHAR:        '+'|'/'|'\\'|'*'|'~'|'<'|'>'|'='|'@'|'%'|'|'|'&'|'?'|'!'|',';
fragment NORMAL_CHAR:        '['|']'|'{'|'}'|'('|')'|'^'|'_'|';'|'$'|'#'|':'|'.'|'\'';






 		 	   		  


More information about the antlr-interest mailing list