ANTLR:“规则范围内缺少属性访问”问题

2024-01-14

我正在尝试构建一个 ANTLR 语法来解析标记句子,例如:

DT The NP cat VB ate DT a NP rat

并有语法:

fragment TOKEN  :   (('A'..'Z') | ('a'..'z'))+;
fragment WS :   (' ' | '\t')+;
WSX :   WS;
DTTOK   :   ('DT' WS TOKEN);
NPTOK   :   ('NP' WS TOKEN);
nounPhrase:  (DTTOK WSX NPTOK);
chunker : nounPhrase {System.out.println("chunk found "+"("+$nounPhrase+")");};

语法生成器生成“missing attribute access on rule scope: nounPhrase“在最后一行。

[我对 ANTLR 还很陌生,虽然有些语法可以工作,但仍然需要反复试验。当运行像这样小的语法时,我也经常收到“OutOfMemory”错误 - 欢迎任何帮助。]

我使用 ANTLRWorks 1.3 生成代码并在 Java 1.6 下运行。


“缺少属性访问”意味着您引用了一个范围($nounPhrase)而不是的属性范围(例如$nounPhrase.text).

一般来说,解决属性问题的一个好方法是查看所生成的解析器方法以查找相关规则。

例如,当我有点生疏时,我最初尝试创建一个新规则:

multiple_names returns [List<Name> names]
@init {
    names = new ArrayList<Name>(4);
}
 : a=fullname ' AND ' b=fullname { names.add($a.value); names.add($b.value); };

结果是“规则全名的未知属性”。所以我尝试了

multiple_names returns [List<Name> names]
@init {
    names = new ArrayList<Name>(4);
}
 : a=fullname ' AND ' b=fullname { names.add($a); names.add($b); };

这导致“缺少属性访问”。查看生成的解析器方法可以清楚地表明我需要做什么。虽然有一些神秘的部分,但与范围(变量)相关的部分很容易理解:

public final List<Name> multiple_names() throws RecognitionException {
    List<Name> names = null;        // based on "returns" clause of rule definition
    Name a = null;                  // based on scopes declared in rule definition
    Name b = null;                  // based on scopes declared in rule definition
    names = new ArrayList<Name>(4); // snippet inserted from `@init` block

    try {
        pushFollow(FOLLOW_fullname_in_multiple_names42);
        a=fullname();
        state._fsp--;
        match(input,189,FOLLOW_189_in_multiple_names44); 
        pushFollow(FOLLOW_fullname_in_multiple_names48);
        b=fullname();
        state._fsp--;
        names.add($a); names.add($b);// code inserted from {...} block
    }
    catch (RecognitionException re) {
        reportError(re);
        recover(input,re);
    }
    finally {
        // do for sure before leaving
    }
    return names;                    // based on "returns" clause of rule definition
}

查看生成的代码后,很容易看出fullname规则返回的实例Name类,所以在这种情况下我需要的很简单:

multiple_names returns [List<Name> names]
@init {
    names = new ArrayList<Name>(4);
}
 : a=fullname ' AND ' b=fullname { names.add(a); names.add(b); };

您的情况所需的版本可能会有所不同,但您通常可以通过查看生成的代码轻松找出它。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ANTLR:“规则范围内缺少属性访问”问题 的相关文章

随机推荐