ANTLR:"缺少对规则范围的属性访问"问题

pet*_*ust 8 java antlr

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

DT The NP cat VB ate DT a NP rat
Run Code Online (Sandbox Code Playgroud)

并有语法:

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+")");};
Run Code Online (Sandbox Code Playgroud)

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

[我仍然是ANTLR的新手,虽然有些语法工作但它仍然是反复试验的.我还经常在运行像这样小的语法时遇到"OutOfMemory"错误 - 欢迎任何帮助.

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

Bra*_*ace 11

"缺少属性访问"意味着您引用了scope($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); };
Run Code Online (Sandbox Code Playgroud)

导致" 规则全名的未知属性 ".所以我试过了

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

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

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
}
Run Code Online (Sandbox Code Playgroud)

查看生成的代码后,很容易看出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); };
Run Code Online (Sandbox Code Playgroud)

在您的情况下您需要的版本可能会有所不同,但您通常可以通过查看生成的代码很容易地找到它.


pet*_*ust 0

找到更好的方法后回答问题......

WS  :    (' '|'\t')+;
TOKEN   :   (('A'..'Z') | ('a'..'z'))+;
dttok   :   'DT' WS TOKEN;
nntok   :   'NN' WS TOKEN; 
nounPhrase :    (dttok WS nntok);
chunker :  nounPhrase ;
Run Code Online (Sandbox Code Playgroud)

问题是我在词法分析器和解析器之间感到困惑(这显然很常见)。大写项目是词法项目,小写项目是解析器项目。现在这似乎有效。(注意我已将 NP 更改为 NN)。