Antlr 可以忽略某些关键字吗?

问题描述

我是 Antlr 的新手,但我正在尝试更改现有项目中的一些语法。语法示例如下

...

factor 
    : ava | NOT^ factor | (LPAREN! expr RPAREN!) ;
    
ava
    : key=ALPHANUM EQUALS value=ALPHANUM ;

AND     
    : ('and' | 'AND');

OR  
    : ('or' | 'OR'); 
    

NOT
    : ('not' | 'NOT');  


ALPHANUM 
    : (ALPHA | DIGIT | LIMITED_SYMBOLS)+ ;
        
    
WHITESPACE 
    : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+ { $channel = HIDDEN; } ;

fragment ALPHA 
        : ('a'..'z' | 'A'..'Z') ;

fragment DIGIT 
    : '0'..'9' ;
    
fragment LIMITED_SYMBOLS
    : ('.' | '!' | '@' | '#' | '$' | '%' | '^' | '&' | '*' | '-' | '_' | '+' | '~' | ':' | '/' | '?' | '|');

语法应该解析类似 a=10 AND s=1 AND s=2((a=9 AND s=1) AND s=2)内容

问题是是否可以忽略任何不是 s={ANYTHING}内容。所以从上面的例子来看。 AST 将减少到

s=1 AND s=2((s=1) AND s=2)

这甚至可以通过改变语法来实现吗?

解决方法

这甚至可以通过改变语法来实现吗?

没有

当然,树重写是有可能的,但它会涉及到很多目标特定的代码被嵌入到你的语法中。最好的解决方案是只解析整个输入,然后遍历 AST 并丢弃某些以 s 开头的子树(以纯代码形式)。