【问题标题】:Writing a custom Xtext/ANTLR lexer without a grammar file编写没有语法文件的自定义 Xtext/ANTLR 词法分析器
【发布时间】:2011-12-23 18:32:09
【问题描述】:

我正在为 CoffeeScript 编写一个 Eclipse/Xtext 插件,我意识到我可能需要为它手动编写一个词法分析器。 CoffeeScript 解析器还使用hand-written lexer 来处理语法中的缩进和其他技巧。

Xtext 生成一个扩展org.eclipse.xtext.parser.antlr.Lexer 的类,而后者又扩展org.antlr.runtime.Lexer。所以我想我会延长它。我可以看到两种方法来做到这一点

  • 覆盖mTokens()。这是由生成的代码完成的,改变内部状态。
  • 覆盖 nextToken() 这似乎是一种自然的方法,但是我必须跟踪内部状态。

我找不到任何示例,即使没有语法文件也可以为 ANTLR 编写简单的词法分析器。所以最简单的答案是指向一个的指针。

Xtext: grammar for language with significant/semantic whitespace 的答案是指todotext,它通过更改底层输入流中的标记来处理缩进问题。我不想那样做,因为处理咖啡脚本语法的其他技巧会很困难。

更新:

与此同时,我意识到我的问题部分是针对 Xtext 的。

【问题讨论】:

  • 您只需要实现ITokenSource - 并在nextToken 方法中执行您需要执行的任何操作。您是否查看过stackoverflow.com/questions/4414166/… Definitive Antlr Reference 中有处理缩进的示例(例如在 Python 中)。

标签: antlr lexer xtext


【解决方案1】:

这就是我所做的——而且它有效。

public class MyLexer extends myprj.parser.antlr.internal.InternalMylangLexer {
  private SomeExternalLexer externalLexer;

  public Lexer(CharStream in) {
    super(in);
    externalLexer = new SomeExternalLexer(in);
  }

  @Override
  public Token nextToken() {
    Token token = null;
    ExternalToken extToken = null;
    try {
      extToken = externalLexer.nextToken();
      if (extToken == null) {
        token = CommonToken.INVALID_TOKEN;
      }
      else {
        token = mapExternalToken(extToken);
      }
    }
    catch (Exception e) {
      token = CommonToken.INVALID_TOKEN;
    }
    return token;
  }

  protected Token mapExternalToken(ExternalToken extToken) {
    // ...
  }
}

然后我有一个稍微定制的解析器,其中包含:

public class BetterParser extends MylangParser {
  @Override
  protected TokenSource createLexer(CharStream stream) {
    MyLexer lexer = new MyLexer(stream);
    return lexer;
  }
}

我还必须更改我的 MylangRuntimeModule.java 以包含此方法

@Override
public Class<? extends org.eclipse.xtext.parser.IParser> bindIParser() {
     return myprj.parser.BetterParser.class ;
}

就是这样。

【讨论】:

    【解决方案2】:

    另一种方法(无需创建自定义解析器)是通过扩展 Xtext 的词法分析器(org.eclipse.xtext.parser.antlr.Lexer)来创建自定义词法分析器,如下所示:

    public class CustomSTLexer extends Lexer {
    
        @Override
        public void mTokens() {
          // implement lexer here
        }
    }
    

    然后你将它绑定到你的模块中:

    @Override
    public void configureRuntimeLexer(Binder binder) {
        binder.bind(Lexer.class)
                    .annotatedWith(Names.named(LexerBindings.RUNTIME))
                    .to(CustomSTLexer.class);
    }
    

    如果您想看一个完整的示例,我已经为 StringTemplate 的基于 Xtext 的编辑器实现了一个自定义词法分析器,名为 hastee

    【讨论】:

      猜你喜欢
      • 2011-01-30
      • 2020-08-18
      • 2021-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-15
      • 1970-01-01
      相关资源
      最近更新 更多