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

MODULEandの前に述語がないと、これらのトークンがトークンの前に定義されていてもLTLSPEC、が優先されるようです。これが仕様なのかバグなのか、私にはわかりません。NAMENAME

ただし、それを解決しようとしている方法はかなり複雑に思えます。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 に答える