Попробуйте что-то вроде этого (работает только для Java):
grammar Rule;
any : .*? EOF;
LPAREN : '(';
RPAREN : ')';
UUID : '"'[0-9a-fA-F]+'-'[0-9a-fA-F]+'-'[1-5][0-9a-fA-F]+'-'[89abAB][0-9a-fA-F]+'-'[0-9a-fA-F]+'"';
NUMERIC : [0-9]+ ( '.' [0-9]+ )? ;
PIDENTIFIER : IDENTIFIER {_input.LA(1) == '('}?;
IDENTIFIER : '#' [a-zA-Z$_] [a-zA-Z$_0-9]*;
WS : [ \r\t\u000C\n]+ -> skip;
OTHER : . ;
Если между идентификатором и (
разрешены пробелы, сделайте что-то вроде этого:
grammar Rule;
@lexer::members {
boolean spacesAndOpenParenAhead() {
for (int i = 1; ; i++) {
char ch = (char)_input.LA(i);
if (ch == '(') {
return true;
}
else if (ch != ' ' && ch != '\t' && ch != '\r' && ch != '\n') {
return false;
}
}
}
}
...
PIDENTIFIER : IDENTIFIER {spacesAndOpenParenAhead()}?;
IDENTIFIER : '#' [a-zA-Z$_] [a-zA-Z$_0-9]*;
Когда я запускаю приведенный ниже код в обоих моих примерах грамматик:
import org.antlr.v4.runtime.*;
public class Main {
public static void main(String[] args) throws Exception {
String source = "#someNameAttribute\n" +
"#someNameAttribute(\"2a3a796e-9870-4b88-9f2d-383eb9566613\", 10)";
RuleLexer lexer = new RuleLexer(CharStreams.fromString(source));
CommonTokenStream stream = new CommonTokenStream(lexer);
stream.fill();
for (Token t : stream.getTokens()) {
System.out.printf("%-20s `%s`%n",
RuleLexer.VOCABULARY.getDisplayName(t.getType()),
t.getText().replace("\n", "\\n"));
}
}
}
, на моей консоли печатается следующее:
IDENTIFIER `#someNameAttribute`
PIDENTIFIER `#someNameAttribute`
'(' `(`
UUID `"2a3a796e-9870-4b88-9f2d-383eb9566613"`
OTHER `,`
NUMERIC `10`
')' `)`