1

这是来自Antlr的后续问题,需要多余的谓词吗?我以简化的方式陈述了我的问题,但是在那里无法解决。
我有以下语法,当我删除{true}?=>谓词时,文本不再被识别。输入字符串是MODULE main LTLSPEC H {} {} {o} FALSE;。请注意,尾随;未标记为 EOC,而是标记为 IGNORE。当我添加{true}?=>到 EOC 规则时;,它被标记为 EOC。
我用 antlr-v3.3 和 v3.4 从命令行尝试了这个,没有区别。在此先感谢,感谢您的帮助。

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();}
    ;
4

1 回答 1

1

似乎在 and 之前没有谓词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' | '_' | '$' | '#' | '-')*;
于 2012-07-10T15:59:00.580 回答