我正在使用antlr 4.5为具有几种特殊注释格式的语言构建解析器,我想将其流式传输到不同的频道。
似乎antlr 4.5已经扩展了一个新的结构来声明额外的词法器通道:
摘自文档 https://theantlrguy.atlassian.net/wiki/display/ANTLR4/Lexer+Rules
我的从 4.5 开始,您还可以定义通道名称,例如枚举 在词法分析器规则之上使用以下构造:
频道 { 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
如果我将词法分析和解析器拆分为两个不同的文件,并使用导入语句在解析器中导入词法分析器,我仍然会收到与上述相同的错误,
使用整数常量而不是具有组合语法的名称
-> channel(10000)
产生以下错误
error(164): Scade6.g4:8:0: custom channels are not supported in combined grammars
如果我将词法分析和解析器拆分为两个文件并使用整数常量,则没有警告,但是对于可读性来说,它并不令人满意。
我能做些什么来正确命名额外的频道?(使用组合或单独的词法分析器/解析器规范,无首选项)
问候
我能做些什么来正确命名额外的频道?
不确定 v4.5(没有使用过),但在 v4.x 中,您始终可以这样定义通道(假设使用 Java):
grammar MyGrammar;
@lexer::members {
public static final int WHITESPACE = 1;
public static final int COMMENTS = 2;
}
...the rest of your grammar goes here...
WS : [ tnr]+ -> channel(WHITESPACE) ; // channel(1)
SL_COMMENT
: '//' .*? 'n' -> channel(COMMENTS) // channel(2)
;
如果您还没有"权威ANTLR 4参考"一书,我建议您掌握它。将为您节省大量时间。上面的例子来自那本书。