Parsing ANTLR lexer禁用令牌,然后重新启用它们,但无法按预期工作

Parsing ANTLR lexer禁用令牌,然后重新启用它们,但无法按预期工作,parsing,antlr,grammar,antlr4,Parsing,Antlr,Grammar,Antlr4,所以我有一个lexer,它定义了一个标记,以便在布尔属性上启用/禁用它 我创建一个输入流并解析一个文本。我的标记名为PHRASE\u TEXT,应该与此模式下的任何内容匹配“'('\\'~[]\.~('\'\''\'.'\')'”“{phrasenabled}” 我将“foo-bar”标记化,并按预期获得一个标记。在lexer上将属性设置为false并使用相同的文本对其调用setInputStream后,我获得了“foo,bar”因此得到了两个标记,而不是一个。这也是预期的行为 再次将属性设置为

所以我有一个lexer,它定义了一个标记,以便在布尔属性上启用/禁用它

我创建一个输入流并解析一个文本。我的标记名为
PHRASE\u TEXT
,应该与此模式下的任何内容匹配
“'('\\'~[]\.~('\'\''\'.'\')'”“{phrasenabled}”

我将
“foo-bar”
标记化,并按预期获得一个标记。在lexer上将属性设置为
false
并使用相同的文本对其调用
setInputStream
后,我获得了
“foo,bar”
因此得到了两个标记,而不是一个。这也是预期的行为

再次将属性设置为
true
时会出现问题。我希望相同的文本标记整个1标记
“foo bar“
但改为标记为以前的2个标记。这是我的错误吗?我做错了什么?我试着使用标记器的新实例并重用同一个实例,但这两种方法似乎都不起作用。提前谢谢

编辑:我的部分语法如下

grammar LuceneQueryParser;

@header{package com.amazon.platformsearch.solr.queryparser.psclassicqueryparser;}

@lexer::members {
    public boolean phrases = true;
}

@parser::members {
    public boolean phraseQueries = true;
}

mainQ : LPAREN query RPAREN
      | query
      ;

query : not ((AND|OR)? not)* ;

andClause : AND ;
orClause  : OR ;

not : NOT? modifier? clause;

clause : qualified                        
       | unqualified                          
       ;

unqualified : LBRACK range_in LBRACK
            | LCURL range_out RCURL
            | truncated
            | {phraseQueries}? quoted
            | LPAREN query RPAREN
            | normal
            ;

truncated : TERM_TEXT_TRUNCATED;
range_in  : (TERM_TEXT|STAR) TO (TERM_TEXT|STAR);
range_out : (TERM_TEXT|STAR) TO (TERM_TEXT|STAR);

qualified : TERM_TEXT COLON unqualified ;

normal : TERM_TEXT;
quoted : PHRASE_TEXT;

modifier : PLUS
         | MINUS
         ;

PHRASE_TEXT : '"' (ESCAPE|~('\"'|'\\'))+ '"' {phrases}?;
TERM_TEXT : (TERM_CHAR|ESCAPE)+;
TERM_CHAR  : ~(' ' | '\t' | '\n' | '\r' | '\u3000'
           | '\\' | '\'' | '(' | ')' | '[' | ']' | '{' | '}'
           | '+' | '-' | '!' | ':' | '~' | '^'
           | '*' | '|' | '&' | '?' );


ESCAPE : '\\' ~[];

问题似乎是,在我将短语设置为false,然后再次设置为true之后,似乎没有更多的标记被识别为短语\文本。我知道作为一个指导原则,我应该明确定义我的语法,但这基本上就是它最终的结果:根据情况,以两种不同的方式用引号标记字符串。

我必须用我的一位同事指出的答案来更新这一点。lexer生成的类在该类的所有实例之间共享一个静态DFA[]数组。一旦属性设置为false而不是默认的true,所有对象实例的决策树都会发生明显的更改。解决方法是,必须为我正在修改的属性的true和false实例分离DFA[]数组。我认为使该数组不是静态的代价太高,我实在想不出其他修复方法。

为了回答这个问题,我需要更多地了解语法和调用代码。您可能希望了解ANTLR4对的支持,并尝试从代码中触发切换机制。我相信这个特性是为了支持一些情况,比如在HTML中嵌入PHP。