【发布时间】:2014-10-17 21:32:05
【问题描述】:
我想稍微扩展一下IDL.g4 语法,以便我可以区分以下两个cmets //@top-level false 和//@top-level true,我只想像以前一样跳过所有其他cmets。
我曾尝试像这样添加top_level、TOP_LEVEL_TRUE和TOP_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;