我想与您分享一个我必须在 ANTLR4 中实施的孤岛解决方案。
- 语言的结构。我必须为其编写语法的语言源自 PL/SQL,并带有一些额外的结构。我不会在这里详细介绍,因为这是题外话。
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(); } };
此外ANTLRStringStream
,必须定义在 ANTLR 4 中消失的类:
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--;
}
}
非常欢迎任何反馈!亲切的问候,沃尔夫冈·哈默