带有@init块的ANTLR4 lexer规则

带有@init块的ANTLR4 lexer规则,antlr4,Antlr4,我在我的ANTLR v3语法文件中定义了这个lexer规则——它是双引号中的数学文本。 我需要将其转换为ANTLR v4。ANTLR编译器在匹配lexer规则时抛出错误“语法错误:不匹配的输入”@“需要冒号”(在@init行中)。lexer规则能否包含@init块?这应该如何改写 DOUBLE_QUOTED_CHARACTERS @init { int doubleQuoteMark = input.mark(); int semiColonPos = -1; } : ('"'

我在我的ANTLR v3语法文件中定义了这个lexer规则——它是双引号中的数学文本。 我需要将其转换为ANTLR v4。ANTLR编译器在匹配lexer规则时抛出错误“语法错误:不匹配的输入”@“需要冒号”(在@init行中)。lexer规则能否包含@init块?这应该如何改写

DOUBLE_QUOTED_CHARACTERS
@init 
{
   int doubleQuoteMark = input.mark(); 
   int semiColonPos = -1;
}
: ('"' WS* '"') => '"' WS* '"' { $channel = HIDDEN; }
{
    RecognitionException re = new RecognitionException("Illegal empty quotes\"\"!", input);
    reportError(re);
}
| '"' (options {greedy=false;}: ~('"'))+ 
  ('"'|';' { semiColonPos = input.index(); } ('\u0020'|'\t')* ('\n'|'\r'))
{ 
    if (semiColonPos >= 0)
    {
        input.rewind(doubleQuoteMark);

        RecognitionException re = new RecognitionException("Missing closing double quote!", input);
        reportError(re);
        input.consume();            
    }
    else
    {
        setText(getText().substring(1, getText().length()-1));
    }
}
; 
样本数据:

  • “->抛出错误“非法空引号!”
  • “asd->抛出错误”缺少结束双引号!"
  • “text”->返回文本(有效输入,“…”的内容)

  • 当我的.g4语法导入一个lexer文件时,我就解决了这个问题。导入语法文件似乎会触发ANTLR4中许多未记录的缺陷。因此,最终我不得不停止使用import。 在我的例子中,一旦我将LEXER语法合并到解析器语法(一个.g4文件)中,我的@input和@after解析错误就消失了。我应该提交一个测试用例+bug,至少要将其记录下来。一旦我这样做,我将在这里更新。
    我模模糊糊地回忆起有关将lexer语法导入解析器的2-3个问题,这些问题触发了未记录的行为。这里将详细介绍stackoverflow。

    我认为这是正确的方法

    DOUBLE_QUOTED_CHARACTERS
    :
    {
       int doubleQuoteMark = input.mark();
       int semiColonPos = -1;
    }
    (
        ('"' WS* '"') => '"' WS* '"' { $channel = HIDDEN; }
        {
            RecognitionException re = new RecognitionException("Illegal empty quotes\"\"!", input);
            reportError(re);
        }
        | '"' (options {greedy=false;}: ~('"'))+
          ('"'|';' { semiColonPos = input.index(); } ('\u0020'|'\t')* ('\n'|'\r'))
        {
            if (semiColonPos >= 0)
            {
                input.rewind(doubleQuoteMark);
    
                RecognitionException re = new RecognitionException("Missing closing double quote!", input);
                reportError(re);
                input.consume();
            }
            else
            {
                setText(getText().substring(1, getText().length()-1));
            }
        }
    )
    ;
    
    上面也有一些错误,比如WS..=>,但我并不是在这个答案中纠正它们。只是为了简单起见。我从

    为了避免链接在某个时间后移动或失效,请按原样引用该文本:

    从4.2开始,Lexer操作可以出现在任何地方,而不仅仅是最外层备选方案的末尾。Lexer根据操作在规则中的位置在适当的输入位置执行操作。要为具有多个备选方案的角色执行单个操作,可以将Alt括在括号中,并将该操作放在n之后:

    END : ('endif'|'end') {System.out.println("found an end");} ;
    
    The action conforms to the syntax of the target language. ANTLR copies the action’s contents into the generated code verbatim; there is no translation of expressions like $x.y as there is in parser actions.
    
    Only actions within the outermost token rule are executed. In other words, if STRING calls ESC_CHAR and ESC_CHAR has an action, that action is not executed when the lexer starts matching in STRING.
    

    通过查看您的规则,我不清楚您打算与
    双引号字符匹配什么。您能给出一些有效的输入示例吗?我编辑了我的问题并添加了一些示例。LEXER规则不接受init和after块。