2010-07-18 87 views
1

我想实现嵌套评论中D.的ANTLR问题与嵌入的注释

nestingBlockComment 
: '/+' (options {greedy=false;} :nestingBlockCommentCharacters)* '+/' {$channel=HIDDEN;}; // line 58 

    nestingBlockCommentCharacters 
    : (nestingBlockComment| '/'~'+' | ~'/') ; //line 61 

对我来说,这将是合乎逻辑的,这应该工作...

This is the error message I get: 
[21:06:34] warning(200): d.g:58:64: Decision can match input such as "'+/'" using multiple alternatives: 1, 2 
As a result, alternative(s) 1 were disabled for that input 
[21:06:34] warning(200): d.g:61:7: Decision can match input such as "'/+'" using multiple alternatives: 1, 3 
As a result, alternative(s) 3 were disabled for that input 
莫非

人解释这些错误消息给我和修复?

谢谢。

回答

2

AFAIK,错误是因为nestingBlockCommentCharacters可以匹配+/(两次~'/')。

就个人而言,我会保留nestingBlockComment作为词法分析器规则而不是解析器规则。

public boolean openOrCloseCommentAhead() { 
    // return true iff '/+' or '+/' is ahead in the character stream 
} 

,然后在词法注释规则,使用gated semantic predicates与helper方法作谓语,里面的布尔表达式:

// match nested comments 
Comment 
    : '/+' (Comment | {!openOrCloseCommentAhead()}?=> Any)* '+/' 
    ; 

// match any character 
Any 
    : . 
    ; 
您可以通过在词法分析器类加入少许的helper方法做到这一点

小演示语法:

grammar DComments; 

@lexer::members { 
    public boolean openOrCloseCommentAhead() { 
    return (input.LA(1) == '+' && input.LA(2) == '/') || 
      (input.LA(1) == '/' && input.LA(2) == '+'); 
    } 
} 

parse 
    : token+ EOF 
    ; 

token 
    : Comment {System.out.println("comment :: "+$Comment.text);} 
    | Any 
    ; 

Comment 
    : '/+' (Comment | {!openOrCloseCommentAhead()}?=> Any)* '+/' 
    ; 

Any 
    : . 
    ; 

和一个主类,以测试它:

import org.antlr.runtime.*; 

public class Main { 
    public static void main(String[] args) throws Exception { 
     ANTLRStringStream in = new ANTLRStringStream(
      "foo /+ comment /+ and +/ comment +/ bar /+ comment +/ baz"); 
     DCommentsLexer lexer = new DCommentsLexer(in); 
     CommonTokenStream tokens = new CommonTokenStream(lexer); 
     DCommentsParser parser = new DCommentsParser(tokens); 
     parser.parse(); 
    } 
} 

然后以下命令:

 
java -cp antlr-3.2.jar org.antlr.Tool DComments.g 
javac -cp antlr-3.2.jar *.java 
java -cp .:antlr-3.2.jar Main 

(对于Windows,最后命令是:java -cp .;antlr-3.2.jar Main

产生以下输出:

 
comment :: /+ comment /+ and +/ comment +/ 
comment :: /+ comment +/