تحليل/تقييم التعبير المنطقي الديناميكي في C# أو VB؟

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

  •  20-08-2019
  •  | 
  •  

سؤال

الأفضل هو تقييم تعبير مثل ما يلي:
(أ و ب) أو (أ و ج) أو (ليس ب و ج)
أو
(A && B) || (A && C) || (! B && C)

في وقت التشغيل، كنت أخطط لتحويل التعبيرات المذكورة أعلاه إلى ما يلي:
(صح وخطأ) أو (صح وخطأ) أو (ليس خطأ وصحيح)
أو
(True && false) || (True && false) || (!خطأ && صحيح)

شروط:1) التعبير المنطقي غير معروف حتى وقت التشغيل.2) لا يُعرف المتغير الرقمي وقيمه حتى وقت التشغيل.3) القيم المتغيرة لا تكون فارغة أبدًا.

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

اقتراحات؟

شكرًا.

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

المحلول

إذا كنت تستخدم .NET3.5 ثم يمكنك تحليل النص، وخلق شجرة sytax المجردة باستخدام فئات التعبير. ثم إنشاء مثيل LambdaExpression مناسبة وترجمة ذلك إلى مندوب، والتي يمكنك تنفيذ ذلك الحين.

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

إذا كنت لا تستخدم .NET3.5، ثم كما انها ليست معقدة لتنفيذ تفسير مجردة شجرة جملة نفسك.

نصائح أخرى

وحذر من أن يكون: شرطين النهائية التي نتحدث عنها هي لا يعادل بالضرورة. ومشغلي && في C # استخدام دائرة قصر evalution، في حين أن المشغل And المنطقي في VB لا. إذا كنت تريد أن تتأكد من البيانات تعادل، ترجم And المستخدم لAndAlso وOr المستخدم لOrElse.

لexpresssions بسيطة ربما لن تلاحظ الفرق. ولكن إذا كانت الشروط يمكن أن يكون لها آثار جانبية أو إذا كان الفرق في الأداء بين الاثنين هو مصدر قلق، وهذا يمكن أن يكون مهما.

يمكنك القيام بذلك بسهولة باستخدام:

  1. مولد محلل (مثل ANTLR، المذكور أعلاه) يأخذ التعبيرات المنطقية كمدخلات وينتج قائمة infix و
  2. رمز لتقييم مكدس التدوين البولندي العكسي.

تبدو القواعد النحوية كما يلي:

program: exprList ;

exprList: expr { Append($1); }
    | expr OR exprList { Append(OR); }
    | expr AND exprList { Append(AND); }
    | NOT exprList { Append(NOT); }
    | ( exprList ) { /* Do nothing */ }
    ;

expr: var { Append($1); }
    | TRUE { Append(True); }
    | FALSE { Append(False); }
    ;

للتقييم، قم بما يلي:

for each item in list
    if item is symbol or truth value, push onto RPN stack
    else if item is AND, push (pop() AND pop())
    else if item is OR, push (pop() OR pop())
    else if item is NOT, push (NOT pop())

result = pop()

بالنسبة للرموز، عليك استبدال قيمة الحقيقة في وقت التشغيل.

ويمكنك استخدام https://github.com/mrazekv/logicalparser

وبساطة مكتبة لكتابة تعبير منطقي (evaulated مع طاولة precenednce، ويسمح لOR، NOT، AND المشغل و>،> =، <=، <على المتغيرات عدد صحيح و= على متغيرات السلسلة)

ويمكنك إرسال بريد مترجم بسيط / محلل. استخدام شيء مثل ANTLR و إعادة استخدام قواعد النحو القائم.

إذا كنت تستخدم .NET Framework 3.5، يمكنك إنشاء تعبير لامدا. ثم يمكنك إنشاء مندوب من ذلك، وندعو مندوبا القياسية / الأسلوب. على شبكة الانترنت الكثير من العينات حوالي امدا التعبير.

وحل واحد سيكون لتجميع التعبير كسلسلة، ومن ثم إرساله SQL Server أو أيا كان قاعدة البيانات هي للتقييم. استبدال المتغيرات الفعلية مع 1 = 1 أو 0 = 1 لالصواب والخطأ على التوالي، وكنت في نهاية المطاف مع استعلام مثل هذا:

وSELECT 1 WHERE (1 = 1 و0 = 1) أو (1 = 1 و 1 = 1) أو (لا 0 = 1 و 1 = 1)

وبعد ذلك عند تشغيل الاستعلام، وتحصل على الظهر 1 عندما تكون النتيجة صحيحة. قد لا يكون الحل الأكثر أناقة، لكنها ستعمل. وهناك الكثير من الناس وربما ينصح ضد هذا، ولكن أنا مجرد الذهاب الى رميها هناك كحل ممكن على أي حال.

لن تكون هذه أفضل إجابة، لكني واجهت هذه المشكلة منذ فترة.

هذا هو الكود القديم الخاص بي:VB.Net - لا يوجد ضمان على الإطلاق!

https://cloud.downfight.de/index.php/s/w92i9Qq1Ia216XB

Dim BoolTermParseObjekt As New BoolTermParse
MsgBox(BoolTermParseObjekt.parseTerm("1 und (((0 oder 1 und (0 oder 4))) oder 2)").ToString)

يأكل هذا الكود سلسلة تحتوي على عدة "('،')'، و'و'، و'أو' بالإضافة إلى "أشياء أخرى" ويقسم المنطق إلى قيمة منطقية عن طريق استبدال الأشياء بقيم منطقية.لذلك:

مهما كانت "الأشياء الأخرى" التي أردت تقييمها ، كان عليّ أن أضع في حل الوظيفة () في تعليق "Funktionen Ausführen und Zurücgeben ، Einzelwert!" في الصفحة 2.هناك التقييم الوحيد الآن هو "إذا كان الرقم > 1"

تحيات

ونلقي نظرة على مكتبتي، Proviant . انها مكتبة. NET قياسي باستخدام خوارزمية السحب يارد لتقييم التعبيرات المنطقية.

ويمكن أيضا توليد جدول الحقيقة للتعبير الخاص بك.

ويمكنك أيضا تنفيذ قواعد اللغة الخاصة بك.

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