我正在尝试在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
有人可以向我解释这些错误消息吗?
感谢。
答案 0 :(得分:2)
AFAIK,错误是因为nestingBlockCommentCharacters
可以匹配+/
(~'/'
两次)。
就个人而言,我会将nestingBlockComment
保留为词法分析器规则而不是解析器规则。您可以通过在词法分析器类中添加一个小助手方法来实现:
public boolean openOrCloseCommentAhead() {
// return true iff '/+' or '+/' is ahead in the character stream
}
然后在词法分析器注释规则中,使用带有帮助器方法的gated semantic predicates作为谓词中的布尔表达式:
// 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 Main
(对于Windows,最后一个命令是:java -cp .;antlr-3.2.jar Main
)
产生以下输出:
comment :: /+ comment /+ and +/ comment +/ comment :: /+ comment +/