I'm using Antlr 3 under AntlrWorks 1.4.3 and I'm having trouble writing a grammar to ignore comment lines.
This is the grammar that exhibits the problem:
grammar Ex2;
@header {
import java.util.HashMap;
}
@members {
HashMap memory = new HashMap();
}
prog: stat+ ;
stat
: expr NEWLINE {System.out.println($expr.value);}
| ID '=' expr NEWLINE
{ memory.put($ID.text, new Integer($expr.value)); }
| NEWLINE
;
expr returns [int value]
: e=term {$value = $e.value;}
( '+' e=term {$value += $e.value;}
| '-' e=term {$value -= $e.value;}
)*
;
term returns [int value]
: e=fact {$value = $e.value; }
( '*' e=fact {$value *= $e.value;}
| '/' e=fact {$value /= $e.value;}
| '^' e=fact {
for(int i = 0; i < $e.value; i++)
$value *= $value;
}
)*;
fact returns [int value]
: INT {$value = Integer.parseInt($INT.text);}
| ID
{
Integer v = (Integer)memory.get($ID.text);
if ( v!=null ) $value = v.intValue();
else System.err.println("undefined variable "+$ID.text);
}
| '(' expr ')' {$value = $expr.value;}
;
COMMENT
: '--' ~('/r' | '/n')* {skip();}
;
ID
: ('a'..'z'|'A'..'Z')+
;
INT
: '0'..'9'+
;
NEWLINE
:'\r'? '\n'
;
WS
: (' '|'\t')+ {skip();}
;
I get this error
error(204): /../Ex2.g:46:16: duplicate token type '/n' when collapsing subrule into set
I would like to mention that almost every type of grammar that i try to debug using the COMMENT rule for the lexer crashes into the same error.
Please help and thank you in advance.
It's not:
COMMENT
: '--' ~('/r' | '/n')* {skip();}
;
but:
COMMENT
: '--' ~('\r' | '\n')* {skip();}
;
The problem is that /n
are two characters, and the negation operator only works on sets of single characters. You can't negate the two substrings '/r'
and '/n'
but you can negate the set of two (single) chars '\r'
and '\n'
.