在ANTLR 2上,注释语法是这样的,
// Single-line comments
SL_COMMENT
: (options {warnWhenFollowAmbig=false;}
: '--'( { LA(2)!='-' }? '-' | ~('-'|'\n'|'\r'))* ( (('\r')? '\n') { newline(); }| '--') )
{$setType(Token.SKIP); }
;
但是,将其移植到ANTLR 3时,
SL_COMMENT
: (
: '--'( { input.LA(2)!='-' }? '-' | ~('-'|'\n'|'\r'))* ( (('\r')? '\n') | '--') )
{$channel = HIDDEN;}
;
因为没有其他选项{warnWhenFollowAmbig=false;}
,无法正确解析以下注释,
-- some comment -- some not comment
那么,为ANTLR 3定义这个SL_COMMENT规则的可行方法是什么?
答案 0 :(得分:1)
就个人而言,我喜欢将语法规则保持为“空”。在这种情况下,如果输入中的后两个字符为true
,我将创建一个返回"--"
的词法分析器方法。只要不这种情况,请匹配\r
和\n
以外的任何字符,并重复该次数零次或更多次,直到遇到可选的"--"
为止。请注意,我最后没有添加新行,因为最后不一定有新行(也可能是EOF
)。此外,\r
和\n
可能会与放在SPACE
频道上的HIDDEN
规则匹配:所以按照我的建议做这件事并没有什么害处。
演示:
...
@lexer::members {
private boolean endCommentAhead() {
return input.LA(1) == '-' && input.LA(2) == '-';
}
}
...
SL_COMMENT
: '--' ({!endCommentAhead()}?=> ~('\r' | '\n'))* '--'?
;
...
如果您不喜欢词法分析器成员块,您只需执行以下操作:
SL_COMMENT
: '--' ({!(input.LA(1) == '-' && input.LA(2) == '-')}?=> ~('\r' | '\n'))* '--'?
;
一个小而完整的演示:
grammar T;
@parser::members {
public static void main(String[] args) throws Exception {
String source = "12 - 34 -- foo - bar -- 42 \n - - 5678 -- more comments 666\n--\n--";
TLexer lexer = new TLexer(new ANTLRStringStream(source));
TParser parser = new TParser(new CommonTokenStream(lexer));
parser.parse();
}
}
@lexer::members {
private boolean endCommentAhead() {
return input.LA(1) == '-' && input.LA(2) == '-';
}
}
parse
: (t=. {System.out.printf("\%-15s\%s\n", tokenNames[$t.type], $t.text);})* EOF
;
SL_COMMENT
: '--' ({!endCommentAhead()}?=> ~('\r' | '\n'))* '--'?
;
MINUS
: '-'
;
INT
: '0'..'9'+
;
SPACE
: (' ' | '\t' | '\r' | '\n') {skip();}
;
,在解析输入之后:
12 - 34 -- foo - bar -- 42 - - 5678 -- more comments 666
将打印:
INT 12 MINUS - INT 34 SL_COMMENT -- foo - bar -- INT 42 MINUS - MINUS - INT 5678 SL_COMMENT -- more comments 666 SL_COMMENT -- SL_COMMENT --
答案 1 :(得分:0)
我最终遇到了一个解决方案,
SL_COMMENT :评论(({input.LA(2)!=' - '}?' - ')=>' - '|〜(' - '|'\ n'|'\ r'))*((( '\ r')?'\ n')|评论) {$ channel = HIDDEN; } ;