تشمل البنية في %الاتحاد مواطنه مع البيسون/Yacc
سؤال
أنا أحاول أن تشمل البنية كجزء من الاتحاد مع البيسون ، ولكن يمكنني الحصول على خطأ على البنية عقدة وسائط' في %الاتحاد:
parser.y:17: error: field ‘args’ has incomplete type
رمز:
struct node {
char * val;
struct node * next;
};
%}
%union {
char * string;
struct node args;
}
%token <string> CD WORD PWD EXIT
%type <args> arg_list
أحد يعرف ما أقوم به خطأ ؟
المحلول
حتى أفضل, استخدام %قانون التوجيه مع "يتطلب" الخيار ، أي:
%code requires {
struct node {
char * val;
struct node * next;
};
}
%union {
char * string;
struct node args;
}
وسوف يشمل هذا الرمز في "يتطلب" كتلة في علامة التبويب.ساعة الملف وكذلك محلل الملف المصدر.
من الوثائق: http://www.gnu.org/software/bison/manual/html_node/Decl-Summary.html#Decl-Summary
- يتطلب
- الغرض:هذا هو أفضل مكان لكتابة التبعية رمز المطلوبة YYSTYPE و YYLTYPE.وبعبارة أخرى ، إنه أفضل مكان لتحديد أنواع المشار إليها في %توجيهات الاتحاد ، إنه أفضل مكان لتجاوز البيسون الافتراضي YYSTYPE و YYLTYPE التعاريف.
نصائح أخرى
ويتعلق الأمر الى انخفاض الانتاج y.tab.h عرجاء تحصل عليه.
وتحتاج إلى إصلاح ذلك عن طريق ضمان أن "العقدة البنية" هو الذي يعرف قبل تضمين y.tab.h في أي مكان.
لذلك إنشاء node.h ملف تعريف البنية.
وبعد ذلك تشمل node.h قبل y.tab.h في ملف parser.l الخاص بك، ملف parser.y فضلا عن أي ملفات ج لديك والتي تشمل y.tab.h. هذا أمر مزعج قليلا.
وبدلا من ذلك يمكن أن يتغير "البنية سائط العقدة" إلى "عقدة البنية * وسائط" منذ كنت لا تحتاج إلى معرفة نوع الكامل حتى تذهب لاستخدامه في مكان ما. لست متأكدا إذا كان ذلك يتناسب مع التعليمات البرمجية.
وإما واحد يجب أن تعمل.
وربما أكثر بساطة (على ما أظن) - تستخدم هذا بنفسي:
%union {
char c;
struct {
char name[30];
int type;
} s;
}
وبعد ذلك، في العطف يمكنك استخدام "yylval.s.name"، أو "yylval.s.type"، وما إلى ذلك .. في حين البيسون، بدلا من $$=0, $1=bla
... يمكنك الآن إرسال $<s.type>$=0 , $<s.type>1=bla...