رد کردن این محتوا

ساخت زبان برنامه نویسی ریاضی : بخش Lexer

در مقاله ی قبل توضیح دادیم FLex و Bison چه نرم افزار هایی هستند و قول داده بودیم با این دو نرم افزار پروژه شمارش کلمات کلیدی زبان را انجام بدیم، ولی به دلیل پیچیدگی موضوع تصمیم گرفتیم که در ابتدا یک زبان برنامه نویسی ساده تر طراحی کنیم و بعد به موضوع گفته شده بپردازیم.

تعریف زبان برنامه نویسی

یک زبان برنامه نویسی به صورت کلی شامل کلمات و ساختار های مختلفی است که با دنبال کردن دستورات آن می توان از کامپیوتر نتیجه ی خاصی را انتظار داشت.

مراحل تبدیل زبان برنامه نویسی از متن قابل درک برای انسان تا تبدیل به زبان ماشین باید مراحل زیر طی شود.

  1. شناسایی کلمات زبان (Lexer)
  2. شناسایی ساختار های زبان (Parser)
  3. ساخت درخت از ساختار زبان (Parser tree)
  4. ساخت کدهای زبان ماشین بر اساس Parser Tree

این چهار مرحله، مراحل ساخت کامپایلر هستند. برای ساخت مفسر که قصد ما می باشد، در مرحله ی چهارم به جای ساخت کد زبان ماشین، مستقیما درخت پارس را اجرا می کنیم.

تعریف پروژه

در این پروژه قصد داریم یک زبان برنامه نویسی طراحی کنیم که توانایی انجام محاسبات ریاضی را داشته باشد.

این زبان شامل اعداد اعشاری و صحیح و علامت های ریاضی، با رعایت اولویت و توابع و متغیر می باشد.

  • اعداد اعشاری : اعداد اعشاری شامل اعدادی به صورت “a.b” هستند که a  و b مجموعه ای از 0 تا 9 هستند.
  • اعداد صحیح : اعداد صحیح به صورت مجموعه ای از اعداد 0 تا 9 تعریف می شود.
  • علامت های ریاضی : علامت های + ، – ، * ، / ، % (به عنوان باقیمانده)
  • توابع : توابع ریاضی شامل توابعی مانند sin ، cos و توابع دیگر …
  • متغیر : برای نوشتن توابع پیچیده نیاز به متغیر است تا بتوان بخش های مختلف را از هم تفکیک کرد. متغیرها به صورت ترکیبی از حروف و اعداد تعریف می شوند، که باید با حرف شروع شوند.
  • پرانتر : برای تغییر اولویت عملیات در این زبان از پرانتز استفاده می شود.

ساخت Lexer

به صورت کلی Lexer وظیفه ی شناسایی اجزای زبان را دارد و در واقع کلمات زبان را شناسایی می کند و در اختیار Parser قرار می دهد.

برای ساخت Lexer از زبان علامت گذاری Regex که یک زبان منظم است استفاده می کنیم. هر مجموعه از کلمات زبان با یک regex مشخص می شود که نباید با regex های دیگر اشتراک داشته باشد.
در صورتی که دو regex با هم اشتراک داشته باشد regex ای تایید می شود که کلمه ی بزرگتری تولید کند. متاسفانه توضیحات regex از حوصله ی این مقاله خارج است و یادگیری آن را به خواننده می سپاریم.

Regex برای اعداد اعشاری به صورت زیر تعریف می شود.

که اجزای این جمله عبارت از [] که نماد مجموعه است و یکی از اعضای این مجموعه را می توان انتخاب کرد.
علامت + نماد یکی با بیشتر است پس []+ یعنی حداقل یکی یا بیشتر از اعضای این مجموعه.
علامت * نماد هیچ یا بیشتر است.
علامت \ به معنای رها کردن است، به این معنا که منظور از حرف بعد از علامت \ دقیقا همان حرف است. بعضی حروف در regex معنای خاصی دارند مثل . + * و … برای اینکه بتوانیم از این حروف در زبان برنامه نویسی استفاده کنیم باید آن ها را Escape کنیم و این کار توسط کاراکتر \ انجام می شود.

برای بخش های دیگر زبان نیز به همین روش عمل می کنیم.

  • شناسایی فضاهای خالی [ \r\n\t]+
  • شناسایی شناسه ها [a-zA-Z]+[a-zA-Z0-9]*
  • شناسایی اعداد غیر اعشاری [0-9]+
  • شناسایی اعداد اعشاری [0-9]+\.[0-9]+
  • شناسایی علامت ها [+,-]

با توجه به موارد توضیح داده شده و آموزش هایی که در مقاله ی “معرفی ابزار Bison و FLex” دادیم، Lexer به صورت زیر در قالب FLex نوشته می شود.

به عنوان توضیحات بیشتر باید بگوییم که بعد از هر دستور Regex می توانیم کد های سی متناسب با آن Regex را در مقابل آن بنویسیم.
محتوای کلمه ی شناسایی شده توسط Regex در متغییر yytext قرار می گیرد و می توانیم نسبت به این متن و Regex تصمیم بگیریم چه توکنی به پارسر ارسال شود.
با دستور return می توانیم توکن مد نظر را به پارسر ارسال کنیم.

کد کامل لکسر را می توانید در گیت هاب ببینید.

منتشر شده آموزش

اولین نظر دهنده باشید

دیدگاهتان را بنویسید

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