لکس
لکس (به انگلیسی: Lex) در علوم کامپیوتر برنامهای است که تحلیلگرهای لغوی را (اسکنرها یا لکسرها) تولید میکند. Lex معمولاً با یَک (نرمافزار تولید کنندهٔ پارسر) استفاده میشود. Lex در اصل، توسط Eric Schmidt و Mike Lesk طراحی و نوشته شد و این تحلیلگر لغوی، بهطور استاندارد تحت سیستمهای یونیکس است و یک ابزار برای نمایش رفتار (که برگرفته از استاندارد پازیکس است) دارد. Lex یک رشته را از ورودی میخواند و تحلیلگر لغوی را مشخص میکند و خروجی، سورس کد یک Lexer به زبان برنامه نویسی سی است. بههرحال، نسخههای اختصاصی سنتی Lex، همچون اوپنسولاریس و پلان ۹ برپایهٔ کد AT&T به صورت متن باز و جزئی از این سیستمها موجود میباشند. همچنین نسخهٔ دیگری از Lex نیز به صورت متن باز و با نام تحلیلگر واژگانی فلکس رایج است.
ساختار یک فایل Lex
ساختار یک فایل Lex عمداً شبیه به یک فایل Yacc است. فایلها به سه بخش تقسیم میشوند که هر بخش با %% از بخش دیگر جدا میشود:
بخش تعریف %% بخش قواعد %% بخش کد زبان C
- قسمت تعریف (definition section)، جایی برای تعریف ماکروها و وارد کردن فایلهای سرآمدی (header) است که به زبان C نوشته شدهاند. همچنین امکان اینکه هر کدی از زبان C را در اینجا بنویسید، وجود دارد، و این کد به صورت کلمه به کلمه، در کد اصلی تولید شده خواهد آمد.
- قسمت قواعد (rules section)، مهمترین بخش است که الگوها (عبارات منظم ساده) را با استفاده از دستورهای زبان C با هم مرتبط میسازد. زمانی که لکسر، متون را از ورودی میگیرد، الگوی معینی را برایشان مشخص میکند و کد (به زبان C) مرتبط با آن الگو را نیز اجرا میکند. و این چرخهٔ اصلی فعالیت Lex است.
- قسمت کد زبان C (C code section)، شامل دستورهای و توابع کد زبان C است که کلمه به کلمه به فایل سورس تولید شده، اضافه میشود. احتمالاً این دستورهای حاوی کدهایی هستند که در قسمت قواعد، توسط قواعد مختلف، فراخوانی میگردند. بهتر است که در برنامههای بزرگ، این بخش بهطور جداگانه در یک فایل دیگر قرار بگیرد و در زمان کامپایل، به فایل اصلی اضافه شود.
مثالی از فایل Flex
در ادامه یک فایل Lex از ویرایش Flex میآید. که یک رشتهای از اعداد صحیح را از ورودی، تشخیص داده و در خروجی نمایشش میدهد:
/*** Definition section ***/
%{
/* C code to be copied verbatim */
#include <stdio.h>
%}
/* This tells flex to read only one input file */
%option noyywrap
%%
/*** Rules section ***/
/* [0-9]+ matches a string of one or more digits */
[0-9]+ {
/* yytext is a string containing the matched text. */
printf("Saw an integer: %s\n", yytext);
}
.|\n { /* Ignore all other characters. */ }
%%
/*** C Code section ***/
int main(void)
{
/* Call the lexer, then quit. */
yylex();
return 0;
}
اگر رشته ورودی به Flex ارسال شود، آن را به فایل C (lex.yy.c) تبدیل میکند. و به فایل قابل اجرا، کامپایل میشود که رشتهای از اعداد صحیح را تشخیص داده و در خروجی نمایش میدهد. بهعنوان مثال اگر رشتهٔ زیر را بهعنوان ورودی بدهیم:
abc123z.!&*2gj6
برنامه، خروجی زیر را خواهد داشت:
Saw an integer: 123 Saw an integer: 2 Saw an integer: 6
استفاده از Lex به همراه Yacc
عموماً Lex و Yacc(تولید کنندهٔ Parser) در کنار یکدیگر مورد استفاده قرار میگیرند. چون Lex به ماشینهای قطعی (DFA) محدود میشود بنابراین آن رشتههای ورودی، که Lex با استفاده از عبارات منظم قادر به تجزیهٔ آنها نیست، Yacc با استفاده از یک گرامر رسمی، آنها را تجزیه میکند، با این حال، Yacc قادر به دریافت رشته از ورودی نیست و به مجموعهای از توکنها احتیاج دارد. غالباً Lex برای تأمین توکنهای مورد نیاز Yacc مورد استفاده قرار میگیرد.
Lex و ساختن
مزیت ساختن، برای حفظ و نگهداری برنامههایی است که شامل Lex هستند. سازنده هر فایلی را که دارای پسوند.l باشد را فایل سورس Lex در نظر میگیرد. و چنین فایلی را بهعنوان فایلی که باید به فایل مقصد تبدیل شود، میشناسد. بهطور مثال اجازه دهید تا فایلی با نام ex.l و فایل قابل اجرای EXE را در خروجی داشته باشیم. روش معمول به صورت زیر است:
$>lex ex.l <return>
شما فایلی با نام lex.yy.c را خواهید داشت.
$>gcc -o EXE lex.yy.c -ll (or -lfl) <return>
با این روش ما فایل EXE را تهیه میکنیم.
EXE: ex.o <tab>gcc -o EXE ex.o –ll
قبل از تعریفات سازنده، <tab> مورد نیاز است. یعنی در هر زمان فقط سازنده اجرا میشود:
$> make <return>
این کار در اینجا بسیار سریع انجام شد اما اگر شما به ۱۰ فایل برای کامپایل، نیاز داشته باشید، آنگاه این روش واقعاً مفید خواهد بود.
منابع
۱. ^ "make", The Open Group Base Specifications Issue ۶، IEEE Std ۱۰۰۳٫۱، ۲۰۰۴ Edition (The IEEE and The Open Group), ۲۰۰۴، http://www.opengroup.org/onlinepubs/009695399/utilities/make.html