ریگل (به انگلیسی: Ragel) یک کامپایلر ماشین حالت محدود و یک مولد تجزیه کننده است. در ابتدا Ragel برای C , C ++ و کد منبع اسمبلی پشتیبانی میکرد،[۱] برای پشتیبانی از چندین زبان دیگر از جمله Objective C، D، Go، Ruby و Java گسترش یافت.[۲] پشتیبانی زبانهای دیگر نیز در حال توسعه است[۳] این برنامه از تولید ماشینهای حالت جدول یا کنترل جریان از عبارات منظم[۴] و / یا نمودارهای حالت پشتیبانی میکند و همچنین میتواند تحلیل لغوی از طریق روش طولانیترین تطبیق ایجاد کند. Ragel بهطور خاص تجزیه متن و اعتبارسنجی ورودی میپردازد.[۵]
Ragel از تولید جدول یا کنترل جریان از عبارات منظم یا نمودارهای حالت پشتیبانی میکند و همچنین میتواند با روش طولانیترین تطبیق تحلیل لغوی را انجام دهد. یک ویژگی منحصر به فرد Ragel این است که اقدامات کاربر با استفاده از عملگرهایی که در عبارات منظم ادغام شدهاند، میتوانند با انتقال دستگاههای حالت دلخواه همراه شوند. Ragel همچنین از تصویرسازی ماشینهای تولید شده از طریق graphviz پشتیبانی میکند.
نمودار، یک حالت ماشین را نشان میدهد که به عنوان ورودی کاربر یک رشته از بایتها که نشانگر کاراکترهای ASCII و کدهای کنترل هستند را میگیرد. ۴۸..۵۷ معادل عبارت منظم [۰-۹] (یعنی هر رقمی) میباشند، بنابراین تنها توالیهایی که با یک رقم شروع میشوند قابل تشخیص هستند. اگر ۱۰ (نو خط) مشاهده شود، کار ما تمام است. ۴۶ علامت اعشاری ('.') بوده و ۴۳ و ۴۵ علامت مثبت و منفی ('+'، '-') و ۶۹/۱۰۱ بزرگ / کوچک 'e' هستند (برای نشان دادن یک عدد در قالب علمی). به این ترتیب موارد زیر را به درستی تشخیص داده میشوند:
۲ ۴۵ ۰۵۵ ۴۶. ۷۸٫۱ 2e5 78.3e12 69.0e-۳ 3e+۳
اما نه موارد زیر:
.۳–۵ 3.e2 2e5.۱
ورودی راگل یک عبارت منظم است و این تنها به این دلیل است که راگل یک زبان منظم را توصیف میکند. این ورودی معمولاً به صورت یک عبارت منظم دقیق نوشته نمیشود، اما در چندین قسمت مانند فرم Extended Backus – Naur است. به عنوان مثال، به جای پشتیبانی از کلاسهای کاراکترهای POSIX در نحو عبارات منظم، آنها را به عنوان قوانین تولید خودساخته و داخلی پیادهسازی میکند. همانند دیگر مولدهای تجزیه کنندهٔ معمول، Ragel اجازه میدهد تا کد دستوری برای تولیدات با نحو نوشته شود.[۶] کدی که، طبق وبسایت رسمی، مثال بالا را میسازد بصورت زیر است:
action dgt { printf("DGT: %c\n", fc); }
action dec { printf("DEC: .\n"); }
action exp { printf("EXP: %c\n", fc); }
action exp_sign { printf("SGN: %c\n", fc); }
action number { /*NUMBER*/ }
# A floating-point number literal.
number = (
[0-9]+ $dgt ( '.' @dec [0-9]+ $dgt )?
( [eE] ( [+\-] $exp_sign )? [0-9]+ $exp )?
) %number;
main := ( number '\n' )*;