繁体   English   中英

ANTLR4中的规则变量

[英]Rule variables in ANTLR4

我正在尝试将我的语法从v3转换为v4并遇到一些麻烦。

在第3节我有这样的规则:

dataspec[DataLayout layout] returns [DataExtractor extractor]
    @init {
        DataExtractorBuilder builder = new DataExtractorBuilder(layout);
    }
    @after {
        extractor = builder.create();
    }
    : first=expr { builder.addAll(first); } (COMMA next=expr { builder.addAll(next); })* 
    ;

expr returns [List<ValueExtractor> ext]
    ...

但是,使用v4中的规则返回这些自定义上下文对象而不是我明确告诉他们返回的内容,事情都搞砸了。 什么是v4方式这样做?

这里有多种情况:

  • 访问传入的变量( layout
  • 访问当前规则的返回值( extractor
  • 访问局部变量( firstnext

传入变量和当前规则的返回值

当访问传入变量或当前规则的返回值时,您只需要在规则定义中给出的名称前缀为$

  • layout变成了$layout
  • extractor变为$extractor

局部变量

显然,需要做的是引用变量的成员,该成员是根据返回值的规则的returns子句命名的。

例如, firstexpr规则捕获结果, expr命名其返回值ext ,表示:

  • first成为$first.ext
  • next变成$next.ext

何时使用$表单

与v3中不同的是,你可以将某些变量作为常规java字段引用,在所有情况下都需要使用$ form,包括在action中,在@init@after块中,以及将变量传递给其他规则时。

其他陷阱

如果您在局部变量中捕获可选标记,则可能会遇到空指针异常,因为您正在引用该变量的属性。

single_lname returns [String s]
    : p=LNAME_PREFIX? r=NAME { $p.text + toNameCase($r.text); }
;

您需要检查$p是否为空,但大多数情况下这将导致“缺少属性访问”错误。 ANTLR4发出一个特殊异常,以便您可以检查这一点, 这只适用于在if条件下使用(例如,重构这个以使用三元运算符仍然会导致错误)。

single_lname returns [String s]
    : p=LNAME_PREFIX? r=NAME { 
        if ($p == null) {
            $s = toNameCase($r.text);
        } else {
            $s = $p.text + toNameCase($r.text);
        }
    }
;

更新的规则

总而言之,数据dataspec规则变为:

dataspec[DataLayout layout] returns [DataExtractor extractor]
    @init {
        DataExtractorBuilder builder = new DataExtractorBuilder($layout);
    }
    @after {
        $extractor = builder.create();
    }
    : first=expr { builder.addAll($first.ext); }
        (COMMA next=expr { builder.addAll($next.ext); })* 
    ;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM