2012-07-10 54 views
1

這是一個來自Antlr superfluous Predicate required?的後續問題,我以簡化的方式說明了我的問題,但無法在此解決。
我有以下語法,當我刪除{true}?=>謂詞時,文本不再被識別。輸入字符串是MODULE main LTLSPEC H {} {} {o} FALSE;。請注意,尾部;未標記爲EOC,而是標記爲IGNORE。當我將{true}?=>添加到EOC規則;被標記爲EOC時。
我從antlr-v3.3和v3.4的命令行嘗試了這一點,沒有區別。在此先感謝,我感謝您的幫助。antlr gated predicate

grammar NusmvInput; 

options { 
    language = Java; 
}  
@parser::members{ 
public static void main(String[] args) throws Exception { 
    NusmvInputLexer lexer = new NusmvInputLexer(new ANTLRStringStream("MODULE main LTLSPEC H {} {} {o} FALSE;")); 
    NusmvInputParser parser = new NusmvInputParser(new CommonTokenStream(lexer)); 
    parser.specification(); 
    } 
}  
@lexer::members{ 
    private boolean inLTL = false; 
} 

specification : 
    module+ EOF 
    ; 
module : 
    MODULE module_decl  
    ; 

module_decl : 
    NAME parameter_list ; 
parameter_list 
    : (LP (parameter (COMMA parameter)*)? RP)? 
    ;  
parameter 
    : (NAME | INTEGER) 
    ;  
/************** 
*** LEXER 
**************/ 
COMMA 
    :{!inLTL}?=> ',' 
    ; 
OTHER 
    : {!inLTL}?=>('&' | '|' | 'xor' | 'xnor' | '=' | '!' | 
    '<' | '>' | '-' | '+' | '*' | '/' | 
     'mod' | '[' | ']' | '?') 
     ;  
RCP 
     : {!inLTL}?=>'}' 
     ;  
LCP 
     : {!inLTL}?=>'{' 
     ; 
LP 
    : {!inLTL}?=>'(' 
    ; 
RP 
    : {!inLTL}?=>')' 
    ; 
MODULE 
    : {true}?=> 'MODULE' {inLTL = false;} 
    ; 
LTLSPEC 
    : {true}?=> 'LTLSPEC' 
    {inLTL = true; skip(); } 
    ; 
EOC 
    : ';' 
    { 
     if (inLTL){ 
      inLTL = false; 
      skip(); 
     } 
    } 
    ; 
WS 
    : (' ' | '\t' | '\n' | '\r')+ {$channel = HIDDEN;} 
    ; 
COMMENT 
    : '--' .* ('\n' | '\r') {$channel = HIDDEN;} 
    ; 
INTEGER 
    : {!inLTL}?=> ('0'..'9')+ 
    ; 
NAME 
    :{!inLTL}?=> ('A'..'Z' | 'a'..'z') ('a'..'z' | 'A'..'Z' | '0'..'9' | '_' | '$' | '#' | '-')* 
    ; 
IGNORE 
    : {inLTL}?=> . {skip();} 
    ; 
+1

只需掃視你的語法,我已經看到兩個錯誤:一''^在'module'規則而沒有'輸出= AST'存在於選項, '規範'規則以'-'(減號)結尾。 – 2012-07-10 14:03:13

+0

對不起。將代碼複製到stackoverflow後,我刪除了樹重寫,並忘記了這些。 – 2012-07-10 14:16:48

回答

1

似乎沒有MODULELTLSPEC前的謂語時,NAME得到優先於他們,即使這些令牌的NAME令牌中定義。不管這是設計還是錯誤,我都不知道。

然而,你試圖解決它的方式似乎相當複雜。據我所知,你似乎想要忽略(或跳過)以LTLSPEC開始並以分號結尾的輸入。爲什麼不這樣做,而不是:

specification : module+ EOF; 
module   : MODULE module_decl; 
module_decl : NAME parameter_list; 
parameter_list : (LP (parameter (COMMA parameter)*)? RP)?;  
parameter  : (NAME | INTEGER);  

MODULE : 'MODULE'; 
LTLSPEC : 'LTLSPEC' ~';'* ';' {skip();}; 
COMMA : ','; 
OTHER : ('&' | '|' | 'xor' | 'xnor' | '=' | '!' | 
      '<' | '>' | '-' | '+' | '*' | '/' | 
      'mod' | '[' | ']' | '?') 
     ;  
RCP  : '}';  
LCP  : '{'; 
LP  : '('; 
RP  : ')'; 
EOC  : ';'; 
WS  : (' ' | '\t' | '\n' | '\r')+ {$channel = HIDDEN;}; 
COMMENT : '--' .* ('\n' | '\r') {$channel = HIDDEN;}; 
INTEGER : ('0'..'9')+; 
NAME : ('A'..'Z' | 'a'..'z') ('a'..'z' | 'A'..'Z' | '0'..'9' | '_' | '$' | '#' | '-')*; 
+0

你不能從這個例子中看到它,但'LTLSPEC' _may_可以用';'結束。它也可以通過'MODULE'或另一個'LTLSPEC'完成。當我嘗試類似'(〜(MODULE | LTLSPEC))''這奇怪的是不起作用,但現在不記得錯誤。 – 2012-07-11 07:52:04

+0

我想我基本上可以採納你的建議,如果我在LTLSPEC部分之前添加了一個人爲的'END'令牌,然後:'LTLSPEC:'LTLSPEC'〜END * {skip();};' – 2012-07-11 08:02:25

+1

@ HeinrichOdy,要小心否定'〜',只適用於單個字符! (或匹配單個字符的規則)。看到這個問答:http://stackoverflow.com/questions/8284919/negating-inside-lexer-and-parser-rules – 2012-07-11 08:23:03