سؤال

أنا أكتب لغة باستخدام أشجار antlr وأشجار التعبير.

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

في الوقت الحالي ، يكون ساذجًا بشكل لا يصدق ، فهو ببساطة يفعل هذا (رمز TDD قيد التقدم غالبًا ما يبدو ساذجًا!؟):

protected Expression GenerateAdd(Expression left, Expression right)
{
  if (left.Type.Equals(right.Type))
    return Expression.Add(left, right);
  if (left.Type.IsValueType && right.Type.IsValueType)
    Promote7_2_6_2(ref left, ref right);
  return Expression.Add(left, right);
}

أين Promote7_2_6_2 يولد تعبيرات تحويلها التي تتبع قواعد الترويج المتكامل كما هو موضح من قبل C# SPEC 7.2.6.2 (ستكون اللغة مشابهة لـ C# ، ولكنها ستعمل مع JScript بالإضافة إلى وجود كلمات رئيسية جديدة أخرى).

بطبيعة الحال ، انتقلت إلى إضافة سلسلة الإضافة - أي "a" + "b"; وأحصل على الخطأ:

System.InvalidOperationException: The binary operator Add is not defined for the types 'System.String' and 'System.String'.

عادلة بما فيه الكفاية - أعكس النظام. توليد شجرة تعبير في طريقة اختبار مثل هذا:

Expression<Func<string, string, string>> e = (s1, s2) => s1 + s2;

يوضح أنه يتم بالفعل إنشاء إضافة ثنائية الثنائية ، ولكن مع طريقة التنفيذ المُعين على أحد string.Concat طُرق.

كنت أدرك أنه سأضطر إلى النظر في القيام بشيء كهذا في بعض الحالات ، ولكن كم عدد الأنواع الأخرى التي تحدد الإضافة بهذه الطريقة؟ هل هو عادل string?

هل هي قاعدة مضمنة في برنامج التحويل البرمجي C# - أم أن هناك نوعًا من بيانات التعريف القابلة للاكتشاف التي يمكنني استخدامها لاكتشاف هذه الطرق على الأنواع الأخرى؟

شكرا مقدما!

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

المحلول

يبدو أنني أقوم بخط رائع في الإجابة على أسئلتي!

اعتذاري ، يمكن أن تكون هذه الإجابة منسقة أفضل ، لكنني على رغبتي في HTC ولوحة المفاتيح الخاصة بها لا تدعم جميع الرموز!

يبدو أنه لا توجد وسيلة "لاكتشاف" هذه القواعد في وقت التشغيل ، تقع على عاتق لغة المضيف مسؤولية تحديد كيفية تنفيذ أشياء مثل إضافة السلسلة. C# يتكيف مع عدد المصطلحات المتتالية في إضافة ، ودعا طريقة .concat التي تتوافق مع ذلك بشكل مناسب.

لذا ، إذا كنت أرغب في دعم إضافة مثيلات الفصل حيث لم يتم تعريف المشغل لها ، على سبيل المثال ، يمكنني ببساطة كتابة أو العثور على طريقة ثابتة للقيام بذلك (من التوقيع الصحيح بالطبع!) لغة لاستخدامها في هذه الحالة. مثال كلاسيكي هنا هو ما إذا كان سيتم دعم Array1 + Array2 من خلال طرق الصفيف الثابت.

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

على هذا النحو ، من الأفضل أن تعكس المشغل أولاً ، لمعرفة ما إذا كان يتم تعريف أحدهما للنوعين ، قبل ذلك ، عند التفكير في التحويل في حالة وجود واحد.

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