BYACC(1) دستورهای کاربر (User Commands) BYACC(1)

byacc - یک تولیدکننده تجزیه‌کننده LALR(1)

byacc [ -BdghilLPrtvVy ] [ -b file_prefix ] [ -H defines_file ] [ -o output_file ] [ -p symbol_prefix ] filename

دستور Byacc مشخصات گرامر را در فایل filename می‌خواند و یک تجزیه‌کننده (parser) از نوع LALR(1) برای آن تولید می‌کند. این تجزیه‌کننده‌ها شامل مجموعه‌ای از جدول‌های تجزیه LALR(1) و یک روال گرداننده هستند که به زبان برنامه‌نویسی C نوشته شده است. Byacc به‌طور معمول جدول‌های تجزیه و روال گرداننده را در فایلی به نام y.tab.c می‌نویسد.

گزینه‌های زیر در دسترس هستند:

گزینه -b پیشوند اضافه‌شده به نام فایل‌های خروجی را به رشته تعیین‌شده توسط file_prefix تغییر می‌دهد. پیشوند پیش‌فرض نویسه y است.
ایجاد یک تجزیه‌کننده با قابلیت پس‌گرد (backtracking) (پیکربندی زمان کامپایل برای btyacc).
باعث می‌شود فایل سرآیند y.tab.h نوشته شود. این فایل شامل دستورات #define برای شناسه‌های نشانه‌ها (tokens) است.
چاپ پیام نحوه استفاده در خطای استاندارد.
باعث می‌شود تعاریف #define برای شناسه‌های نشانه‌ها در فایل مشخص‌شده defines_file به جای فایل y.tab.h استفاده‌شده در گزینه -d نوشته شود.
گزینه -g باعث می‌شود توصیف گرافیکی تجزیه‌کننده LALR(1) تولیدشده در فایل y.dot به قالب graphviz نوشته شود تا توسط dot(1) پردازش گردد.
گزینه -i باعث می‌شود فایل سرآیند تکمیلی y.tab.i نوشته شود. این فایل شامل اعلان‌های extern و تعاریف تکمیلی #define بر حسب نیاز برای نگاشت نام‌های مرسوم با پیشوند yy در yacc به نام‌های تعیین‌شده با گزینه -p است. فایل کد (مانند y.tab.c) تغییر می‌یابد تا هم این فایل و هم فایل y.tab.h را #include کند، که استفاده منسجم از نمادهای تعریف‌شده را تضمین می‌نماید.
فایل سرآیند تکمیلی، کامپایل جداگانه فایل‌های lex و yacc را ساده‌تر می‌کند.
اگر گزینه -l مشخص نشود، byacc دستورات #line را در کد تولیدشده درج می‌کند. دستورات #line به کامپایلر C اجازه می‌دهند خطاهای کد تولیدشده را به کد اصلی کاربر مرتبط کند. اگر گزینه -l مشخص شود، byacc دستورات #line را درج نمی‌کند. دستورات #line مشخص‌شده توسط کاربر حفظ خواهند شد.
فعال‌سازی پردازش موقعیت، مانند “%locations” (پیکربندی زمان کامپایل برای btyacc).
مشخص کردن نام فایل برای فایل تجزیه‌کننده. اگر این گزینه داده نشود، نام فایل خروجی برابر با پیشوند فایل به همراه پسوند آن است (مانند y.tab.c). این گزینه بر گزینه -b اولویت دارد.
گزینه -p پیشوند نمادهای تولیدشده توسط yacc را به رشته تعیین‌شده توسط symbol_prefix تغییر می‌دهد. پیشوند پیش‌فرض رشته yy. است.
ایجاد یک تجزیه‌کننده بازگشت‌پذیر (reentrant)، مانند “%pure-parser”.
گزینه -r باعث می‌شود byacc فایل‌های جداگانه‌ای برای کد و جدول‌ها تولید کند. فایل کد y.code.c و فایل جدول‌ها y.tab.c نامیده می‌شود. پیشوند “y.” می‌تواند با استفاده از گزینه -b تغییر یابد.
حذف دستورات “#define” تولیدشده برای رشته‌های ثابت در دستور “%token”، برای مطابقت بیشتر با رفتار اصلی yacc.
به‌طور معمول وقتی byacc خطی مانند خط زیر را می‌بیند:
%token OP_ADD "ADD"
متوجه می‌شود که رشته داخل گیومه “ADD” یک شناسه معتبر C است، و یک #define نه تنها برای OP_ADD، بلکه برای ADD نیز تولید می‌کند، مانند:
#define OP_ADD 257
#define ADD 258
دستور اصلی yacc دومین “#define” را تولید نمی‌کند. گزینه -s این “#define” را حذف می‌کند.
استاندارد POSIX (IEEE 1003.1 2004) فقط نام‌ها و اعداد را برای “%token” مستند می‌کند، هرچند yacc اصلی و bison رشته‌های ثابت را نیز می‌پذیرند.
گزینه -t دستورات پیش‌پردازنده تولیدشده توسط byacc را به گونه‌ای تغییر می‌دهد که دستورات اشکال‌زدایی در کد کامپایل‌شده گنجانده شوند.
Byacc خروجی اشکال‌زدایی را به خروجی استاندارد ارسال می‌کند (سازگار با هر دو نسخه اصلی yacc و btyacc)، در حالی که btyacc خروجی اشکال‌زدایی را در خطای استاندارد می‌نویسد (مانند bison).
گزینه -v باعث می‌شود توصیفی خوانا برای انسان از تجزیه‌کننده تولیدشده در فایل y.output نوشته شود.
چاپ شماره نسخه در خروجی استاندارد.
دستور byacc از این گزینه صرف‌نظر می‌کند؛ گزینه‌ای که bison برای سازگاری ظاهری با POSIX پشتیبانی می‌نماید.

پارامتر filename اختیاری نیست. با این حال، byacc علامت تکی “-” را برای خواندن گرامر از ورودی استاندارد می‌پذیرد. یک نشانگر دوگانه “--” نشان‌دهنده پایان گزینه‌ها است. پس از نشانگر “--” یک پارامتر filename تکی مورد انتظار است.

اگر قواعدی وجود داشته باشند که هرگز کاهش (reduce) نمی‌یابند، تعداد چنین قواعدی در خطای استاندارد گزارش می‌شود. اگر هرگونه تعارض LALR(1) وجود داشته باشد، تعداد تعارض‌ها در خطای استاندارد گزارش خواهد شد.

دستور Byacc برخی افزونه‌ها را برای سازگاری با bison و سایر پیاده‌سازی‌های yacc فراهم می‌کند. این دستور چندین گزینه طولانی را می‌پذیرد که معادل‌هایی در byacc دارند. قابلیت‌های %destructor و %locations فقط در صورتی در دسترس هستند که byacc برای پشتیبانی از قابلیت پس‌گرد (btyacc) پیکربندی و کامپایل شده باشد. سایر ویژگی‌ها همیشه در دسترس هستند:

%code keyword { code }
کد منبع مشخص‌شده code را در نقطه معینی از فایل خروجی اضافه می‌کند. کلمه کلیدی اختیاری keyword به byacc می‌گوید که code در کجا درج شود:
درست پس از تعریف نسخه در فایل کد تولیدشده.
درست پس از اعلان متغیرهای عمومی تجزیه‌کننده. اگر گزینه -d داده شود، کد در ابتدای فایل تعاریف درج می‌شود.
درست پس از اعلان متغیرهای خصوصی تجزیه‌کننده. اگر گزینه -d داده شود، کد در انتهای فایل تعاریف درج می‌شود.
اگر هیچ کلمه کلیدی (keyword) داده نشود، کد در ابتدای بخشی از کد که عیناً از فایل منبع کپی شده درج می‌شود. می‌توان چندین دستورالعمل %code را تعیین کرد؛ byacc آنها را به همان ترتیبی که در فایل منبع ظاهر می‌شوند در فایل کد یا تعاریف مربوطه درج می‌کند.
%debug
این کار تأثیری مشابه با گزینه خط فرمان “-t” دارد.
%destructor { code } symbol+
کدی را تعریف می‌کند که هنگام دور انداختن خودکار یک نماد در حین بازیابی خطا فراخوانی می‌شود. این کد می‌تواند برای بازپس‌گیری حافظه پویای اختصاص‌یافته به مقدار معنایی مربوطه در مواردی که اقدامات کاربر نمی‌تواند حافظه را به صراحت مدیریت کند، استفاده شود.
هنگام مواجهه با خطای تجزیه، تجزیه‌کننده تولیدشده نمادهای روی پشته و نشانه‌های ورودی را دور می‌اندازد تا به وضعیتی برسد که اجازه ادامه تجزیه را بدهد. این روش بازیابی خطا در صورتی که مقدار YYSTYPE اشاره‌گرهایی به حافظه پویا داشته باشد یا حاوی آنها باشد، منجر به نشت حافظه می‌شود.
کد داخل براکت code هر زمان که تجزیه‌کننده یکی از نمادها را دور بیندازد فراخوانی می‌شود. درون code، عبارت “$$” یا “$<tag>$” بیانگر مقدار معنایی مرتبط با نماد دور انداخته‌شده است، و “@$” بیانگر مکان آن است (دستورالعمل %locations را ببینید).
یک نابودکننده اختصاصی برای هر نماد با ذکر یک نماد گرامر در symbol+ تعریف می‌شود. یک نابودکننده برای هر نوع با ذکر یک برچسب نوع معنایی (مانند “<some_tag>”) در symbol+ تعریف می‌شود؛ در این حالت، تجزیه‌کننده هر زمان که هر نماد گرامری دارای آن برچسب نوع را دور بیندازد، کد code را فراخوانی می‌کند، مگر اینکه آن نماد نابودکننده اختصاصی خود را داشته باشد.
دو دسته نابودکننده پیش‌فرض پشتیبانی می‌شوند که هنگام دور انداختن هر نماد گرامری که نابودکننده اختصاصی نماد یا نوع ندارد، فراخوانی می‌شوند:
  • کد مربوط به “<*>” برای نمادهای گرامری استفاده می‌شود که دارای یک برچسب نوع معنایی صراحتاً اعلام‌شده هستند (از طریق “%type”);
  • کد مربوط به “<>” برای نمادهای گرامری استفاده می‌شود که برچسب نوع معنایی اعلام‌شده‌ای ندارند.
%empty
توسط byacc نادیده گرفته می‌شود.
%expect number
تعداد مورد انتظار تعارض‌های shift/reduce را به byacc می‌گوید. این کار باعث می‌شود تنها در صورت تفاوت، تعداد آن گزارش شود.
%expect-rr number
تعداد مورد انتظار تعارض‌های reduce/reduce را به byacc می‌گوید. این کار باعث می‌شود تنها در صورت تفاوت، تعداد آن گزارش شود. این مورد (برخلاف bison) در تجزیه‌کننده‌های LALR مجاز است.
%locations
به byacc دستور می‌دهد تا مدیریت اطلاعات موقعیت مکانی مربوط به هر نشانه را فعال کند؛ اطلاعاتی که توسط تحلیل‌گر واژگانی (lexer) در متغیر سراسری yylloc ارائه می‌شود، مشابه مدیریت اطلاعات مقدار معنایی ارائه‌شده در yylval.
همانند مقادیر معنایی، موقعیت‌ها را می‌توان در اقدامات با استفاده از @$ برای ارجاع به موقعیت نماد سمت چپ، و @N (N یک عدد صحیح) برای ارجاع به موقعیت یکی از نمادهای سمت راست به کار برد. همچنین همانند مقادیر معنایی، هنگام تطبیق یک قاعده، یک عمل پیش‌فرض برای محاسبه موقعیت ارائه‌شده توسط @$ به عنوان شروع اولین نماد و پایان آخرین نماد در سمت راست قاعده استفاده می‌شود. این محاسبات پیش‌فرض را می‌توان با انتساب مستقیم به @$ در یک اقدام قاعده لغو کرد.
نوع yylloc برابر با YYLTYPE است که به طور پیش‌فرض به صورت زیر تعریف می‌شود:
typedef struct YYLTYPE {
    int first_line;
    int first_column;
    int last_line;
    int last_column;
} YYLTYPE;
ساختار YYLTYPE می‌تواند توسط کاربر در بخش اعلان‌های فایل مشخصات بازتعریف شود (باید YYLTYPE_IS_DEFINED تعریف شود تا از تعریف پیش‌فرض جلوگیری به عمل آید). همانند bison، ماکروی YYLLOC_DEFAULT هر بار که یک قاعده تطبیق داده می‌شود، فراخوانی می‌شود تا موقعیت سمت چپ قاعده را پیش از اجرای اقدام مربوطه محاسبه کند؛ این ماکرو توسط کاربر قابل بازتعریف است.
این دستورالعمل یک پارامتر YYLTYPE به yyerror() اضافه می‌کند. اگر دستورالعمل %pure-parser وجود داشته باشد، یک پارامتر YYLTYPE به فراخوانی‌های yylex() اضافه می‌شود.
%lex-param { argument-declaration }
به طور پیش‌فرض، تحلیل‌گر واژگانی هیچ پارامتری نمی‌پذیرد (مانند yylex()). از این دستورالعمل برای افزودن اعلان‌های پارامتر برای تحلیل‌گر واژگانی سفارشی خود استفاده کنید.
%parse-param { argument-declaration }
به طور پیش‌فرض، تجزیه‌کننده هیچ پارامتری نمی‌پذیرد (مانند yyparse()). از این دستورالعمل برای افزودن اعلان‌های پارامتر برای تجزیه‌کننده سفارشی خود استفاده کنید.
%pure-parser
بیشتر متغیرها (به جز yydebug و yynerrs) روی پشته در yyparse تخصیص داده می‌شوند که باعث می‌شود تجزیه‌کننده تا حد معقولی بازگشت‌پذیر (reentrant) باشد.
%token-table
نام‌های تجزیه‌کننده را برای نشانه‌ها در آرایه yytname در دسترس قرار می‌دهد. با این حال، byacc نمادهای “$end”، “$error” یا “$undefined” را از پیش در این آرایه تعریف نمی‌کند.

بر اساس توضیحات رابرت کوربت (Robert Corbett):

برکلی یَک (Berkeley Yacc) یک تولیدکننده تجزیه‌کننده LALR(1) است.
Berkeley Yacc تا حد ممکن با AT&T Yacc سازگار ساخته شده است.
Berkeley Yacc می‌تواند هر مشخصات ورودی که با مستندات AT&T Yacc مطابقت دارد را بپذیرد.
مشخصاتی که از ویژگی‌های مستندنشده AT&T Yacc بهره می‌برند احتمالاً رد خواهند شد.

استدلال‌های موجود در

برخی از ویژگی‌های AT&T yacc را که دیگر برای انطباق با POSIX لازم نیستند، مستند می‌کند.

با این حال، ممکن است علاقه‌مند به استفاده مجدد از فایل‌های گرامر با برخی پیاده‌سازی‌های دیگر باشید که کاملاً با AT&T yacc سازگار نیستند؛ به عنوان مثال، bison. در اینجا چند تفاوت آورده شده است:

•
دستور Yacc علامت مساوی قبل از آکولاد باز یک اقدام (action) را می‌پذیرد (همان‌طور که در فایل گرامر اصلی ftp.y وجود داشت):
|   STAT CRLF
    = {
            statcmd();
    }
  • دستور Yacc و bison کد را به ترتیب متفاوتی منتشر می‌کنند؛ به ویژه bison به توابع متداولی مانند yylex، yyparse و yyerror بدون ارائه پیش‌نمونه (prototype) ارجاع به جلو می‌دهد.
  • پشتیبانی Bison از “%expect” در بیش از یک نسخه دچار ایراد است. برای بهترین نتیجه هنگام استفاده از bison، آن دستورالعمل را حذف کنید.
  • برنامه Bison معادل‌هایی برای برخی از گزینه‌های خط فرمان byacc ندارد و به دستورالعمل‌های تعبیه‌شده در فایل گرامر متکی است.
  • گزینه “-y” در bison بر عدم پشتیبانی آن از ویژگی‌های منسوخ‌شده AT&T yacc تأثیری ندارد.
  • دستور Yacc چندین پارامتر را با %lex-param و %parse-param در دو قالب می‌پذیرد:
{type1 name1} {type2 name2} ...
{type1 name1,  type2 name2 ...}
دستور Bison شکل دوم را می‌پذیرد (هرچند مستند نشده است)، اما بسته به نسخه ممکن است کد نامناسبی تولید کند.
•
همانند bison، برنامه byacc پارامترهای مشخص‌شده از طریق %parse-param را به yyparse، yyerror و (در صورت پیکربندی برای پس‌گرد) به نابودکننده اعلام‌شده با %destructor اضافه می‌کند. دستور Bison پارامترهای اضافی را برای yyparse و yyerror در ابتدا اما برای نابودکننده‌ها در انتها قرار می‌دهد. دستور Yacc نیز با این رفتار مطابقت دارد.

bison(1), btyacc(1), lex(1), flex(1), yacc(1)

2024-12-31 Berkeley Yacc