2009-11-02 10 views
6

Ich versuche, eine ANTLR Grammatik zu bauen, die getaggten Sätze wie parst:ANTLR: „Attribut Zugriff auf Regel Umfang fehlt“ Problem

DT The NP cat VB ate DT a NP rat 

und haben die Grammatik:

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+")");}; 

Die Grammatik Generator erzeugt in der letzten Zeile "missing attribute access on rule scope: nounPhrase".

[Ich bin noch neu in ANTLR und obwohl einige Grammatiken es ist immer noch Versuch und Irrtum arbeiten. Ich bekomme auch häufig einen "OutOfMemory" -Fehler, wenn ich Grammatiken so klein wie diese helfe - jede Hilfe willkommen.]

Ich benutze ANTLRWorks 1.3, um den Code zu generieren und laufe unter Java 1.6.

Antwort

1

die Beantwortung der Frage nach, einen besseren Weg gefunden zu haben ...

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

Das Problem war, ich wurde zwischen dem Lexer und Parser verworren bekommen (das ist offenbar sehr häufig). Die Großbuchstaben sind lexikalisch, der Kleinbuchstabe im Parser. Das scheint jetzt zu funktionieren. (NB Ich habe NP zu NN geändert).

2

In der ursprünglichen grammer, warum nicht das Attribut enthalten es ist zu fragen, höchstwahrscheinlich:

chunker : nounPhrase {System.out.println("chunk found "+"("+$nounPhrase.text+")");}; 

Jeder Ihrer Regeln (chunker, derjenige zu sein ich schnell erkennen kann) haben Attribute (Zusatzinformationen) zugeordnet mit ihnen. Sie können eine schnelle Liste der verschiedenen Attribute für die verschiedenen Arten von Regeln bei http://www.antlr.org/wiki/display/ANTLR3/Attribute+and+Dynamic+Scopes finden, wäre nett, wenn Beschreibungen auf der Webseite für jedes dieser Attribute gesetzt wurden (wie für das Start-und Stopp-Attribut für die Parser-Regeln auf Token beziehen von Ihrem Lexer - was Ihnen erlauben würde, zu Ihrer Zeilennummer und Position zurückzukehren.

Ich denke, Ihre Chunker-Regel sollte nur leicht geändert werden, anstelle von $nounPhrase sollten Sie $nounPhrase.text verwenden. text ist ein Attribut für Ihre nounPhrase Regel.

Sie könnten ein wenig andere Formatierungen auch tun wollen, in der Regel der Parser Regeln erscheinen vor den Lexer Regeln (beginnen mit Großbuchstaben)

PS (mit Kleinbuchstaben beginnen). Wenn ich die Box eintippe, beginnt die Chunker-Regel auf einer neuen Zeile, aber in meiner ursprünglichen Antwort begann sie nicht in einer neuen Zeile.

+0

Könnten Sie bitte noch etwas erläutern? Ich bin mir nicht sicher, was ein Attribut ist –

8

„fehlendes Attribut access“ bedeutet, dass Sie einen Bereich verwiesen haben ($nounPhrase), anstatt ein Attribut den Rahmen (wie $nounPhrase.text).

Im Allgemeinen ist eine gute Möglichkeit, Probleme mit Attributen zu beheben ist in der generierten Parser-Methode für die betreffende Regel zu suchen.

Zum Beispiel ist mein erster Versuch bei Erstellen eine neue Regel, wenn ich ein wenig rostig war:

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); }; 

Folge „unbekanntes Attribut für Regel Fullnamen“.Also habe ich versucht

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

was dazu führt, "Attribut Zugriff fehlt". Ein Blick auf die generierte Parser-Methode machte deutlich, was ich tun musste. Zwar gibt es einige kryptische Stücke sind, werden die relevanten Teile Bereiche (Variablen) leicht zu verstehen:

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 
} 

Nachdem bei den generierten Code suchen, ist es leicht zu sehen, dass die fullname Regel Instanzen der Name Klasse zurückkehrt, so was ich in diesem Fall brauchte, war einfach:

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

die Version, die Sie in Ihrer Situation benötigen kann unterschiedlich sein, aber Sie werden es in der Regel der Lage sein, ziemlich leicht, herauszufinden, um den generierten Code suchen.

1

Wenn Sie versehentlich etwas dummes tun wie $thing.$attribute, wo Sie $thing.attribute bedeuten, werden Sie auch die missing attribute access on rule scope Fehlermeldung sehen. (Ich weiß, dass diese Frage schon vor langer Zeit beantwortet wurde, aber dieses Quäntchen könnte jemand anderem helfen, der die Fehlermeldung sieht!)

Verwandte Themen