یک (کامپایلر)

**یَک**،  یکی از برنامه‌های کامپیوتری است که در سیستم عامل یونیکس به کار می‌رود. کلمهٔ یَک، از عبارت [//en.wikipedia.org/wiki/Yet_Another **Yet Another**][//en.wikipedia.org/wiki/Compiler_Compiler **Compiler Compiler**] گرفته شده‌است. این برنامه، توسط S.C.Johnson در آزمایشگاه Bell توسعه پیدا کرد.

یَک، در واقع بخشی از مراحل کامپایلر است که کد منبع را گرفته و آن را از دید قواعد صرف و نحو مورد بررسی قرار می‌دهد. می‌توان اینطور بیان کرد که گرامر زبان منظم را به آن می‌دهیم و برنامهٔ آن را به زبان برنامه نویسی C می‌سازد که در آن ورودی‌ها با توجه به نقششان در گرامر، تجزیه(parse) می‌شوند.

## بایسون
یکی دیگر از برنامه‌هایی که مشابه یَک عمل می‌کند، بایسون (به انگلیسی :[//en.wikipedia.org/wiki/GNU_bison Bison]) است که سند (به انگلیسی:[//en.wikipedia.org/wiki/License License]) آن، رایگان و استفاده از آن برای عموم آزاد است.

## استفاده از هر دو برنامهٔ لکس و یَک
عموماً Lex (فاز اول کامپایل کردن یک برنامه) و یَک در کنار یکدیگر مورد استفاده قرار می‌گیرند. چون لکس به ماشین تعیین‌پذیر حالات متناهی (به انگلیسی:[//en.wikipedia.org/wiki/Deterministic_finite_automaton DFA]) محدود می‌شود، بنابراین آن رشته‌های ورودی، که لکس با استفاده از عبارات منظم قادر به تجزیهٔ آن‌ها نیست، یَک با استفاده از یک دستور زبان منظم، آن‌ها را تجزیه می‌کند، با این حال، یَک قادر به دریافت رشته از ورودی نمی‌باشد و به مجموعه‌ای از توکنها احتیاج دارد. غالباً لکس برای تأمین توکن‌های مورد نیاز یَک، مورد استفاده قرار می‌گیرد.

## ساختار یَک
برنامهٔ یَک شامل یک فایل ورودی به فورم زیر است:

   **خصوصیات تجزیه کننده**

   %%

   **نقش‌های گرامر**

   %%

   **زیرروال برنامهٔ سی**

* **قسمت اول**: شامل *لیستی از توکن* هاست که توسط تجزیه‌کننده و معیارهای نشانه‌های شروع گرامر پیش‌بینی شده‌است. شرکت پذیری عملگرها و اولویت آن‌ها هم در این قسمت یَک گنجانده شده‌اند. این خصیصه انعطاف‌پذیری بیشتری به انتخاب گرامرهای منظم می‌دهد.

**توجه***:عملگرهای افزایشی و کاهشی (جمع و تفریق، ضرب و تقسیم)، شرکت پذیری چپ دارند و اولویت کمتری نسبت به توان دارند.

*'توجه**'':توان، شرکت پذیری راست و اولیت بیشتری دارد.

به عنوان مثال:
<syntaxhighlight lang='bash'>
   % start   program

   % token   LET INTEGER IN

   % token   SKIP IF THEN ELSE END WHILE DO READ WRITE

   % token   NUMBER

   % token  IDENTIFIER

   % left  ’-’  ’+’

   % left  ’*’  ’/’

   % right  ’ˆ ’

   %% 

   قسمت دوم

    %% 

   قسمت سوم

</syntaxhighlight>
* **قسمت دوم** :شامل دستور [[زبان منظم|زبان‌های منظم]] برای زبان‌های مختلف است. هر قسمت، توسط سمی کالن از سایر قسمت‌ها جدا می‌شود. نشانهٔ **=.. ** ([[فرم بکوس-نائور]]- به انگلیسی:[//en.wikipedia.org/wiki/Backus-Naur_form BNF]) با **:** جایگزین می‌شود.

**توجه :** قسمت‌های خالی، را خالی در نظر می‌گیریم.

**توجه :**متوجه می‌شویم ساده کردن گرامر منظم نیازمند جدا کردن اولویت‌ها از گرامرها است.

برای مثال:
<syntaxhighlight lang='bash'>

   قسمت اول

    %% 

    program  :   LET declarations IN commands END ;

    declarations  :   /* empty */  | INTEGER id seq IDENTIFIER ’. ’   ;
    id seq : /* empty */   | id seq IDENTIFIER ’,’    ;

    commands : /*empty */ | commands command ’;’  ;

   command : SKIP  | READ IDENTIFIER  | WRITE exp
          |IDENTIFIER ASSGNOP exp
          |IF exp THEN commands ELSE commands FI
          | WHILE exp DO commands END  ;

    %% 

   قسمت سوم
</syntaxhighlight>
* **قسمت سوم**: شامل [[کد زبان]] سی آن است.
باید تابع یکنواخت ()main وجود داشته باشد که تابع ()yyparse را صدا زند.

تابع ()yyerror برای گزارش خطاهای ایجاد شده به کار می‌رود.

نمونهٔ ساده‌ای از استفادهٔ توابع ()main و ()yyerror را می‌بینیم:

<syntaxhighlight lang='bash'>
   قسمت اول

    %% 

   قسمت دوم

    %% 

   main(int argc, char *argv[])

   {

      extern FILE *yyin;

      ++argv; −−argc;

      yyin = fopen(argv[۰], ”r”);

      yydebug = 1;

      errors = 0;

      yyparse();

   }

   yyerror (char *s)

   {

      printf (”%s\n”, s);

   }
</syntaxhighlight>

== کد برای اجرای یَک یا بایسون ==

بسته به اینکه از بایسون استفاده می‌کنید یا یَک، از کد پایین برای کامپایل برنامه استفاده می‌شود:

در یَک:
<syntaxhighlight lang='bash'>
    yacc -vd file.y 
</syntaxhighlight>

در بایسون:
<syntaxhighlight lang='bash'>
    bison -vd file.y 
</syntaxhighlight>

وقتی این کد را تایپ می‌کنید، در واقع دو فایل با پسوندهای **file.tab.h** و **file.tab.c** از فایلی که قبلاً نوشته بودید، ساخته می‌شود.

**file.tab.h**: شامل لیستی از توکن‌هایی است که اسکنر آن‌ها را از فایل خوانده است.

**file.tab.c''': تابع ()yyparse را در برنامهٔ سی می‌خواند.

## جستارهای وابسته
* تحلیل‌گر واژگانی فلکس
* لکس
* گنو بایسون
* برکلی یاک

## منابع

* http://epaperpress.com/lexandyacc/pry1.html
* http://www.tldp.org/HOWTO/Lex-YACC-HOWTO-6.html
* http://en.wikipedia.org/wiki/Yacc

رده:ابزارهای اس یو اس ۲۰۰۸ یونیکس
رده:ابزارهای برنامه‌نویسی یونیکس
رده:ابزارهای مرتبط با کامپایل کردن
رده:تولیدکننده‌های تجزیه‌گر