كيف أقوم بتنفيذ ماسح ضوئي ثنائي المرور باستخدام Flex؟

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

سؤال

كمشروع مفضل، أود أن أحاول تنفيذ لغة أساسية من تصميمي الخاص والتي يمكن استخدامها كلغة برمجة نصية للويب.من السهل تشغيل برنامج C++ باعتباره Apache CGI، لذا فإن العمل الحقيقي يكمن في كيفية تحليل ملف إدخال يحتوي على تعليمات برمجية غير رمزية (علامات HTML/CSS) ورمز من جانب الخادم.

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

الفرق بين ذلك وما أود فعله هو أنه مثل PHP، يمكن أن تحتوي هذه اللغة على ترميز HTML عادي ولغة البرمجة النصية تتخللها ما يلي:

<p>Hello,
<? echo "World ?>
</p>

هل أنا مخطئ في افتراض أنه سيكون من الفعال تحليل ملف الإدخال على النحو التالي:

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

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

إن كان هذا لا نمط تصميم متين، كيف تتعامل لغات مثل PHP مع إدخال المسح الضوئي وتحليل التعليمات البرمجية بكفاءة؟

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

المحلول

تريد أن تنظر إلى شروط البداية.على سبيل المثال:

"<?"            { BEGIN (PHP); }
<PHP>[a-zA-Z]*  { return PHP_TOKEN; }
<PHP>">?"       { BEGIN (0); }
[a-zA-Z]*       { return HTML_TOKEN; }

تبدأ بالحالة 0، استخدم ماكرو BEGIN لتغيير الحالات.لمطابقة RE فقط أثناء وجودك في حالة معينة، ضع بادئة RE باسم الحالة محاطًا بأقواس زاوية.

في المثال أعلاه، "PHP" هو الحالة."PHP_TOKEN" و"HTML_TOKEN" هما _%token_s محددان بواسطة ملف yacc الخاص بك.

نصائح أخرى

لا تفرق PHP بين المسح والترميز.فهو ببساطة يقوم بالإخراج إلى المخزن المؤقت عندما يكون في وضع العلامات، ثم يتحول إلى التحليل عندما يكون في وضع التعليمات البرمجية.لا تحتاج إلى ماسح ضوئي ثنائي التمرير، ويمكنك القيام بذلك باستخدام معجم مرن واحد فقط.

إذا كنت مهتمًا بكيفية عمل PHP نفسها، فقم بتنزيل المصدر (جرب مصدر PHP4 فهو أسهل بكثير في الفهم).ما تريد الاطلاع عليه موجود في دليل Zend، zend_language_scanner.l.

بعد أن كتبت شيئًا مشابهًا بنفسي، أوصي حقًا بإعادة التفكير في اتباع طريق Flex وBison، والذهاب إلى شيء حديث مثل أنتلر.إنه أسهل بكثير وأسهل للفهم (وحدات الماكرو المستخدمة في القواعد النحوية تصبح مربكة للغاية ويصعب قراءتها) وهي تحتوي على مصحح أخطاء مدمج (AntlrWorks) حتى لا تضطر إلى قضاء ساعات في النظر إلى ملفات تصحيح 3 ميجا.كما أنه يدعم العديد من اللغات (Java، وc#، وC، وPython، وActionscript) ويحتوي على كتاب ممتاز وموقع ويب جيد جدًا من شأنه أن يكون قادرًا على تشغيلك في أي وقت من الأوقات.

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