带@init块的ANTLR4词法分析器规则

时间:2014-10-16 13:28:12

标签: antlr4

我在我的ANTLR v3语法文件中定义了这个词法分析器规则 - 它用双引号计算文本。 我需要将其转换为ANTLR v4。 ANTLR编译器抛出错误'语法错误:匹配词法分析器规则'(在@init行中)期望COLON不匹配输入'@'。词法分析器规则是否包含@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));
    }
}
; 

示例数据:

  1. “” - >抛出错误“非法空引号!”;
  2. “asd - >抛出错误”缺少关闭双引号!“
  3. “text” - >返回文本(有效输入,“......”的内容)

2 个答案:

答案 0 :(得分:0)

当我的.g4语法导入lexer文件时,我反击了这个问题。导入语法文件似乎在ANTLR4中引发了许多未记录的缺陷。所以最终我不得不停止使用导入。 在我的例子中,一旦我将LEXER语法合并到解析器语法(一个.g4文件)中,我的@input和@after解析错误就消失了。我应该提交一个测试用例+ bug,至少要记录下来。一旦我这样做,我会在这里更新。 我含糊地回忆起关于将词法分析器语法导入我的解析器中引发无证行为的2-3个问题。 stackoverflow上有很多内容。

答案 1 :(得分:0)

我认为这是正确的方法。

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 .. => ...,但我没有将其作为此答案的一部分进行更正。只是为了使事情简单。我从here

得到了提示

只是为了避免该链接在一段时间后移动或变得无效,请照原样引用该文本:

Lexer动作从4.2版本开始可以出现在任何地方,而不仅仅是最外层选项的结尾。词法分析器根据规则中动作的位置在适当的输入位置执行动作。要对具有多个替代选项的角色执行单个操作,可以将alt括在括号中,然后将该操作放在后面:

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.