ساخت Parser برای گرامر Ansi C با استفاده از مولدهای FLEX و YACC

ابزارهای زیادی برای ساخت تحلیلگرهای لغوی و نحوی موجود در کامپایلرها وجود دارند که از معروفترین آنها میتوان به زوج Flex و Yacc اشاره نمود.
ابزار Flex یک مولد تحلیلگر لغوی (Lexical Analyzer)، بر مبنای عبارتهای منظم (Regular expressions) مشخص کننده token های گرامر است. به زبان ساده‌تر این برنامه با دریافت متن ورودی (از فایل یا خط فرمان) پس از شناسایی کلماتی خاص که با الگوهای از پیش تعریف شده برای برنامه، تطبیق می‌شوند، عملیات خاصی انجام می‌دهد.

ابزار Yacc نیز یک مولد تحلیلگر نحوی (Syntax Analyzer) است که در صورت استفاده در کنار token ،Flex های ورودی خود را از آن گرفته و سپس عملیات تحلیل معنایی را بر اساس قوانین تعریف شده گرامر انجام میدهد. در صورت عدم تعلق برنامه ورودی، به گرامر تعریف شده، میتوان پیام خطای مناسب ارائه نمود.

به عنوان مثال گرامر کامل زبان Ansi C را جهت استفاده با این دو ابزار پیاده سازی نموده‌ام که به عنوان ورودی خود، هر برنامه به زبان C را دریافت (به سادگی و با Drag&Drop فایل برنامه C بر روی parser) نموده و با تحلیل آن، صحت یا عدم صحت آن را تشخیص میدهد.

مثلا با دریافت این برنامه:

const row=3,col=3;
int table[row*col/10];

int fact(int x
{
if (x==1) return 1;
else return fact(x-1)*x;

خروجی پیام خطا خواهد بود:

[1] const row=3,col=3;
[2] int table[row*col/10];
[3]
[4] int fact(int x
[5] {
**Yacc: syntax error

و یا این برنامه:

void main()
{
int i,r,n,l,nn;
cout<<“Enter number of
queens:”;
cin>>n;
while(n>=4){
r=n%6;
if(r!=2&&r!=3){ //0,1,4,5
l=n/2;
for(i=1;i<=l;i++)cout<<“(“<<i<<“,”<<2*i<<“)”;
for(i=l+1;i<=n;i++)cout<<“(“<<i<<“,”<<2*(i-l)-1<<“)”;
}else{ //2,3
l=n/2;
nn=l*2;
cout<<“(1,”<<nn-3<<“)”;
for(i=2;i<l-1;i++)cout<<“(“<<i<<“,”<<2*i-1<<“)”;
cout<<“(“<<l-1<<“,1)”;
cout<<“(“<<l<<“,”<<nn-1<<“)”;
cout<<“(“<<l+1<<“,2)”;
cout<<“(“<<l+2<<“,”<<nn<<“)”;
for(i=3;i<l;i++)cout<<“(“<<i+l<<“,”<<2*i<<“)”;
cout<<“(“<<nn<<“,4)”;
if(r==3)cout<<“(“<<n<<“,”<<n<<“)”;
}
cout<<endl;
cin>>n;
}
}

که به سادگی صحت آن تشخیص داده می‌شود:

[1] void main()
[2] {
[3] int i,r,n,l,nn;
[4] cout<<“Enter number of queens:”;
[5] cin>>n;
[6] while(n>=4){
[7] r=n%6;
[8] if(r!=2&&r!=3){
[9] l=n/2;
[10] for(i=1;i<=l;i++)cout<<“(“<<i<<“,”<<2*i<<“)”;
[11] for(i=l+1;i<=n;i++)cout<<“(“<<i<<“,”<<2*(i-l)-1<<“)”; [12] }else{
[13] l=n/2;
[14] nn=l*2;
[15] cout<<“(1,”<<nn-3<<“)”;
[16] for(i=2;i<l-1;i++)cout<<“(“<<i<<“,”<<2*i-1<<“)”;
[17] cout<<“(“<<l-1<<“,1)”;
[18] cout<<“(“<<l<<“,”<<nn-1<<“)”;
[19] cout<<“(“<<l+1<<“,2)”;
[20] cout<<“(“<<l+2<<“,”<<nn<<“)”;
[21] for(i=3;i<l;i++)cout<<“(“<<i+l<<“,”<<2*i<<“)”;
[22] cout<<“(“<<nn<<“,4)”;
[23] if(r==3)cout<<“(“<<n<<“,”<<n<<“)”;
[24] }
[25] cout<<endl;
[26] cin>>n;
[27] }
[28] }
**Yacc: Succes program!

پیشنهاد میکنم جهت استفاده مفیدتر از این دو ابزار، مقاله Using MKS Lex & Yacc Effectively را مطالعه نمایید.دریافت فایل گرامر C و parser آن + ابزارهای Flex و Yacc

About محمد شمس

برنامه‌نویس، طراح انیمیشن و علاقمند به هوش مصنوعی

10 Comments

  1. سلام!
    خیلی مطالب مفیدی در سایت شما وجود دارد
    متشکر
    از طرف F4RR3LL

  2. سلام
    شما چه طور مطالب رو دسته بندی میکنید؟

  3. سلام
    لطفا در مورد کربرد هوش مصنوعی در روبات های انسان نما مطالبی ارائه دهید
    متشکر
    از طرف F4RR3LL

  4. سلام
    لطفا در مورد کاربرد هوش مصنوعی در روباتیک مطالبی را ارائه دهید
    متشکرم
    از طرف F4RR3LL

  5. salam mishe darbareye Lex&Yacc age mituni kami
    etelaat bezarin

  6. راهنمای استفاده از این ابزارها را در وبسایت تولید کننده به آدرس:
    http://www.scl.com/products/mks

    میتوانید پیدا کنید.
    در اکثر کتب مربوط به آنالیز و شرح کامپایلرها در مورد این دو ابزار اطلاعات جامعی موجود است.

  7. سلام
    ممنون بابت این فایل خیلی کمکم کرد.

  8. نجاتم دادید…

  9. سلام لطفا در صورت امکان درباره چگونه تولید فایل های با استفاده از بیسون توضیح دهید.برای مثال فایل تولید شده با پسوند y.tab.c و y.tab.h و y.output که چگونه تولید شده اند.

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *


× 3 = 12