【问题标题】:How to iterate over a production in ANTLR如何在 ANTLR 中迭代生产
【发布时间】:2012-04-30 17:15:39
【问题描述】:

让我们假设以下具有 2 个 ANTLR 语法的场景:

1)

expr     : antExp+;
antExpr  : '{' T '}' ;
T        : 'foo';

2)

expr     : antExpr; 
antExpr  : '{' T* '}' ;
T        : 'bar';

在这两种情况下,我都需要知道如何迭代 antExp+ 和 T*,因为我需要为它们的每个元素生成一个 ArrayList。当然我的语法更复杂,但我认为这个例子应该解释我需要什么。谢谢!

【问题讨论】:

    标签: java parsing antlr rules production


    【解决方案1】:

    ANTLR 中的生产规则可以有一个或多个返回类型,您可以在循环内引用它们((...)* 或(...)+)。因此,假设您要打印与antExp 规则匹配的每个T 的文本。可以这样做:

    expr
     : (antExp {System.out.println($antExp.str);} )+
     ;
    
    antExpr returns [String str]
     : '{' T '}' {$str = $T.text;}
     ;
    
    T : 'foo';
    

    同样的原则也适用于语法 #2:

    expr     : antExpr; 
    antExpr  : '{' (T {System.out.println($T.text);} )* '}' ;
    T        : 'bar';
    

    编辑

    请注意,您不仅限于返回单个引用。运行从以下位置生成的解析器:

    grammar T;  
    
    parse
     : ids {System.out.println($ids.firstId + "\n" + $ids.allIds);}
     ;
    
    ids returns [String firstId, List<String> allIds]
    @init{$allIds = new ArrayList<String>();}
    @after{$firstId = $allIds.get(0);}
     : (ID {$allIds.add($ID.text);})+
     ;
    
    ID    : ('a'..'z' | 'A'..'Z')+;
    SPACE : ' ' {skip();};
    

    在输入 "aaa bbb ccc" 上将打印以下内容:

    aaa
    [aaa, bbb, ccc]
    

    【讨论】:

    • 非常感谢巴特!我不知道我能做到这一点。
    • 请注意,您可以在规则中的 @init 中创建 ArrayList,并且可以使用“expr 返回 [ List value ] 从规则中返回它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-15
    • 2015-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-19
    • 2017-02-17
    相关资源
    最近更新 更多