نسخ أو مرجعية دلالات التعزيز :: قاعدة الروح <>؟

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

  •  28-09-2019
  •  | 
  •  

سؤال

أحاول كتابة محلل لغة قذيفة في Boost.Spirit. ومع ذلك ، أنا غير واضح بشأن بعض القضايا الأساسية المتعلقة بالدلالات ruleس.

بالنظر إلى الوثائق ، هناك أعضاء r.alias() و r.copy() من rule. iiuc ، يجب على هؤلاء الأعضاء إرجاع إشارة إلى القاعدة ونسخة من محتويات القاعدة ، على التوالي. ومع ذلك ، لم يتم تحديد ما يحدث بوضوح عندما أستخدم القاعدة في تعريف قاعدة أخرى. من تجاربي ، وجدت أن القواعد العودية المتبادلة يمكن تحديدها بواسطة:

rule<Iter> r1, r2;
r1 = ... >> r2 >> ...;
r2 = ... >> r1 >> ...;

مما يشير إلى أن القواعد تؤخذ بالرجوع إليها داخل تعبيرات المحلل. المشكلة هي ، ماذا تفعل عندما يخرج المتغير عن النطاق ، على سبيل المثال:

rule<Iter> r1;
{ 
  rule<Iter> r2;
  r1 = ... >> r2 >> ...;
  r2 = ... >> r1 >> ...;
}
... // use r1

على نفس المذكرة ، من الممكن أن يعين لقاعدة من تعبير التحليل الذي يحتويr.copy() سيكون rvalue من النوع rule أيضا ، أليس كذلك)؟ على سبيل المثال.

rule<Iter> f() { return char_('a') << char_('b'); }
rule<Iter> r1 = ... << f();

هل يمكن لأي شخص أن ينيرني على الدلالات التفصيلية لـ ruleنسخ ومراجع ، وربما تصحيح أي مفاهيم خاطئة في هذا المنشور؟

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

المحلول

تعتمد الإجابة على إصدار الروح الذي تشير إليه.


Spirit.Classic (The Spirit v1.x) تنفذ دلالات النسخ الخاصة للقواعد. الوثائق تقول:

عندما تتم الرجوع إلى قاعدة في أي مكان في الجانب الأيمن من تعبير EBNF ، يتم الاحتفاظ بالقاعدة بالتعبير بالرجوع إليها. تقع على عاتق العميل مسؤولية التأكد من أن القاعدة المشار إليها تظل في نطاقها ولا يتم تدميرها أثناء الرجوع إليها.

يشير مشغل المهمة بشكل أساسي إلى قاعدة RHS دون إنشاء نسخة عميقة أيضًا. وقد تم ذلك للسماح:

rule<> r1, r2;
r1 = ...;
r2 = r1;

ولكن اتضح أن هذا يشترط للغاية لأنه منع التعامل مع القواعد بنفس طريقة الكائنات "الطبيعية".

لهذا السبب كانت هناك وظيفة العضو rule::copy(), ، السماح بإنشاء نسخ عميقة صريحة من القاعدة (على سبيل المثال لتخزينها في حاوية STL).

في نفس الوقت هذا:

r2 = r1.copy();

هو خطأ عادي. r2 سوف تشير إلى النسخة المؤقتة (المدمرة) من r1 عاد من الوظيفة copy().


In Spirit.Qi (أي Spirit v2.x) يتم تغيير السلوك جزئيًا. تتصرف القواعد الآن كما هو متوقع عند التعامل معها خارج المحللين. يمكنك تخزينها بشكل طبيعي في الحاويات (يعرض مشغل المهمة السلوك المتوقع). ولكن احذر ، أن قواعد تعبير محلل داخلي لا تزال محتفظًا بالرجوع إليها ، والتي لا تزال تسمح بالإشارة إلى قاعدة بنفس الطريقة التي كانت كذلك من قبل:

rule<> r1, r2;
r1 = ... >> r2 >> ...;
r2 = ... >> r1 >> ...;

في بعض الأحيان يكون من الضروري إنشاء نسخة عميقة من القاعدة ، لذلك لا يزال هناك عضو فونكتون copy.

يتم تغيير الدلالات النسخ المتغيرة لها تأثير جانبي آخر. بنيات مثل:

r1 = r2;

يقومون الآن بإنشاء نسخة (عميقة) من r2, ، قد لا يكون ما تتوقعه ، خاصة إذا r2 لن يتم تعيين RHS إلا بعد "تعيينهم" r1. لهذا السبب هناك وظيفة العضو الجديدة alias تمكين الدلالات المرجعية لهذه الحالة الزاوية:

r1 = r2.alias();

في أي حال ، في كلا الإصدارين من الروح سوف ينتهي بك الأمر إلى المراجع المتدلية إذا كان جزء من القواعد المشار إليها من تعبير محلل خارج النطاق.

راجع للشغل ، لا نسخة روحية تنفذ وظيفة rule::ref().

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