【问题标题】:want to skip all line comments except two in antlr4 grammar想要跳过 antlr4 语法中除了两个之外的所有行注释
【发布时间】:2014-10-17 21:32:05
【问题描述】:

我想稍微扩展一下IDL.g4 语法,以便我可以区分以下两个cmets //@top-level false//@top-level true,我只想像以前一样跳过所有其他cmets。

我曾尝试像这样添加top_levelTOP_LEVEL_TRUETOP_LEVEL_FALSE,因为我认为antr4优先考虑首先出现的词法规则。

top_level
  : TOP_LEVEL_TRUE
  | TOP_LEVEL_FALSE
  ;

TOP_LEVEL_TRUE
  : '//@top-level true'
  ;

TOP_LEVEL_FALSE
  : '//@top-level false'
  ;

LINE_COMMENT
  : '//' ~('\n'|'\r')* '\r'? '\' -> channel(HIDDEN)
  ;

但是永远不会调用监听器enterTop_level(...), 所有 cmets 似乎都被 LINE_COMMENT 吃掉了。我应该如何组织词法分析器和解析器规则?

还有一个问题,我还想在到达输入文件末尾时收到通知。我怎么做?我在侦听器类中尝试了finalize() 函数,但从未被调用。

更新了一个完整的例子:

我使用这个语法文件:IDL.g4 如上所述。然后我通过将解析器规则top_level 放在event_header 规则下方来更新它。 Lexer 规则位于 ID 规则的上方。

这是我的 Listener.java 文件

class Listener extends IDLBaseListener {
    @Override
    public void enterTop_level(IDLParser.Top_levelContext ctx) {
        System.out.println("Found top-level");
    }
}

这是一个主程序:IDLCheck.java

import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import java.io.FileInputStream;
import java.io.InputStream;

public class IDLCheck {
    public void process(String[] args) throws Exception {
        InputStream is = new FileInputStream("sample.idl");
        ANTLRInputStream input = new ANTLRInputStream(is);
        IDLLexer lexer = new IDLLexer(input);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        IDLParser parser = new IDLParser(tokens);
        parser.setBuildParseTree(true);
        RuleContext tree = parser.specification();
        Listener listener = new Listener();
        ParseTreeWalker walker = new ParseTreeWalker();
        walker.walk(listener, tree);    
  }

  public static void main(String[] args) throws Exception {
      new IDLCheck().process(args);
  }
}

和一个输入文件:sample.idl

module CommonTypes {
  struct WChannel {
    int w;
    float d;
  }; //@top-level false
  struct EPlanID {
    int kind;
    short index;
  }; //@top-level TRUE
};

我希望看到输出“Found top-level”两次,但我什么也没看到

【问题讨论】:

  • 您能提供一个示例输入吗?我刚刚运行了这个语法,没有任何问题。另外,我建议 cmets 使用 skip 而不是 channel(HIDDEN)
  • 回答我最后一个问题,关于如何在 .idl 文件中出现 eof 时收到通知。我只是在开始规则中添加了一个 eof:specification: import_decl* definition+ eof,而 eof 规则是 eof: EOF;

标签: parsing antlr4


【解决方案1】:

终于找到了解决办法。我刚刚在TOP_LEVEL_FALSETOP_LEVEL_TRUElexer 规则中添加了换行符,我还在定义规则中添加了top_level 解析器规则,因为我只希望top_level 出现在结构或联合之后。这是 rti.com 对 IDL 格式的特定扩展,这个修改对我来说似乎已经足够了。

definition
  : type_decl SEMICOLON top_level?
  | const_decl SEMICOLON
  ...

TOP_LEVEL_TRUE
  : '//@top-level true' '\r'? '\n'
  ;

TOP_LEVEL_FALSE
  : '//@top-level false' '\r'? '\n'
  ;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-17
    • 1970-01-01
    • 1970-01-01
    • 2012-06-07
    • 1970-01-01
    • 1970-01-01
    • 2021-12-11
    相关资源
    最近更新 更多