Having the subsequent simple grammar, I'd like to simultaneously parse strings and numbers:
grammar Simple;
aRule : 'fs' '(' value["textual"] ')' ;
bRule : 'fi' '(' value["numeral"] ')' ;
cRule : 'f' '(' (value["textual"] | value["numeral"]) ')' ;
value[String k]
: {$k.equals("any") || $k.equals("textual")}? string
| {$k.equals("any") || $k.equals("numeral")}? numeric
;
string
: STRING_LITERAL
;
numeric
: ('+' | '-')? INTEGER_LITERAL
;
STRING_LITERAL
: '\'' (~('\'' | '\r' | '\n') | '\'' '\'' | NEWLINE)* '\''
;
INTEGER_LITERAL
: '0' | [1-9] [0-9]*
;
SPACES
: [ \t\r\n]+ -> skip
;
fragment NEWLINE : '\r'? '\n';
Now, I'd like to parse the following expressions:
fs('asdf') // works
fi(512) // works
f('asdf') // works
f(512) // fails
If I switch textual
and numeral
in cRule
, then f('asdf')
fails and f(512)
works.
Any ideas?
UPDATE1
grammar Simple;
rules : aRule | bRule | cRule ;
aRule : 'fs' '(' value["textual"] ')' ;
bRule : 'fi' '(' value["numeral"] ')' ;
cRule : 'f' '(' (tRule | nRule) ')' ;
tRule : value["textual"] ;
nRule : value["numeral"] ;
value[String k]
: {$k.equals("any") || $k.equals("textual")}? string
| {$k.equals("any") || $k.equals("numeral")}? numeric
;
string : STRING_LITERAL ;
numeric : ('+' | '-')? INTEGER_LITERAL ;
STRING_LITERAL : '\'' (~('\'' | '\r' | '\n') | '\'' '\'' | NEWLINE)* '\'' ;
INTEGER_LITERAL : '0' | [1-9] [0-9]* ;
SPACES : [ \t\r\n]+ -> skip ;
fragment NEWLINE : '\r'? '\n';
Even w/ this updated grammar --- as suggest by @GRosenberg --- for f(512)
I still get no viable alternative at input '512'
. Again fs('asdf')
, fi(512)
and f('asdf')
work.