2010-03-09 14 views

risposta

8

Questo può essere gestito utilizzando un semantic predicate.

Prima scrivi la tua grammatica in modo che non importi per quanto tempo sono le tue linee. Un esempio sarebbe simile a questa:

grammar Test; 

parse 
    : line* EOF 
    ; 

line 
    : Char+ (LineBreak | EOF) 
    | LineBreak // empty line! 
    ; 

LineBreak : '\r'? '\n' | '\r' ; 
Char  : ~('\r' | '\n') ; 

e quindi aggiungere il "predicato" alla regola 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') ; 

Il c+=Char sarà costruire un ArrayList contenente tutti i caratteri della linea. Il {$c.size()<=5}? provoca un'eccezione quando la dimensione s' il ArrayList supera 5.

ho anche aggiunto un metodo main nel parser modo da poter testare voi stessi:

// *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 

che sarà in uscita:

line 0:-1 rule line failed predicate: {$c.size()<=5}? 

HTH

Problemi correlati