这是来自Antlr superfluous Predicate required?的后续问题,其中我以简化的方式陈述了我的问题,但在那里无法解决。
我有以下语法,当我删除{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();}
;
答案 0 :(得分:1)
似乎没有MODULE
和LTLSPEC
之前的谓词,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' | '_' | '$' | '#' | '-')*;