سؤال

لدي GRAMMAR YACC (BISON)، ومأكولات LEX (FLEX)، وبرنامج جيم الذي أحتاجه لمشاركة struct (أو حقا أي متغير). حاليا، أعلن الكائن الفعلي في ملف القواعد و extern إنه أينما كنت في حاجة إليها (وهو القول، ملف المصدر C الخاص بي)، عادة باستخدام مؤشر لمعالجة ذلك. لدي ملف رأس مشترك (وتنفيذ) بين ملف C وملف Grammar مع وظائف مفيدة لمعالجة بنية البيانات الخاصة بي. هذا يعمل، لكنه يشعر بعدم الارتياح قليلا. هل هناك طريقة أفضل لمشاركة الذاكرة بين القواعد والبرنامج؟

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

المحلول

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

نصائح أخرى

إذا كنت ترغب في التمسك بمعيار (Posix) LEX / YACC، فسيكون خيارك الوحيد هو الذهاب إلى المتغيرات / الوظائف العالمية. إذا كنت بخير باستخدام Bison و Flex Extensions، فهناك طرق لتمرير المتغيرات حولها، والتي تشمل في الغالب إضافة معلمات إضافية إلى YYPARESE () و Yylex ().

في Bison، يتم إنجاز ذلك من خلال٪ Lex-Param و٪ Parse-Parme.

%parse-param { struct somestruct *mystruct }
%lex-param { struct somestruct *mystruct }

في Flex، هناك نوعان مختلفان، اعتمادا على ما إذا كنت تريد Lexer Reentrant أم لا. على افتراض أنك تذهب مع الخيار الافتراضي (غير Reentrant)، سترغب في إعادة تعريف YY_DECL:

%{
#define YY_DECL int yylex(struct somestruct *mystruct)
%}

في Reentrant Flex Lexer، يمكن إضافة حجج إضافية من خلال بنية الماسحة الضوئية التي تنقل المرن للحفاظ على حالتها. سترغب في تحديد yy_extra_type؛ يمكن الوصول إلى البيانات الإضافية من خلال yyget / set_extra ().

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