我想稍微扩展IDL.g4语法,以便区分以下两个注释//@top-level false和//@top-level true ,所有其他注释我只想像以前一样跳过。
我试图像这样添加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(...) ,所有注释似乎都被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 };我希望看到输出“发现顶级”两次,但我什么也看不见
I want to extend the IDL.g4 grammar a bit so that I can distinguish the following two comments //@top-level false and //@top-level true, all other comments I just want to skip like before.
I have tried to add top_level, TOP_LEVEL_TRUEand TOP_LEVEL_FALSElike this, because I thought antr4 gave precedence to lexical rules comming first.
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) ;But the listener enterTop_level(...) is never called, all comments seems to be eaten by LINE_COMMENT. How shall I organize the lexer and parser rules?
And one more question, I also want to be notified when end of input-file is reached. How do I do that? I have tried a finalize() function i the listener class, but never get called.
Updated with a complete example:
I use this grammar file : IDL.g4 as I said above. Then I update it by putting the parser rule top_level just below the event_header rule. The Lexer rules is put just above the ID rule.
Here is my Listener.java file
class Listener extends IDLBaseListener { @Override public void enterTop_level(IDLParser.Top_levelContext ctx) { System.out.println("Found top-level"); } }and here is a main program: 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); } }and a input file: sample.idl
module CommonTypes { struct WChannel { int w; float d; }; //@top-level false struct EPlanID { int kind; short index; }; //@top-level TRUE };I expect to see the output "Found top-level" twice, but I see nothing
最满意答案
最后我找到了解决方案。 我刚刚在TOP_LEVEL_FALSE和TOP_LEVEL_TRUE词法分析器规则中添加了换行符,我还将top_level解析器规则添加到定义规则中,因为我只希望top_level出现在struct或union之后。 这是IDL格式的rti.com特定扩展,这个修改对我来说似乎已经足够了。
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' ;Finally I found a solution. I just added newline characters to the TOP_LEVEL_FALSE and TOP_LEVEL_TRUElexer rules an I also added the top_level parser rule to the definition rule because I only expected top_level to appear after a struct or union. this is a rti.com specific extension to the IDL-format, this modification seems to be good enough for me.
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' ;更多推荐
发布评论