سؤال

أخلق مترجم مع Lex و YACC (في الواقع Flex و Bison). تتيح اللغة مراجع إلى الأمام غير محدود إلى أي رمز (مثل C #). المشكلة هي أنه من المستحيل تحليل اللغة دون معرفة ما هو المعرف.

الحل الوحيد الذي أعرفه هو LEX المصدر بأكمله، ثم قم بتحليل "اتساع أولا"، لذلك يتم تحليل أشياء أعلى مستوى مثل تصريحات الفئة وإعلانات الوظائف قبل الوظائف التي تستخدمها. ومع ذلك، فإن هذا سيستغرق كمية كبيرة من الذاكرة للملفات الكبيرة، وسيكون من الصعب التعامل مع YACC (سيتعين علي إنشاء قواعد النحوية منفصلة لكل نوع من الإعلانات / الجسم). أود أيضا أن أدمج الكتابة إلى Lexer (وهذا ليس الكثير من المشكلة).

لا يهمني الكثير حول الكفاءة (على الرغم من أنه لا يزال مهم)، لأنني ذاهب لإعادة كتابة المحول البرمجي في حد ذاته بمجرد الانتهاء منه، لكنني أريد أن يكون هذا الإصدار سريعا (لذلك إذا كان هناك أي عام سريع التقنيات التي لا يمكن القيام بها في Lex / YACC ولكن يمكن القيام به باليد، يرجى اقتراح لهم أيضا). حتى الآن، سهولة التنمية هي أهم عامل.

هل هناك أي حلول جيدة لهذه المشكلة؟ كيف يتم ذلك عادة في مجال التحويل البرمجيات لغات مثل C # أو Java؟

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

المحلول

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

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

تحرير: إذا كنت تريد أن ترى كيف يتم ذلك، تحقق من التعليمات البرمجية المصدر لتجميع Mono C #. هذا هو بالفعل مكتوب في C # بدلا من C أو C ++، ولكنه يستخدم .NET ميناء Jay وهو مشابه جدا YACC.

نصائح أخرى

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

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

بالنسبة لعمل العديد من النحو، فإن القليل من المرح مع Preprocessor في ملف YACC ويجب أن تكون قادرا على تحقيقها من نفس المصدر الأصلي

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