我正在尝试构建一个解析标记句子的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)
在您的情况下您需要的版本可能会有所不同,但您通常可以通过查看生成的代码很容易地找到它.
找到更好的方法后回答问题......
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)。