使用ANTLR4的Island解决方案

时间:2013-02-12 12:44:21

标签: antlr4

我想与您分享我必须在ANTLR4中实施的岛屿解决方案。

  1. 语言的结构。我必须编写语法的语言来源于 PL / SQL带有一些额外的结构。我不会在这里详细介绍,因为这不是主题。
  2. 该语言定义了一个特殊命令PUT,其结构如下:

    PUT [<SPECIALISED LANGUAGE>]

  3. 我的解决方案是:

    1. 覆盖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;
      }
      
    2. 在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();
          } 
      };
      
    3. 此外,必须定义在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

1 个答案:

答案 0 :(得分:3)

这应该是社区维基。

我的第一个主要评论是你需要摆脱ANTLRStringStream课程。 ANTLR 4提供的ANTLRInputStream类在ANTLR 3中提供ANTLRStringStream的功能。IntStreamCharStream接口在ANTLR 4中进行了修订和广泛记录,以摆脱有问题的rewind方法和其他未定义的行为。你不应该重新介绍它们。