2010-03-09 18 views

Respuesta

8

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

Cuestiones relacionadas