ANTLR 3上的ASN.1 / SMI注释语法

时间:2012-01-07 10:53:08

标签: antlr antlr3

在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规则的可行方法是什么?

2 个答案:

答案 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; }     ;