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(); } };
さらに、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--;
}
}
どんなフィードバックでも大歓迎です!敬具、ヴォルフガング・ハマー