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
:)
次の出力を生成します。
コメント::/+コメント/+および+/コメント+/
コメント::/+コメント+/