[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