2011-11-29 72 views
3

我想構建一個解析器來分析一個大的輸入文件,但我不需要整個輸入文件,只需要它的一部分。在ANTLR中跳過輸入文件的一部分

對於〔實施例中,輸入文件可能看起來像這樣:

bla bla bla bla bla ... 

EVENT: e1 
type: t1 
version: 1 
additional-info: abc 

EVENT: e2 
type: t2 
version: 1 
uninteresting-info: def 

blu blu blu blu blu ... 

從該文件中,所有我想是有地圖上的事件的輸入(E1 => t1時,E2 => T2)。所有其他信息對我來說都不感興趣。

如何構建一個簡單的ANTLR語法來實現這一點?

回答

3

通過在詞法分析器中引入布爾標誌來跟蹤event-或type-關鍵字是否已經遇到。如果遇到過,詞法分析器應該跳過而不是跳過該單詞,其他所有單詞應該跳過

小演示:

grammar T; 

@lexer::members { 
    private boolean ignoreWord = true; 
} 

parse 
    : event* EOF 
    ; 

event 
    : Event w1=Word Type w2=Word 
    {System.out.println("event=" + $w1.text + ", type=" + $w2.text);} 
    ; 

Event 
    : 'EVENT:' {ignoreWord=false;} 
    ; 

Type 
    : 'type:' {ignoreWord=false;} 
    ; 

Word 
    : ('a'..'z' | 'A'..'Z' | '0'..'9')+ {if(ignoreWord) skip();} 
    ; 

NewLine 
    : ('\r'? '\n' | '\r') {ignoreWord=true; skip();} 
    ; 

Other 
    : . {skip();} 
    ; 

你可以用下面的類測試解析器:

import org.antlr.runtime.*; 

public class Main { 
    public static void main(String[] args) throws Exception { 
    String src = 
     "bla bla bla bla bla ... \n" + 
     "       \n" + 
     "prEVENT: ...    \n" + 
     "EVENTs: ...    \n" + 
     "       \n" + 
     "EVENT: e1    \n" + 
     "type: t1     \n" + 
     "version: 1    \n" + 
     "additional-info: abc  \n" + 
     "       \n" + 
     "EVENT: e2    \n" + 
     "type: t2     \n" + 
     "version: 1    \n" + 
     "uninteresting-info: def \n" + 
     "       \n" + 
     "blu blu blu blu blu ... \n"; 
    TLexer lexer = new TLexer(new ANTLRStringStream(src)); 
    TParser parser = new TParser(new CommonTokenStream(lexer)); 
    parser.parse(); 
    } 
} 

這將產生以下輸出:

java -cp antlr-3.3.jar org.antlr.Tool T.g 
javac -cp antlr-3.3.jar *.java 
java -cp .:antlr-3.3.jar Main 

event=e1, type=t1 
event=e2, type=t2 
+0

哇,就像一個魅力!謝謝。 –

+0

不客氣@ErelSegalHalevi。 –