Antlr: "مفقود الوصول إلى السمات على مشكلة في نطاق القاعدة"

StackOverflow https://stackoverflow.com/questions/1658869

  •  11-09-2019
  •  | 
  •  

سؤال

أحاول بناء قواعد قذر من أنطري أن يوزع الجمل الموسومة مثل:

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.

هل كانت مفيدة؟

المحلول 4

الإجابة على السؤال بعد أن وجدت طريقة أفضل ...

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

كانت المشكلة كنت أحصل على مشوش بين Lexer والتحلل (هذا يبدو شائعا للغاية). العناصر الكبيرة هي معجمية، والصغيرة في المحلل المحلل. هذا يبدو الآن يعمل. (NB لقد غيرت NP إلى NN).

نصائح أخرى

"وصول السمة المفقود" يعني أنك أشيرت إلى نطاق ($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); };

قد تكون الإصدار الذي تحتاجه في وضعك مختلفا، لكنك ستتمكن بشكل عام من معرفة ذلك بسهولة من خلال النظر في التعليمات البرمجية التي تم إنشاؤها.

في القطر الأصلي، لماذا لا تشمل السمة التي يطلبها، على الأرجح:

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

كل من القواعد الخاصة بك (chunker أن تكون الشخص الذي يمكنني بقعةه بسرعة) لديه سمات (معلومات إضافية) مرتبطة بها. يمكنك العثور على قائمة سريعة من السمات المختلفة لأنواع مختلفة من القواعد في http://www.antlr.org/wiki/display/antlr3/attriver+dynamic+scopes., ، سيكون لطيفا إذا تم وضع أوصاف على صفحة الويب لكل من هذه الصفات (مثل سمة بدء وإيقاف قواعد المحللين يشير إلى الرموز المميزة من Lexer - مما سيسمح لك بالعودة إلى رقم السطر والموقف) وبعد

أعتقد أنه يجب تغيير حكم المختنق الخاص بك قليلا، بدلا من $nounPhrase يجب عليك استخدامها $nounPhrase.text. text هي سمة لك nounPhrase القاعدة.

قد ترغب في القيام ببعض الإضافات الأخرى أيضا، عادة ما تظهر قواعد المحلل (ابدأ بحرف صغير) قبل قواعد Lexer (ابدأ بحرف كبير)

ملاحظة. عندما اكتب في المربع، بدأت قاعدة Chunker في سطر جديد، ولكن في إجابتي الأصلية لم تبدأ في سطر جديد.

إذا كنت تفعل شيئا بطريق الخطأ شيء سخيف $thing.$attribute حيث تقصد $thing.attribute, ، سوف ترى أيضا missing attribute access on rule scope رسالة خطأ. (أعرف أن هذا السؤال أجاب منذ وقت طويل، ولكن قد يساعد هذا القليل من التوافه شخصا آخر يرى رسالة الخطأ!)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top