اكتشاف OP_ADDITION أو تنفيذ طريقة للتعبير. add
-
03-10-2019 - |
سؤال
أنا أكتب لغة باستخدام أشجار 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 من خلال طرق الصفيف الثابت.
أما بالنسبة لاكتشاف المشغلين ، فإن طريقة التعبير. العائد تهتم بذلك ، لكنها لا تؤدي تلقائيًا إلى أي تحويلات ، لذلك ، كما هو الحال مع طريقة الترويج للنقطة المتكاملة/العائمة التي أشير إليها في السؤال ، مرة أخرى ، الأمر متروك للغة قواعد لتحديد ما إذا كانت التحويلات الأخرى مطلوبة قبل محاولة بناء التعبير.
على هذا النحو ، من الأفضل أن تعكس المشغل أولاً ، لمعرفة ما إذا كان يتم تعريف أحدهما للنوعين ، قبل ذلك ، عند التفكير في التحويل في حالة وجود واحد.