1

Dでネストされたコメントを実装しようとしています.

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

これらのエラー メッセージと修正方法を説明してもらえますか?

ありがとう。

4

1 に答える 1

2

AFAIK、エラーは一致nestingBlockCommentCharacters する可能性+/があるためです(~'/'2回)。

個人的にnestingBlockCommentは、パーサールールではなくレクサールールとして保持します。これを行うには、レクサークラスに小さなヘルパーメソッドを追加します。

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

次に、レクサーコメントルールで、述語内のブール式として、そのヘルパーメソッドでゲートされたセマンティック述語を使用します。

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

// match any character
Any
  :  .
  ;

ちょっとしたデモ文法:

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メイン

(Windowsの場合、最後のコマンドは次のとおりですjava -cp .;antlr-3.2.jar Main:)

次の出力を生成します。

コメント::/+コメント/+および+/コメント+/
コメント::/+コメント+/
于 2010-07-18T20:10:21.237 に答える