ابزارهای زیادی برای ساخت تحلیلگرهای لغوی و نحوی موجود در کامپایلرها وجود دارند که از معروفترین آنها میتوان به زوج 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

Print this pageEmail this to someoneShare on Google+Share on FacebookShare on LinkedInTweet about this on TwitterShare on RedditShare on TumblrShare on StumbleUponPin on Pinterest