Antlr4 antlr 4.5中的额外通道

Antlr4 antlr 4.5中的额外通道,antlr4,channels,Antlr4,Channels,我正在使用Antlr4.5为一种具有几种特殊注释格式的语言构建一个解析器,我希望将其流式传输到不同的通道 antlr 4.5似乎已经扩展了一个新的结构,用于声明额外的lexer通道: 从文档中摘录 从4.5开始,您还可以像枚举一样定义通道名称 使用lexer规则之上的以下构造: 通道{WSCHANNEL,MYHIDDEN} 我的词法分析和解析规则位于单个文件中,我的代码如下所示: channels { ANNOT_CHANNEL, FORMAL_SPEC_CH

我正在使用Antlr4.5为一种具有几种特殊注释格式的语言构建一个解析器,我希望将其流式传输到不同的通道

antlr 4.5似乎已经扩展了一个新的结构,用于声明额外的lexer通道:

从文档中摘录

从4.5开始,您还可以像枚举一样定义通道名称 使用lexer规则之上的以下构造:

通道{WSCHANNEL,MYHIDDEN}

我的词法分析和解析规则位于单个文件中,我的代码如下所示:

    channels {
       ANNOT_CHANNEL,
       FORMAL_SPEC_CHANNEL,
       DOC_CHANNEL,
       COMMENT_CHANNEL,
       PRAGMAS_CHANNEL
    }
。。。正在分析规则

// expression annotation (sent to a special channel)
    ANNOT: (EOL_ANNOT | LUS_ANNOT | C_ANNOT) -> channel(ANNOT_CHANNEL) ;
    fragment LUS_ANNOT: '(*!' ( COMMENT | . )*? '*)' ;
    fragment C_ANNOT: '/*!' ( COMMENT | . )*? '*/' ;
    fragment EOL_ANNOT: ('--!' | '//!') .*? EOL ;

    // formal specification annotations (sent to a special channel)
    FORMAL_SPEC: (EOL_SPEC | LUS_SPEC | C_SPEC ) -> channel(FORMAL_SPEC_CHANNEL) ;
    fragment LUS_SPEC: '(*@' ( COMMENT | . )*? '*)' ;
    fragment C_SPEC: '/*@' ( COMMENT | . )*? '*/' ;
    fragment EOL_SPEC: ('--@' | '//@' | '--%') .*? EOL;

    // documentation annotation (sent to a special channel)
    DOC: ( EOL_DOC |LUS_DOC | C_DOC ) -> channel(DOC_CHANNEL);
    fragment LUS_DOC: '(**' ( COMMENT | . )*? '*)' ;
    fragment C_DOC: '/**' ( COMMENT | . )*? '*/' ;
    fragment EOL_DOC: ('--*' | '//*') .*? EOL;

    // standard comment (sent to a special channel)
    COMMENT: ( EOL_COMMENT | LUS_COMMENT | C_COMMENT ) -> channel(COMMENT_CHANNEL);
    fragment LUS_COMMENT: '(*' ( COMMENT | . )*? '*)' ;
    fragment C_COMMENT: '/*' ( COMMENT |. )*? '*/' ;
    fragment EOL_COMMENT: ('--' | '//') .*? EOL;

    // pragmas are sent to a special channel
    PRAGMA: '#pragma' CHARACTER* '#end' -> channel(PRAGMAS_CHANNEL);
然而,我仍然得到这个类似4.4的错误

warning(155): Scade6.g4:550:52: rule ANNOT contains a lexer command with an unrecognized constant value; lexer interpreters may produce incorrect output
warning(155): Scade6.g4:556:56: rule FORMAL_SPEC contains a lexer command with an unrecognized constant value; lexer interpreters may produce incorrect output
warning(155): Scade6.g4:562:45: rule DOC contains a lexer command with an unrecognized constant value; lexer interpreters may produce incorrect output
warning(155): Scade6.g4:568:62: rule COMMENT contains a lexer command with an unrecognized constant value; lexer interpreters may produce incorrect output
warning(155): Scade6.g4:574:47: rule PRAGMA contains a lexer command with an unrecognized constant value; lexer interpreters may produce incorrect output
如果我将lexer和parser拆分为两个不同的文件,并使用import语句在解析器中导入lexer,我仍然会得到与上面相同的错误

使用整数常量而不是具有组合语法的名称

-> channel(10000)
产生以下错误

error(164): Scade6.g4:8:0: custom channels are not supported in combined grammars
若我将lexer和parser拆分为两个文件,并使用整型常量,并没有任何警告,但它的可读性并不令人满意

我能做些什么来正确命名额外的频道吗?(使用组合或单独的lexer/parser规范,无首选项)

问候,

我能做些什么来正确命名额外的频道吗

不确定v4.5(没有使用它),但在v4.x中,您总是可以这样定义通道(假设使用java):


如果你还没有这本书,我建议你去拿。这会节省你很多时间。上面的例子来自那本书。

事实上,你推荐的书解决方案不起作用,产生了我的帖子中描述的症状。ANTLR不知道空格和注释被定义为lexer成员,并发出警告。这个错误是在4.2版本中报告的,请参见,直到v4.5版本引入了
channels{}
构造,才得到解决。遗憾的是,它似乎没有达到预期的效果,至少从我的实验来看是这样。这本书的解决方案确实有效。刚刚在antlr4.4上进行了测试。它确实会产生相同的警告,但根据错误判断,该警告仅适用于解释器。我猜想您的实际应用程序将使用与此警告无关的生成代码me@garyM试着把频道放在顶部,就在
lexer grammar blah;
grammar MyGrammar;

@lexer::members {
    public static final int WHITESPACE = 1;
    public static final int COMMENTS = 2;
}

...the rest of your grammar goes here...

WS  :   [ \t\n\r]+ -> channel(WHITESPACE) ;  // channel(1)

SL_COMMENT
    :   '//' .*? '\n' -> channel(COMMENTS)   // channel(2)
    ;