Esto puede ser manejado mediante el uso de un semantic predicate.
Primero escribe tu gramática de tal forma que no importe cuánto tiempo duran tus líneas. Un ejemplo sería el siguiente:
grammar Test;
parse
: line* EOF
;
line
: Char+ (LineBreak | EOF)
| LineBreak // empty line!
;
LineBreak : '\r'? '\n' | '\r' ;
Char : ~('\r' | '\n') ;
y luego añadir el "determinante" a la regla line
:
grammar Test;
@parser::members {
public static void main(String[] args) throws Exception {
String source = "abcde\nfghij\nklm\nnopqrst";
ANTLRStringStream in = new ANTLRStringStream(source);
TestLexer lexer = new TestLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
TestParser parser = new TestParser(tokens);
parser.parse();
}
}
parse
: line* EOF
;
line
: (c+=Char)+ {$c.size()<=5}? (LineBreak | EOF)
| LineBreak // empty line!
;
LineBreak : '\r'? '\n' | '\r' ;
Char : ~('\r' | '\n') ;
El c+=Char
construirá un ArrayList
que contiene todos los caracteres en la línea. El {$c.size()<=5}?
provoca a lanzar una excepción cuando el tamaño de la ArrayList
's es superior a 5.
También he añadido un método principal en el analizador para que pueda probar por sí mismo:
// *nix/MacOSX
java -cp antlr-3.2.jar org.antlr.Tool Test.g
javac -cp antlr-3.2.jar *.java
java -cp .:antlr-3.2.jar TestParser
// Windows
java -cp antlr-3.2.jar org.antlr.Tool Test.g
javac -cp antlr-3.2.jar *.java
java -cp .;antlr-3.2.jar TestParser
cual seria:
line 0:-1 rule line failed predicate: {$c.size()<=5}?
HTH