我是antlr和java的新手,所以这可能是一个微不足道的问题(希望如此!)。我正在使用antlr 3.4。我有词法分析器的语法:
lexer grammar MyLexer;
options {
language = Java;
}
COMMENT:
( '//' ~('\n'|'\r')* '\r'? '\n'
| '/*' .* '*/'
) {$channel=HIDDEN;};
WS: (' '
| '\t'
| '\r'
| '\n'
) {$channel=HIDDEN;};
COLLECTION: 'collection';
BRACE_OPEN: '{';
BRACE_CLOSE: '}';
另一个用于解析器:
parser grammar myParser;
options {
language = Java;
tokenVocab = myLexer;
}
collection_def
scope {
MyCollection currentCollection;
}
@init {
$collection_def::currentCollection = new MyCollection();
}
@after {
// There should be a comment preceding this rule. How to get the content of that comment into the commentContent variable?
$collection_def::currentCollection.setDescription(commentContent);
...
}
: COLLECTION BRACE_OPEN
...
BRACE_CLOSE;
词法分析器向隐藏的频道发送评论。但我希望解析器提取注释中包含的文本,该注释位于特定规则之前(或特定标记,因为COLLECTION标记仅出现在上面的规则中)。例如,我想要这个输入:
/* Text describing the collection */
collection {
item 1;
item 2;
}
解析为MyCollection对象,其描述成员变量设置为“描述集合的文本”。
我怎样才能做到这一点?
令牌流具有所有令牌,包括隐藏通道上的令牌。您从解析器结果获得的每个标记(例如,如果您使用的是tree.getToken()
,则通过output = AST
)知道它在标记流(Token.getTokenIndex()
)中的位置。这是您需要能够找到并读取令牌之前的隐藏令牌所需的信息。
剩下要做的就是将所有这些信息发送到您需要使用它的地方。一种可能的方法是获取标记列表(如果在词法分析器和解析器之间使用CommonTokenStream.getTokens()
,则通过CommonTokenStream
)并将其传递给处理注释的任何方法,或者对结果进行一些后处理以添加信息给它。