How to know which alternative rule ANTLR parser is currently in during visit(如何在访问期间知道ANTLR解析器当前处于哪个替代规则中)
问题描述
如果我们查看bash源代码,特别是yacc语法,我们可以看到所有重定向都是这样定义的:
redirection
        :   GREATER WORD
        |   LESS WORD
        |   NUMBER GREATER WORD
        |   NUMBER LESS WORD
        |   REDIR_WORD GREATER WORD
        |   REDIR_WORD LESS WORD
        |   GREATER_GREATER WORD
        |   NUMBER GREATER_GREATER WORD
        |   REDIR_WORD GREATER_GREATER WORD
        |   GREATER_BAR WORD
        |   NUMBER GREATER_BAR WORD
        |   REDIR_WORD GREATER_BAR WORD
        |   LESS_GREATER WORD
        |   NUMBER LESS_GREATER WORD
        |   REDIR_WORD LESS_GREATER WORD
        |   LESS_LESS WORD
        |   NUMBER LESS_LESS WORD
        |   REDIR_WORD LESS_LESS WORD
        |   LESS_LESS_MINUS WORD
        |   NUMBER LESS_LESS_MINUS WORD
        |   REDIR_WORD  LESS_LESS_MINUS WORD
        |   LESS_LESS_LESS WORD
        |   NUMBER LESS_LESS_LESS WORD
        |   REDIR_WORD LESS_LESS_LESS WORD
        |   LESS_AND NUMBER
        |   NUMBER LESS_AND NUMBER
        |   REDIR_WORD LESS_AND NUMBER
        |   GREATER_AND NUMBER
        |   NUMBER GREATER_AND NUMBER
        |   REDIR_WORD GREATER_AND NUMBER
        |   LESS_AND WORD
        |   NUMBER LESS_AND WORD
        |   REDIR_WORD LESS_AND WORD
        |   GREATER_AND WORD
        |   NUMBER GREATER_AND WORD
        |   REDIR_WORD GREATER_AND WORD
        |   GREATER_AND DASH
        |   NUMBER GREATER_AND DASH
        |   REDIR_WORD GREATER_AND DASH
        |   LESS_AND DASH
        |   NUMBER LESS_AND DASH
        |   REDIR_WORD LESS_AND DASH
        |   AND_GREATER WORD
        |   AND_GREATER_GREATER WORD
        ;
在我的访问者中,当调用visitRedirection时,几乎不可能轻松地知道访问者当前处于哪个替代项中。我可以使用#和标签来标记每个备选方案,但仅为一个产生式规则添加43个访问方法似乎有点过多。
通常我只会做一些null检查,以了解是否选择了第一个备选方案,但在本例中几乎总是有两个冲突的备选方案,例如:
GREATER WORD
NUMBER GREATER WORD
那么我是否应该执行ctx.NUMBER() != null && ctx.GREATER() != null以匹配第二个备选方案,并ctx.NUMBER() == null && ctx.GREATER() != null以匹配第一个备选方案?
是否有更简单、更清晰的方法来了解访问者当前所在的特定备选方案?
推荐答案
重新调整语法,以减少可供选择的内容。它们中的许多都有共同的前导或尾部部分,例如:
redirection
        :   GREATER WORD
        |   LESS WORD
        |   NUMBER (GREATER | LESS) WORD
        |   REDIR_WORD (GREATER | LESS | LESS_LESS_MINUS) WORD
        |   ...
这样,您在每个alt中都有一个唯一的第一个令牌,然后可以将其赋给一个局部变量:
redirection
        :   op = GREATER WORD
        |   op = LESS WORD
        |   op = NUMBER subOp= (GREATER | LESS) WORD
        |   op = REDIR_WORD subOp =(GREATER | LESS | LESS_LESS_MINUS) WORD
        |   ...
通过该选项,您可以轻松地检查您在监听器/访问者中的哪个ALT:
public exitRedirection(RedirectionContext ctx) {
    switch (ctx.op.getType()) {
        case YourParser.GREATER_WORD: {
            break;
        }
        case YourParser.REDIR_WORD: {
            switch (ctx.supOp.getType()) {
                case YourParser.LESS_LESS_MINUS: {
                    break;
                }
            }
            break;
        }
    }
                        这篇关于如何在访问期间知道ANTLR解析器当前处于哪个替代规则中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何在访问期间知道ANTLR解析器当前处于哪个替代规则中
				
        
 
            
        基础教程推荐
- 多个组件的复杂布局 2022-01-01
 - 验证是否调用了所有 getter 方法 2022-01-01
 - Java 实例变量在两个语句中声明和初始化 2022-01-01
 - 如何在 JFrame 中覆盖 windowsClosing 事件 2022-01-01
 - 从 python 访问 JVM 2022-01-01
 - 如何在 Spring @Value 注解中正确指定默认值? 2022-01-01
 - Java Swing计时器未清除 2022-01-01
 - 在 Java 中创建日期的正确方法是什么? 2022-01-01
 - 不推荐使用 Api 注释的描述 2022-01-01
 - 大摇大摆的枚举 2022-01-01
 
    	
    	
    	
    	
    	
    	
    	
    	
						
						
						
						
						
				
				
				
				