2010-07-18 86 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 +/