YACC، تطبيق القاعدة فقط مرة واحدة
سؤال
أحاول كتابة قذيفة باستخدام YACC و LEX وتشغيلها في بعض المشاكل مع إعادة توجيهات I / O الخاصة بي. حاليا، يمكنني استخدام المشغلين <و> بشكل جيد وفي أي ترتيب، ولكن مشكلتي هي أن أعيد توجيه مرتين دون أي خطأ، مثل "LS> سجل> LOG2"
رمز قواعدي أدناه، هل يمكن لأي شخص أن يعطيني بعض النصائح حول كيفية إصلاح هذا؟ شكرا!
io_mod:
iomodifier_opt io_mod
|
;
iomodifier_opt:
GREAT WORD {
printf(" Yacc: insert output \"%s\"\n", $2);
Command::_currentCommand._outFile = $2;
}
|
LESS WORD {
printf(" Yacc: insert input \"%s\"\n", $2);
Command::_currentCommand._inputFile = $2;
}
| /* can be empty */
;
تحرير: بعد التحدث إلى بلدي TA، تعلمت أنني لم أحسب فعلا أن يكون لديك 1 تعديل واحد فقط لأمري وأنني فعلا يمكن أن يكون لديك نسخ متعددة من نفس إعادة توجيه الإدخال / الإخراج.
المحلول
هناك طريقتان:
(1) تعديل القواعد الحثية حتى تتمكن من الحصول على واحد من كل نوع من المعدل:
io_mod_opt: out_mod in_mod | in_mod out_mod | in_mod | out_mod | ؛
(2) تعديل معالج البوليات لحساب المعدلات وإبلاغ خطأ إذا كان هناك أكثر من واحد:
Great_word {IF (INAGE_HAVE_OUTPUT_FILE ()) {خطأ ("العديد من ملفات الإخراج: "٪ s " n"، $ 2)} آخر {/ * سجل الإخراج * /}
يبدو من المرجح أن يؤدي الخيار (2) إلى رسائل خطأ أفضل وقواعد قواعد أبسط.
نصائح أخرى
هناك أيضا نهج ثالث - لا تقطع. باش (تحت Cygwin) لا يولد خطأ ل:
ls > x > y
إنه يخلق x ثم Y وينتهي الكتابة إلى y.
أدرك أن هذا قد يكون مجرد تمرين لتعلم LEXX و YACC، ولكن خلاف ذلك السؤال الأول هو أن نسأل لماذا تريد استخدام LEXX و YACC؟ أي لغة قيادة شل المعتادة لديها قواعد النحوية البسيطة جدا؛ ما الذي تحصل عليه من استخدام مولد Lalr؟
حسنا، بخلاف التعقيد، صعوبة في توليد رسائل خطأ جيدة، وسائخ الرمز، أعني.