باستخدام YYPARESE () لجعل مجمع تمرير اثنين؟
-
23-08-2019 - |
سؤال
أنا أكتب مجمع لوحدة تحكم صغيرة مخصصة أعمل عليه. لقد حصلت على المجمع إلى حد حيث سيتجمع التعليمات إلى ثنائي.
ومع ذلك، فإنني الآن تواجه مشاكل في الحصول على ملصقات للعمل. حاليا، عندما يواجه مجمع بلدي تسمية جديدة، يخزن اسم التسمية وموقع الذاكرة في الإشارة إليه. عندما تشير التعليمات إلى تسمية، فإن المجمع يبحث عن الملصق ويستبدل الملصق بالقيمة المناسبة.
هذا جيد ودنتي، ولكن ماذا لو تم تعريف التسمية بعد التعليمة التي تشير إليها؟ لهذا السبب، أحتاج إلى تشغيل محلل محللي على الرمز مرتين.
إليك ما لدي حاليا لوظيفتي الرئيسية:
303 int main(int argc, char* argv[])
304 {
305
306 if(argc < 1 || strcmp(argv[1],"-h")==0 || 0==strcmp(argv[1],"--help"))
307 {
308 //printf("%s\n", usage);
309 return 1;
310 }
311 // redirect stdin to the file pointer
312 int stdin = dup(0);
313 close(0);
314
315 // pass 1 on the file
316 int fp = open(argv[1], O_RDONLY, "r");
317 dup2(fp, 0);
318
319 yyparse();
320
321 lseek(fp, SEEK_SET, 0);
322
323 // pass 2 on the file
324 if(secondPassNeeded)
325 {
326 fp = open(argv[1], O_RDONLY, "r");
327 dup2(fp, 0);
328 yyparse();
329 }
330 close(fp);
331
332 // restore stdin
333 dup2(0, stdin);
334
335 for(int i = 0; i < labels.size(); i++)
336 {
337 printf("Label: %s, Loc: %d\n", labels[i].name.c_str(), labels[i].memoryLoc);
338 }
339 return 0;
340 }
أنا أستخدم هذا داخل تكوين المرن / BISON.
المحلول
إذا كان هذا هو كل ما تحتاجه، فأنت لا تحتاج إلى مجمع ثنائي المرور الكامل. إذا لم يتم تعريف التسمية عند الرجوع إليها، فأنت ببساطة إخراج عنوان مستقل (قل 0x0000) ولديك بنية بيانات تسرد كافة الأماكن بمراجع إلى الأمام والرمز الذي يشار إليه. في نهاية الملف (أو كتلة إذا كان لديك رموز محلية)، فإنك ببساطة تمر هذه القائمة وتصحيح العناوين.