我想与您分享我必须在ANTLR4中实施的岛屿解决方案。
该语言定义了一个特殊命令PUT
,其结构如下:
PUT [<SPECIALISED LANGUAGE>]
。
我的解决方案是:
覆盖Lexer的nextToken
方法:
public Token nextToken() {
if (f_current_idx != -1) {
_input.seek(f_current_idx); f_current_idx = -1;
}
Token l_token = super.nextToken(); return l_token;
}
在Lexer中添加一些代码:
PUT :
'PUT'
{
f_current_idx = _input.index(); ((ANTLRStringStream) _input).rewind();
SRC_PUTLexer l_put_lexer = new SRC_PUTLexer(_input);
UnbufferedTokenStream<Token> l_tokenStream = new UnbufferedTokenStream<Token>(l_put_lexer);
if (l_tokenStream.LA(2) == SRC_PUTLexer.LBRACK) {
new SRC_PUTParser(l_tokenStream).start_rule(); f_current_idx = _input.index();
}
};
此外,必须定义在ANTLR 4中消失的类ANTLRStringStream
:
public class ANTLRStringStream extends ANTLRInputStream {
protected int markDepth = 0;
protected int lastMarker;
protected ArrayList<Integer> markers;
public ANTLRStringStream() {
super();
}
public ANTLRStringStream(String input) {
super(input);
}
public int mark() {
if ( markers==null ) { markers = new ArrayList<Integer>(); }
markers.add(markDepth, index()); markDepth++; lastMarker = markDepth;
return markDepth;
}
public void rewind(int m) {
int state = (int) markers.get(m); seek(state); release(m);
}
public void rewind() { rewind(lastMarker); }
public void release(int marker) {
markDepth = marker; markDepth--;
}
}
非常欢迎任何反馈! 亲切的问候,WolfgangHämmer
答案 0 :(得分:3)
这应该是社区维基。
我的第一个主要评论是你需要摆脱ANTLRStringStream
课程。 ANTLR 4提供的ANTLRInputStream
类在ANTLR 3中提供ANTLRStringStream
的功能。IntStream
和CharStream
接口在ANTLR 4中进行了修订和广泛记录,以摆脱有问题的rewind
方法和其他未定义的行为。你不应该重新介绍它们。