.\" Man page generated from reStructuredText. . . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .TH "RE2SWIFT" 1 "" "" "" .SH "نام (NAME)" re2swift \- تولید تحلیل‌گرهای لغوی سریع برای Swift .SH "خلاصه دستور (SYNOPSIS)" .sp re2swift \fB[ OPTIONS ]\fP \fB[ WARNINGS ]\fP \fBINPUT\fP .sp ورودی می‌تواند یک فایل یا \fB\-\fP برای stdin باشد. .SH "مقدمه (INTRODUCTION)" .sp ابزار re2swift به عنوان یک پیش‌پردازنده عمل می‌کند. این ابزار فایل ورودی را (که معمولاً برنامه‌ای به زبان Swift است، اما می‌تواند هر چیز دیگری نیز باشد) خوانده و به دنبال بلوک‌های کدی می‌گردد که درون نشانگرهای آغاز/پایان با ساختار ویژه محصور شده‌اند. متن خارج از این بلوک‌ها عیناً در فایل خروجی کپی می‌شود. محتوای درون بلوک‌ها توسط re2swift پردازش می‌شود؛ این ابزار آن‌ها را به کد زبان Swift ترجمه کرده و کد تولیدشده را به جای آن بلوک در خروجی قرار می‌دهد. .sp در اینجا مثالی از یک برنامه کوچک آورده شده است که بررسی می‌کند آیا یک رشته داده‌شده حاوی یک عدد ده‌دهی است یا خیر: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2swift $INPUT \-o $OUTPUT \-i func lex(_ yyinput: UnsafePointer) \-> Bool { var yycursor = 0 /*!re2c re2c:yyfill:enable = 0; [1\-9][0\-9]* { return true } * { return false } */ } assert(lex(\(dq1234\(dq)) .ft P .fi .UNINDENT .UNINDENT .sp در خروجی، re2swift بلوک میانی را با کد تولیدشده جایگزین کرده است: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C /* Generated by re2swift */ // re2swift $INPUT \-o $OUTPUT \-i func lex(_ yyinput: UnsafePointer) \-> Bool { var yycursor = 0 var yych: UInt8 = 0 var yystate: UInt = 0 yyl: while true { switch yystate { case 0: yych = yyinput[yycursor] yycursor += 1 switch yych { case 0x31...0x39: yystate = 2 continue yyl default: yystate = 1 continue yyl } case 1: return false case 2: yych = yyinput[yycursor] switch yych { case 0x30...0x39: yycursor += 1 yystate = 2 continue yyl default: yystate = 3 continue yyl } case 3: return true default: fatalError(\(dqinternal lexer error\(dq) } } } assert(lex(\(dq1234\(dq)) .ft P .fi .UNINDENT .UNINDENT.SH "مبانی (BASICS)" .sp یک برنامه re2swift از دنباله‌ای از \fIبلوک‌ها\fP درآمیخته با کد به زبان مقصد تشکیل می‌شود. یک بلوک ممکن است شامل \fIتعاریف\fP، \fIپیکربندی‌ها\fP، \fIقواعد\fP، \fIکنش‌ها\fP و \fIدستورالعمل‌ها\fP به هر ترتیبی باشد: .INDENT 0.0 .TP .B \fBname = regular\-expression ;\fP یک \fIتعریف\fP، \fBname\fP را به \fBregular\-expression\fP مقید می‌سازد\&. نام‌ها می‌توانند شامل نویسه‌های الفبایی\-عددی و زیرخط باشند. بخش \fI\%regular expressions\fP مروری کلی بر نحو re2swift برای عبارت‌های منظم ارائه می‌دهد. پس از تعریف، می‌توان از \fBname\fP در سایر عبارت‌های منظم و قواعد استفاده کرد. بازگشت در تعاریف نام‌گذاری‌شده مجاز نیست و هر نام باید پیش از استفاده تعریف شود. یک بلوک، تعاریف نام‌گذاری‌شده را از حوزه سراسری (global scope) به ارث می‌برد. بازتعریف نامی که در حوزه کنونی وجود دارد یک خطا محسوب می‌شود. .TP .B \fBconfiguration = value ;\fP یک \fIپیکربندی\fP امکان تغییر رفتار re2swift و سفارشی‌سازی کد تولیدشده را فراهم می‌کند. برای مشاهده فهرست کامل پیکربندی‌های پشتیبانی‌شده توسط re2swift، بخش \fI\%configurations\fP را ببینید. بسته به یک پیکربندی خاص، \fBvalue\fP می‌تواند یک کلمه کلیدی، یک عدد صحیح غیرمنفی یا یک رشته تک‌خطی باشد که در صورت عدم تشکیل از نویسه‌های الفبایی\-عددی، باید در نقل‌قول تکی یا دوگانه قرار گیرد. یک بلوک، پیکربندی‌ها را از حوزه سراسری به ارث می‌برد و می‌تواند آن‌ها را بازتعریف کرده یا موارد جدیدی بیفزاید. پیکربندی‌های تعریف‌شده درون یک بلوک، بر کل بلوک تأثیر می‌گذارند، حتی اگر در انتهای آن ظاهر شوند. .TP .B \fBregular\-expression code\fP یک \fIقاعده\fP، \fBregular\-expression\fP را به کنش معنایی آن پیوند می‌دهد (یک بلوک کد درون آکوالاد، یا بلوکی از کد که با \fB:=\fP شروع شده و در یک خط جدیدِ پس از آن با هر نویسه‌ای غیر از فضای خالی پایان می‌یابد). اگر \fBregular\-expression\fP مطابقت پیدا کند، \fBcode\fP مرتبط اجرا می‌شود. اگر چندین قاعده مطابقت داشته باشند، طولانی‌ترین تطابق اولویت دارد. اگر چندین قاعده با رشته یکسانی تطابق پیدا کنند، اولین قاعده اولویت دارد. دو قاعده ویژه وجود دارد: قاعده پیش‌فرض \fB*\fP و قاعده پایان ورودی \fB$\fP\&. قاعده پیش‌فرض همواره باید تعریف شود، صرف‌نظر از جایگاهش در بلوک دارای کمترین اولویت است، و با هر واحد کد (code unit) مطابقت می‌یابد (نه لزوماً یک نویسه معتبر، بخش \fI\%encoding support\fP را ببینید). در صورت استفاده از روش متناظر برای \fI\%handling the end of input\fP، قاعده پایان ورودی باید تعریف شود. همراه با \fI\%start conditions\fP قواعد نحو پیچیده‌تری خواهند داشت. .TP .B \fB!action code\fP یک \fIکنش\fP، بلوک کدی (\fBcode\fP) تعریف‌شده توسط کاربر را به نقطه مشخصی در ماشین حالت متناهی تولیدشده متصل می‌کند (همان‌طور که کنش‌های معنایی کد را به حالت‌های پایانی پیوند می‌دهند). برای فهرست کاملی از کنش‌های از پیش‌تعریف‌شده، بخش \fI\%actions\fP را ببینید. .TP .B \fB!directive ;\fP یک \fIدستورالعمل\fP یکی از گزاره‌های ویژه از پیش‌تعریف‌شده است. هر دستورالعمل هدف منحصربه‌فردی دارد. برای جزئیات بخش \fI\%directives\fP را ببینید. .UNINDENT .SS "بلوک‌ها (Blocks)" .sp نشانگرهای شروع و پایان بلوک یا \fB/*!re2c\fP و \fB*/\fP هستند، یا \fB%{\fP و \fB%}\fP (از هر دو شیوه پشتیبانی می‌شود). از نسخه 2.2 به بعد، بلوک‌ها می‌توانند نام‌های اختیاری داشته باشند که امکان ارجاع به آن‌ها را در سایر بلوک‌ها فراهم می‌کند. انواع مختلفی از بلوک‌ها وجود دارند: .INDENT 0.0 .TP .B \fB/*!re2c[:] ... */\fP or \fB%{[:] ... %}\fP یک \fIبلوک سراسری\fP حاوی تعاریف، پیکربندی‌ها، قواعد و دستورالعمل‌ها است. re2swift عبارت‌های منظم مرتبط با هر قاعده را در یک اتوماتای متناهی معین کامپایل کرده، آن را به شکل پرش‌های شرطی در زبان مقصد کدگذاری می‌کند و بلوک را با کد تولیدشده جایگزین می‌سازد. نام‌ها و پیکربندی‌های تعریف‌شده در یک بلوک سراسری به حوزه سراسری اضافه می‌شوند و برای بلوک‌های پس از آن قابل مشاهده خواهند بود. در آغاز برنامه، حوزه سراسری با \fI\%options\fP خط فرمان مقداردهی اولیه می‌شود\&. .TP .B \fB/*!local:re2c[:] ... */\fP or \fB%{local[:] ... %}\fP یک \fIبلوک محلی\fP شبیه بلوک سراسری است، اما نام‌ها و پیکربندی‌های موجود در آن حوزه محلی دارند (بر سایر بلوک‌ها تأثیری نمی‌گذارند). .TP .B \fB/*!rules:re2c[:] ... */\fP or \fB%{rules[:] ... %}\fP یک \fIبلوک قواعد\fP مانند یک بلوک محلی است، اما خودش کدی تولید نمی‌کند و هیچ تعریفی را هم به حوزه سراسری اضافه نمی‌نماید \-\- هدف آن، استفاده مجدد در سایر بلوک‌ها است. این روشی برای اشتراک‌گذاری کد است (جزئیات بیشتر در بخش \fI\%reusable blocks\fP). پیش از نسخه 2.2 از re2swift، بلوک‌های قواعد نیازمند گزینه \fB\-r \-\-reusable\fP بودند. .TP .B \fB/*!use:re2c[:] ... */\fP or \fB%{use[:] ... %}\fP یک بلوک use که به یک بلوک قواعد از پیش تعریف‌شده ارجاع می‌دهد. اگر نام مشخص شده باشد، re2swift به دنبال بلوک قواعدی با این نام می‌گردد. در غیر این صورت، از تازه‌ترین بلوک قواعد (چه نام‌دار یا بی‌نام) استفاده می‌شود. یک بلوک use می‌تواند تعاریف، پیکربندی‌ها و قواعد مختص به خود را اضافه کند، که این موارد به بلوک قواعد ارجاع‌شده اضافه می‌شوند. پیش از نسخه 2.2 از re2swift، بلوک‌های use نیازمند گزینه \fB\-r \-\-reusable\fP بودند. .TP .B \fB/*!max:re2c[:[:...]] ... */\fP or \fB%{max[:[:...]] ... %}\fP بلوکی که تعریف \fBYYMAXFILL\fP را تولید می‌کند. یک فهرست اختیاری از نام‌های بلوک مشخص می‌کند که هنگام محاسبه مقدار \fBYYMAXFILL\fP کدام بلوک‌ها باید لحاظ شوند (اگر فهرست خالی باشد، تمام بلوک‌ها لحاظ می‌شوند). به طور پیش‌فرض، کد تولیدشده یک تعریف ماکرو برای C (\fB#define YYMAXFILL \fP) یا یک متغیر سراسری برای Go (\fBvar YYMAXFILL int = \fP) است. این بخش را می‌توان با پیکربندی اختیاری \fBformat\fP سفارشی کرد که یک رشته الگو را مشخص می‌کند که در آن \fB@@{max}\fP (یا به اختصار \fB@@\fP) با مقدار عددی \fBYYMAXFILL\fP جایگزین می‌شود\&. .TP .B \fB/*!maxnmatch:re2c[:[:...]] ... */\fP or \fB%{maxnmatch[:[:...]] ... %}\fP بلوکی که تعریف \fBYYMAXNMATCH\fP را تولید می‌کند (نیازمند گزینه \fB\-P \-\-posix\-captures\fP است). یک فهرست اختیاری از نام‌های بلوک مشخص می‌کند که هنگام محاسبه مقدار \fBYYMAXNMATCH\fP کدام بلوک‌ها باید لحاظ شوند (اگر فهرست خالی باشد، همه بلوک‌ها لحاظ می‌شوند). به طور پیش‌فرض، کد تولیدشده یک تعریف ماکرو برای C (\fB#define YYMAXNMATCH \fP) یا یک متغیر سراسری برای Go (\fBvar YYMAXNMATCH int = \fP) است. این بخش را می‌توان با پیکربندی اختیاری \fBformat\fP سفارشی کرد که یک رشته الگو را مشخص می‌کند که در آن \fB@@{max}\fP (یا به اختصار \fB@@\fP) با مقدار عددی \fBYYMAXNMATCH\fP جایگزین می‌شود\&. .TP .B \fB/*!stags:re2c[:[:...]] ... */\fP, \fB/*!mtags:re2c[:[:...]] ... */\fP or \fB%{stags[:[:...]] ... %}\fP, \fB%{mtags[:[:...]] ... %{\fP بلوک‌هایی که قطعه کدی از نوع الگو را تعیین می‌کنند که برای هر متغیر s\-tag/m\-tag تولیدشده توسط re2swift بسط می‌یابد\&. یک فهرست اختیاری از نام‌های بلوک مشخص می‌کند که هنگام محاسبه مجموعه متغیرهای برچسب کدام بلوک‌ها باید لحاظ شوند (اگر فهرست خالی باشد، همه بلوک‌ها لحاظ می‌شوند). دو پیکربندی اختیاری وجود دارد: \fBformat\fP و \fBseparator\fP\&. پیکربندی \fBformat\fP یک رشته الگو را مشخص می‌کند که در آن \fB@@{tag}\fP (یا به اختصار \fB@@\fP) با نام هر متغیر برچسب جایگزین می‌شود. پیکربندی \fBseparator\fP قطعه کدی را مشخص می‌کند که برای متصل کردن قطعات \fBformat\fP تولیدشده برای متغیرهای برچسب مختلف به کار می‌رود. .TP .B \fB/*!svars:re2c[:[:...]] ... */\fP, \fB/*!mvars:re2c[:[:...]] ... */\fP or \fB%{svars[:[:...]] ... %}\fP, \fB%{mvars[:[:...]] ... %{\fP بلوک‌هایی که قطعه کدی از نوع الگو را تعیین می‌کنند که برای هر s\-tag/m\-tag که یا صراحتاً توسط قواعد مشخص شده است (با گزینه \fB\-\-tags\fP) یا به طور ضمنی توسط re2swift ایجاد شده است (با گزینه‌های \fB\-\-captvars\fP یا \fB\-\-posix\-captvars\fP) بسط می‌یابد. یک فهرست اختیاری از نام‌های بلوک مشخص می‌کند که هنگام محاسبه مجموعه برچسب‌ها کدام بلوک‌ها باید لحاظ شوند (اگر فهرست خالی باشد، تمام بلوک‌ها لحاظ می‌شوند). دو پیکربندی اختیاری وجود دارد: \fBformat\fP و \fBseparator\fP\&. پیکربندی \fBformat\fP یک رشته الگو را مشخص می‌کند که در آن \fB@@{tag}\fP (یا به اختصار \fB@@\fP) با نام هر برچسب جایگزین می‌شود. پیکربندی \fBseparator\fP قطعه کدی را مشخص می‌کند که برای متصل کردن قطعات \fBformat\fP تولیدشده برای برچسب‌های مختلف به کار می‌رود. .TP .B \fB/*!getstate:re2c[:[:...]] ... */\fP or \fB%{getstate[:[:...]] ... %}\fP بلوکی که یک توزیع شرطی بر روی وضعیت lexer تولید می‌کند (نیازمند گزینه \fB\-\-storable\-state\fP است). یک فهرست اختیاری از نام‌های بلوک مشخص می‌کند که کدام بلوک‌ها باید در توزیع وضعیت گنجانده شوند. گذار پیش‌فرض به برچسب آغازین اولین بلوک در فهرست انجام می‌شود. اگر فهرست خالی باشد، همه بلوک‌ها لحاظ می‌شوند و گذار پیش‌فرض به اولین بلوک در فایل که دارای برچسب آغازین است انجام می‌پذیرد. این نوع بلوک با گزینه \fB\-\-loop\-switch\fP ناسازگار است، زیرا نیازمند گذارهای بین‌بلوکی است که بدون \fBgoto\fP یا فراخوانی‌های تابع پشتیبانی نمی‌شوند. .TP .B \fB/*!conditions:re2c[:[:...]] ... */\fP, \fB/*!types:re2c... */\fP or \fB%{conditions[:[:...]] ... %}\fP, \fB%{types... %}\fP بلوکی که شمارش شرایط (condition enumeration) را تولید می‌کند (نیازمند گزینه \fB\-\-conditions\fP است). یک فهرست اختیاری از نام‌های بلوک مشخص می‌کند که هنگام محاسبه مجموعه شرایط، کدام بلوک‌ها باید لحاظ شوند (اگر فهرست خالی باشد، تمام بلوک‌ها لحاظ می‌شوند). به طور پیش‌فرض، کد تولیدشده یک شمارش \fBYYCONDTYPE\fP است\&. این بخش می‌تواند با پیکربندی‌های اختیاری \fBformat\fP و \fBseparator\fP سفارشی‌سازی شود. پیکربندی \fBformat\fP یک رشته الگو را مشخص می‌کند که در آن \fB@@{cond}\fP (یا به اختصار \fB@@\fP) با نام هر شرط، و \fB@@{num}\fP با نمایه عددی آن شرط جایگزین می‌شود. پیکربندی \fBseparator\fP قطعه کدی را مشخص می‌کند که برای متصل کردن قطعات \fBformat\fP تولیدشده برای شرایط مختلف به کار می‌رود. .TP .B \fB/*!include:re2c */\fP or \fB%{include %}\fP این بلوک به فرد اجازه می‌دهد \fB\fP را درج کند، که باید یک مسیر فایل درون نقل‌قول دوگانه باشد. محتویات فایل به صورت عین‌به‌عین به جای این بلوک جایگزین می‌شود، درست همان‌گونه که \fB#include\fP در C/C++ عمل می‌کند. این بلوک می‌تواند به همراه گزینه \fB\-\-depfile\fP برای تولید وابستگی‌های سیستم ساخت به فایل‌های درج‌شده استفاده شود. .TP .B \fB/*!header:re2c:on*/\fP or \fB%{header:on %}\fP این بلوک نقطه آغاز فایل سرآیند (header) را علامت‌گذاری می‌کند. همه‌چیز پس از آن تا بلوک \fBheader:off\fP بعدی توسط re2swift پردازش شده و در فایل سرآیند مشخص‌شده با گزینه \fB\-t \-\-type\-header\fP نوشته می‌شود. .TP .B \fB/*!header:re2c:off*/\fP or \fB%{header:off %}\fP این بلوک پایان فایل سرآیندی که با بلوک \fBheader:on*/\fP آغاز شده بود را علامت‌گذاری می‌کند. .TP .B \fB/*!ignore:re2c ... */\fP or \fB%{ignore ... %}\fP بلوکی که محتویات آن نادیده گرفته شده و از فایل خروجی حذف می‌شود. .UNINDENT.SS "پیکربندی‌ها (Configurations)" .sp در اینجا فهرست کاملی از پیکربندی‌های پشتیبانی‌شده توسط re2swift آمده است: .INDENT 0.0 .TP .B \fBre2c:api\fP, \fBre2c:input\fP همانند گزینهٔ \fB\-\-api\fP است. .TP .B \fBre2c:api:sigil\fP نشانه (\(dqsigil\(dq) مورد استفاده برای جای‌نگهدارهای آرگومان در ساختارهای اولیهٔ API را مشخص می‌کند. مقدار پیش‌فرض \fB@@\fP\& است. یک جای‌نگهدار با sigil شروع شده و به دنبال آن نام آرگومان درون دو آکولاد قرار می‌گیرد. برای مثال، اگر sigil روی \fB$\fP تنظیم شود، جای‌نگهدارها به شکل \fB${name}\fP\& خواهند بود. APIهای تک‌آرگومانی می‌توانند از نمادگذاری مختصر بدون نام درون آکولادها استفاده کنند. این گزینه می‌تواند با گزینه‌های مختص به هر یک از ساختارهای اولیهٔ API بازنویسی شود، مانند \fBre2c:YYFILL@len\fP برای \fBYYFILL\fP\&. .TP .B \fBre2c:api:style\fP سبک API را تعیین می‌کند. مقادیر ممکن عبارتند از \fBfunctions\fP (پیش‌فرض برای C) و \fBfree\-form\fP (پیش‌فرض برای Go و Rust). در سبک \fBfunctions\fP ساختارهای اولیهٔ API همراه با فهرست آرگومان‌ها درون پرانتز به دنبال نام ساختار اولیه تولید می‌شوند. آرگومان‌ها تنها برای پارامترهای خودکار تولیدشده فراهم می‌شوند (مانند تعداد نویسه‌های ارسالی به \fBYYFILL\fP)، و نه برای زمینهٔ کلی تحلیل‌گر لغوی، از این رو ساختارهای اولیه بیشتر شبیه ماکروها در C/C++ یا بستارها در Go و Rust عمل می‌کنند. در سبک free\-form ساختارهای اولیهٔ API شکل ثابتی ندارند: آن‌ها باید به صورت رشته‌هایی شامل قطعه‌کدهای آزاد با متغیرهای جایگزین‌شده به فرم \fB@@{var}\fP یا \fB@@\fP تعریف شوند (که متناظر با آرگومان‌ها در سبک تابع‌گونه هستند). این پیکربندی ممکن است برای هر ساختار اولیهٔ API به صورت مجزا بازنویسی شود؛ برای نمونه پیکربندی \fBre2c:YYFILL:naked\fP را برای \fBYYFILL\fP ببینید. .TP .B \fBre2c:bit\-vectors\fP, \fBre2c:flags:bit\-vectors\fP, \fBre2c:flags:b\fP همانند گزینهٔ \fB\-\-bit\-vectors\fP است، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:captures\fP, \fBre2c:leftmost\-captures\fP همانند گزینهٔ \fB\-\-leftmost\-captures\fP است، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:captvars\fP, \fBre2c:leftmost\-captvars\fP همانند گزینهٔ \fB\-\-leftmost\-captvars\fP است، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:case\-insensitive\fP, \fBre2c:flags:case\-insensitive\fP همانند گزینهٔ \fB\-\-case\-insensitive\fP است، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:case\-inverted\fP, \fBre2c:flags:case\-inverted\fP همانند گزینهٔ \fB\-\-case\-inverted\fP است، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:case\-ranges\fP, \fBre2c:flags:case\-ranges\fP همانند گزینهٔ \fB\-\-case\-ranges\fP است، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:computed\-gotos\fP, \fBre2c:flags:computed\-gotos\fP, \fBre2c:flags:g\fP همانند گزینهٔ \fB\-\-computed\-gotos\fP است، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:computed\-gotos:relative\fP, \fBre2c:cgoto:relative\fP همانند گزینهٔ \fB\-\-computed\-gotos\-relative\fP است، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:computed\-gotos:threshold\fP, \fBre2c:cgoto:threshold\fP در صورت استفاده از \fBgoto\fP محاسباتی، این پیکربندی آستانهٔ پیچیدگی‌ای را مشخص می‌کند که باعث تولید جدول‌های پرش به‌جای دستورهای تودرتوی \fBif\fP و نگاشت‌های بیتی می‌شود. مقدار پیش‌فرض \fB9\fP\& است. .TP .B \fBre2c:cond:abort\fP اگر روی یک مقدار عددی صحیح مثبت تنظیم شود، حالت پیش‌فرض در هدایت‌گر وضعیتِ تولیدشده اجرای برنامه را متوقف می‌کند. .TP .B \fBre2c:cond:goto\fP قطعه‌کدی را مشخص می‌کند که برای قواعد میان‌بر خودکار تولیدشدهٔ \fB:=>\fP در شرط‌ها استفاده می‌شود. پیش‌فرض \fBgoto @@;\fP\& است. جای‌نگهدار \fB@@\fP با نام شرط جایگزین می‌شود (پیکربندی‌های \fBre2c:api:sigil\fP و \fBre2c:cond:goto@cond\fP را ببینید). .TP .B \fBre2c:cond:goto@cond\fP نشانهٔ مورد استفاده برای جایگزینی آرگومان در تعریف \fBre2c:cond:goto\fP را مشخص می‌کند. مقدار پیش‌فرض \fB@@\fP\& است. پیکربندی عمومی‌تر \fBre2c:api:sigil\fP را بازنویسی می‌کند. .TP .B \fBre2c:cond:divider\fP جداکنندهٔ بلوک‌های شرط را تعریف می‌کند. مقدار پیش‌فرض \fB/* *********************************** */\fP\& است. جای‌نگهدارها با نام شرط جایگزین می‌شوند (پیکربندی‌های \fBre2c:api;sigil\fP و \fBre2c:cond:divider@cond\fP را ببینید). .TP .B \fBre2c:cond:divider@cond\fP نشانهٔ مورد استفاده برای جایگزینی آرگومان در تعریف \fBre2c:cond:divider\fP را مشخص می‌کند. مقدار پیش‌فرض \fB@@\fP\& است. پیکربندی عمومی‌تر \fBre2c:api:sigil\fP را بازنویسی می‌کند. .TP .B \fBre2c:cond:prefix\fP, \fBre2c:condprefix\fP پیشوند مورد استفاده برای برچسب‌های شرط را مشخص می‌کند. پیش‌فرض \fByyc_\fP\& است. .TP .B \fBre2c:cond:enumprefix\fP, \fBre2c:condenumprefix\fP پیشوند مورد استفاده برای شناسه‌های شرط را مشخص می‌کند. پیش‌فرض \fByyc\fP\& است. .TP .B \fBre2c:debug\-output\fP, \fBre2c:flags:debug\-output\fP, \fBre2c:flags:d\fP همانند گزینهٔ \fB\-\-debug\-output\fP است، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:empty\-class\fP, \fBre2c:flags:empty\-class\fP همانند گزینهٔ \fB\-\-empty\-class\fP است، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:encoding:ebcdic\fP, \fBre2c:flags:ecb\fP, \fBre2c:flags:e\fP همانند گزینهٔ \fB\-\-ebcdic\fP است، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:encoding:ucs2\fP, \fBre2c:flags:wide\-chars\fP, \fBre2c:flags:w\fP همانند گزینهٔ \fB\-\-ucs2\fP است، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:encoding:utf8\fP, \fBre2c:flags:utf\-8\fP, \fBre2c:flags:8\fP همانند گزینهٔ \fB\-\-utf8\fP است، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:encoding:utf16\fP, \fBre2c:flags:utf\-16\fP, \fBre2c:flags:x\fP همانند گزینهٔ \fB\-\-utf16\fP است، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:encoding:utf32\fP, \fBre2c:flags:unicode\fP, \fBre2c:flags:u\fP همانند گزینهٔ \fB\-\-utf32\fP است، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:encoding\-policy\fP, \fBre2c:flags:encoding\-policy\fP همانند گزینهٔ \fB\-\-encoding\-policy\fP است، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:eof\fP نماد نگهبان مورد استفاده با قاعدهٔ پایان ورودی \fB$\fP\& را مشخص می‌کند. مقدار پیش‌فرض \fB\-1\fP است (قاعدهٔ \fB$\fP استفاده نمی‌شود). مقادیر ممکن دیگر شامل تمامی واحدهای کد معتبر هستند. تنها اعداد ده‌دهی شناسایی می‌شوند. .TP .B \fBre2c:header\fP, \fBre2c:flags:type\-header\fP, \fBre2c:flags:t\fP نام فایل سرآیند تولیدشده را به صورت نسبی نسبت به دایرکتوری فایل خروجی مشخص می‌کند. همانند گزینهٔ \fB\-\-header\fP است با این تفاوت که مسیر فایل نسبی است. .TP .B \fBre2c:indent:string\fP رشتهٔ مورد استفاده برای دندانه‌گذاری را مشخص می‌کند. پیش‌فرض یک نویسهٔ تب تک \fB\(dq\et\(dq\fP\& است. رشتهٔ دندانه‌گذاری تنها باید شامل نویسه‌های فاصلهٔ خالی باشد. برای غیرفعال کردن کامل دندانه‌گذاری، این پیکربندی را روی یک رشتهٔ خالی تنظیم کنید. .TP .B \fBre2c:indent:top\fP حداقل مقدار دندانه‌گذاری برای استفاده را مشخص می‌کند. مقدار پیش‌فرض صفر است. این مقدار باید یک عدد صحیح غیرمنفی باشد. .TP .B \fBre2c:invert\-captures\fP همانند گزینهٔ \fB\-\-invert\-captures\fP است، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:label:prefix\fP, \fBre2c:labelprefix\fP پیشوند مورد استفاده برای برچسب‌های وضعیت DFA را مشخص می‌کند. پیش‌فرض \fByy\fP\& است. .TP .B \fBre2c:label:start\fP, \fBre2c:startlabel\fP تولید برچسب شروع بلوک را کنترل می‌کند. مقدار پیش‌فرض صفر است، به این معنی که برچسب شروع تنها در صورت استفاده تولید می‌شود. یک مقدار عددی صحیح بزرگ‌تر از صفر، حتی اگر برچسب شروع توسط تحلیل‌گر لغوی استفاده نشود، تولید آن را اجباری می‌کند. مقدار رشته‌ای نیز تولید برچسب شروع را اجباری کرده و نام برچسب را روی رشتهٔ مشخص‌شده تنظیم می‌کند. این پیکربندی تنها روی بلوک فعلی اعمال می‌شود (برای بلوک بعدی به مقدار پیش‌فرض بازنشانی می‌شود). .TP .B \fBre2c:label:yyFillLabel\fP پیشوند برچسب‌های \fBYYFILL\fP مورد استفاده همراه با \fBre2c:eof\fP و در حالت وضعیت قابل‌ذخیره را مشخص می‌کند. .TP .B \fBre2c:label:yyloop\fP نام برچسب نشان‌دهندهٔ شروع حلقهٔ تحلیل‌گر لغوی با گزینهٔ \fB\-\-loop\-switch\fP را مشخص می‌کند. پیش‌فرض \fByyloop\fP\& است. .TP .B \fBre2c:label:yyNext\fP نام برچسب اختیاری را مشخص می‌کند که بعد از سوییچ \fBYYGETSTATE\fP در حالت وضعیت قابل‌ذخیره می‌آید (با \fBre2c:state:nextlabel\fP فعال می‌شود). پیش‌فرض \fByyNext\fP\& است. .TP .B \fBre2c:lookahead\fP, \fBre2c:flags:lookahead\fP منسوخ شده است (گزینهٔ منسوخ‌شدهٔ \fB\-\-no\-lookahead\fP را ببینید). .TP .B \fBre2c:monadic\fP اگر روی غیرصفر تنظیم شود، تحلیل‌گر لغوی تولیدشده از نشانه‌گذاری مونادیک استفاده خواهد کرد (این پیکربندی مختص به Haskell است). .TP .B \fBre2c:nested\-ifs\fP, \fBre2c:flags:nested\-ifs\fP, \fBre2c:flags:s\fP همانند گزینهٔ \fB\-\-nested\-ifs\fP است، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:posix\-captures\fP, \fBre2c:flags:posix\-captures\fP, \fBre2c:flags:P\fP همانند گزینهٔ \fB\-\-posix\-captures\fP است، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:posix\-captvars\fP همانند گزینهٔ \fB\-\-posix\-captvars\fP است، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:tags\fP, \fBre2c:flags:tags\fP, \fBre2c:flags:T\fP همانند گزینهٔ \fB\-\-tags\fP است، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:tags:expression\fP عبارت مورد استفاده برای متغیرهای برچسب را مشخص می‌کند. به طور پیش‌فرض re2swift عبارت‌هایی به فرم \fByyt\fP\& تولید می‌کند. این حالت ممکن است ناخوشایند باشد، برای مثال اگر متغیرهای برچسب به عنوان فیلدهایی در یک struct تعریف شده باشند. تمامی رخدادهای \fB@@{tag}\fP یا \fB@@\fP با نام واقعی برچسب جایگزین می‌شوند. برای مثال، \fBre2c:tags:expression = \(dqs.@@\(dq;\fP منجر به تولید عبارت‌هایی به فرم \fBs.yyt\fP در کد تولیدشده می‌شود. همچنین پیکربندی \fBre2c:api:sigil\fP را ببینید..TP .B \fBre2c:tags:negative\fP عبارت ثابتی را مشخص می‌کند که برای مقدار منفی تگ استفاده می‌شود (معمولاً در صورتی که تگ‌ها آفست‌های عدد صحیح در رشته ورودی باشند، مقدار آن \fB\-1\fP است یا اگر اشاره‌گر باشند، اشاره‌گر تهی خواهد بود). .TP .B \fBre2c:tags:prefix\fP پیشوند نام متغیرهای تگ را مشخص می‌کند. مقدار پیش‌فرض \fByyt\fP\& است. .TP .B \fBre2c:sentinel\fP نماد دیده‌بان (sentinel) مورد استفاده برای بررسی‌های پایان ورودی را مشخص می‌کند (زمانی که بررسی‌های محدوده با \fBre2c:yyfill:enable = 0;\fP غیرفعال شده باشند و \fBre2c:eof\fP تنظیم نشده باشد). این پیکربندی بر تولید کد تأثیری ندارد: هدف آن اطمینان از عدم وجود نماد دیده‌بان در میان یک قاعده، و تضمین اینکه تحلیل‌گر لغوی فراتر از انتهای بافر را نخواهد خواند است. مقدار پیش‌فرض \fI\-1\(ga\fP است (در این حالت re2swift فرض می‌کند که دیده‌بان صفر است، که رایج‌ترین حالت می‌باشد). فقط اعداد ده‌دهی شناسایی می‌شوند. .TP .B \fBre2c:state:abort\fP اگر روی یک مقدار عدد صحیح مثبت تنظیم شود، شاخهٔ پیش‌فرض (default case) در توزیع وضعیت تولیدشده، اجرای برنامه را لغو (abort) می‌کند و یک شاخهٔ صریح \fB\-1\fP شامل انتقال به ابتدای بلوک خواهد بود. .TP .B \fBre2c:state:nextlabel\fP کنترل می‌کند که آیا بعد از عبارت switch مربوط به \fBYYGETSTATE\fP یک برچسب \fByyNext\fP قرار گیرد یا خیر (مقدار پیش‌فرض صفر است که با عدم وجود برچسب مطابقت دارد). به عنوان جایگزین می‌توان از \fBre2c:label:start\fP برای تولید یک برچسب شروع مشخص، یا از یک بلوک صریح \fBgetstate\fP برای تولید ساختار switch مربوط به \fBYYGETSTATE\fP به صورت جداگانه از بلوک تحلیل‌گر استفاده کرد. .TP .B \fBre2c:unsafe\fP, \fBre2c:flags:unsafe\fP مشابه گزینهٔ \fB\-\-no\-unsafe\fP است، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. اگر روی صفر تنظیم شود، از تولید پوشش‌های (wrappers) \fBunsafe\fP در اطراف \fBYYPEEK\fP\& جلوگیری می‌کند. پیش‌فرض مقداری غیرصفر است (پوشش‌ها تولید می‌شوند). این پیکربندی مختص Rust است. .TP .B \fBre2c:YYBACKUP\fP, \fBre2c:define:YYBACKUP\fP عنصر پایهٔ عمومی API به نام \fBYYBACKUP\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYBACKUPCTX\fP, \fBre2c:define:YYBACKUPCTX\fP عنصر پایهٔ عمومی API به نام \fBYYBACKUPCTX\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYCONDTYPE\fP, \fBre2c:define:YYCONDTYPE\fP عنصر پایهٔ API به نام \fBYYCONDTYPE\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYCTYPE\fP, \fBre2c:define:YYCTYPE\fP عنصر پایهٔ API به نام \fBYYCTYPE\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYCTXMARKER\fP, \fBre2c:define:YYCTXMARKER\fP عنصر پایهٔ API به نام \fBYYCTXMARKER\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYCURSOR\fP, \fBre2c:define:YYCURSOR\fP عنصر پایهٔ API به نام \fBYYCURSOR\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYDEBUG\fP, \fBre2c:define:YYDEBUG\fP عنصر پایهٔ API به نام \fBYYDEBUG\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYFILL\fP, \fBre2c:define:YYFILL\fP عنصر پایهٔ API به نام \fBYYFILL\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYFILL@len\fP, \fBre2c:define:YYFILL@len\fP علامت ویژه (sigil) مورد استفاده برای جایگزینی آرگومان در تعریف \fBYYFILL\fP را مشخص می‌کند. مقدار پیش‌فرض \fB@@\fP\& است. پیکربندی عمومی‌تر \fBre2c:api:sigil\fP را لغو می‌کند. .TP .B \fBre2c:YYFILL:naked\fP, \fBre2c:define:YYFILL:naked\fP پیکربندی عمومی‌تر \fBre2c:api:style\fP را برای \fBYYFILL\fP\& لغو می‌کند. مقدار صفر متناظر با سبک آزاد API (free\-form) است. .TP .B \fBre2c:YYFN\fP عنصر پایهٔ API به نام \fBYYFN\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYINPUT\fP عنصر پایهٔ API به نام \fBYYINPUT\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYGETCOND\fP, \fBre2c:define:YYGETCONDITION\fP عنصر پایهٔ API به نام \fBYYGETCOND\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYGETCOND:naked\fP, \fBre2c:define:YYGETCONDITION:naked\fP پیکربندی عمومی‌تر \fBre2c:api:style\fP را برای \fBYYGETCOND\fP\& لغو می‌کند. مقدار صفر متناظر با سبک آزاد API است. .TP .B \fBre2c:YYGETSTATE\fP, \fBre2c:define:YYGETSTATE\fP عنصر پایهٔ API به نام \fBYYGETSTATE\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYGETSTATE:naked\fP, \fBre2c:define:YYGETSTATE:naked\fP پیکربندی عمومی‌تر \fBre2c:api:style\fP را برای \fBYYGETSTATE\fP\& لغو می‌کند. مقدار صفر متناظر با سبک آزاد API است. .TP .B \fBre2c:YYGETACCEPT\fP, \fBre2c:define:YYGETACCEPT\fP عنصر پایهٔ API به نام \fBYYGETACCEPT\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYLESSTHAN\fP, \fBre2c:define:YYLESSTHAN\fP عنصر پایهٔ عمومی API به نام \fBYYLESSTHAN\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYLIMIT\fP, \fBre2c:define:YYLIMIT\fP عنصر پایهٔ API به نام \fBYYLIMIT\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYMARKER\fP, \fBre2c:define:YYMARKER\fP عنصر پایهٔ API به نام \fBYYMARKER\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYMTAGN\fP, \fBre2c:define:YYMTAGN\fP عنصر پایهٔ عمومی API به نام \fBYYMTAGN\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYMTAGP\fP, \fBre2c:define:YYMTAGP\fP عنصر پایهٔ عمومی API به نام \fBYYMTAGP\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYPEEK\fP, \fBre2c:define:YYPEEK\fP عنصر پایهٔ عمومی API به نام \fBYYPEEK\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYRESTORE\fP, \fBre2c:define:YYRESTORE\fP عنصر پایهٔ عمومی API به نام \fBYYRESTORE\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYRESTORECTX\fP, \fBre2c:define:YYRESTORECTX\fP عنصر پایهٔ عمومی API به نام \fBYYRESTORECTX\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYRESTORETAG\fP, \fBre2c:define:YYRESTORETAG\fP عنصر پایهٔ عمومی API به نام \fBYYRESTORETAG\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYSETCOND\fP, \fBre2c:define:YYSETCONDITION\fP عنصر پایهٔ API به نام \fBYYSETCOND\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYSETCOND@cond\fP, \fBre2c:define:YYSETCONDITION@cond\fP علامت ویژه (sigil) مورد استفاده برای جایگزینی آرگومان در تعریف \fBYYSETCOND\fP را مشخص می‌کند. مقدار پیش‌فرض \fB@@\fP\& است. پیکربندی عمومی‌تر \fBre2c:api:sigil\fP را لغو می‌کند. .TP .B \fBre2c:YYSETCOND:naked\fP, \fBre2c:define:YYSETCONDITION:naked\fP پیکربندی عمومی‌تر \fBre2c:api:style\fP را برای \fBYYSETCOND\fP\& لغو می‌کند. مقدار صفر متناظر با سبک آزاد API است. .TP .B \fBre2c:YYSETSTATE\fP, \fBre2c:define:YYSETSTATE\fP عنصر پایهٔ API به نام \fBYYSETSTATE\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYSETSTATE@state\fP, \fBre2c:define:YYSETSTATE@state\fP علامت ویژه (sigil) مورد استفاده برای جایگزینی آرگومان در تعریف \fBYYSETSTATE\fP را مشخص می‌کند. مقدار پیش‌فرض \fB@@\fP\& است. پیکربندی عمومی‌تر \fBre2c:api:sigil\fP را لغو می‌کند. .TP .B \fBre2c:YYSETSTATE:naked\fP, \fBre2c:define:YYSETSTATE:naked\fP پیکربندی عمومی‌تر \fBre2c:api:style\fP را برای \fBYYSETSTATE\fP\& لغو می‌کند. مقدار صفر متناظر با سبک آزاد API است. .TP .B \fBre2c:YYSETACCEPT\fP, \fBre2c:define:YYSETACCEPT\fP عنصر پایهٔ API به نام \fBYYSETACCEPT\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYSKIP\fP, \fBre2c:define:YYSKIP\fP عنصر پایهٔ عمومی API به نام \fBYYSKIP\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYSHIFT\fP, \fBre2c:define:YYSHIFT\fP عنصر پایهٔ عمومی API به نام \fBYYSHIFT\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYCOPYMTAG\fP, \fBre2c:define:YYCOPYMTAG\fP عنصر پایهٔ عمومی API به نام \fBYYCOPYMTAG\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYCOPYSTAG\fP, \fBre2c:define:YYCOPYSTAG\fP عنصر پایهٔ عمومی API به نام \fBYYCOPYSTAG\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYSHIFTMTAG\fP, \fBre2c:define:YYSHIFTMTAG\fP عنصر پایهٔ عمومی API به نام \fBYYSHIFTMTAG\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYSHIFTSTAG\fP, \fBre2c:define:YYSHIFTSTAG\fP عنصر پایهٔ عمومی API به نام \fBYYSHIFTSTAG\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYSTAGN\fP, \fBre2c:define:YYSTAGN\fP عنصر پایهٔ عمومی API به نام \fBYYSTAGN\fP\& را تعریف می‌کند. .TP .B \fBre2c:YYSTAGP\fP, \fBre2c:define:YYSTAGP\fP عنصر پایهٔ عمومی API به نام \fBYYSTAGP\fP\& را تعریف می‌کند. .TP .B \fBre2c:yyaccept\fP, \fBre2c:variable:yyaccept\fP عنصر پایهٔ API به نام \fByyaccept\fP\& را تعریف می‌کند. .TP .B \fBre2c:yybm\fP, \fBre2c:variable:yybm\fP عنصر پایهٔ API به نام \fByybm\fP\& را تعریف می‌کند. .TP .B \fBre2c:yybm:hex\fP, \fBre2c:variable:yybm:hex\fP اگر روی مقداری غیرصفر تنظیم شود، نقشه‌های بیتی (bitmaps) برای گزینهٔ \fB\-\-bit\-vectors\fP در قالب شانزده‌شانزدهی (hexadecimal) تولید می‌شوند. پیش‌فرض صفر است (نقشه‌های بیتی در قالب ده‌دهی هستند). .TP .B \fBre2c:yych\fP, \fBre2c:variable:yych\fP عنصر پایهٔ API به نام \fByych\fP\& را تعریف می‌کند. .TP .B \fBre2c:yych:emit\fP, \fBre2c:variable:yych:emit\fP اگر روی صفر تنظیم شود، تعریف \fByych\fP تولید نمی‌شود. مقدار پیش‌فرض غیرصفر است. .TP .B \fBre2c:yych:conversion\fP, \fBre2c:variable:yych:conversion\fP اگر روی مقداری غیرصفر تنظیم شود، re2swift به طور خودکار هر بار که \fByych\fP خوانده می‌شود، یک تبدیل به \fBYYCTYPE\fP تولید می‌کند. پیش‌فرض صفر است (بدون تبدیل). .TP .B \fBre2c:yych:literals\fP, \fBre2c:variable:yych:literals\fP قالب لیترال‌هایی که \fByych\fP با آن‌ها مطابقت داده می‌شود را مشخص می‌کند. مقادیر ممکن عبارتند از: \fBchar\fP (لیترال‌های نویسه‌ای درون گیومه تکی؛ موارد غیرقابل چاپ از توالی‌های گریز که با بک‌اسلش شروع می‌شوند استفاده می‌کنند)، \fBhex\fP (اعداد صحیح شانزده‌شانزدهی) و \fBchar_or_hex\fP (ترکیبی از هر دو؛ لیترال‌های نویسه‌ای برای نویسه‌های قابل چاپ و اعداد صحیح شانزده‌شانزدهی برای بقیه). .TP .B \fBre2c:yyctable\fP, \fBre2c:variable:yyctable\fP عنصر پایهٔ API به نام \fByyctable\fP\& را تعریف می‌کند..TP .B \fBre2c:yynmatch\fP, \fBre2c:variable:yynmatch\fP عنصر پایه API با نام \fByynmatch\fP را تعریف می‌کند. .TP .B \fBre2c:yypmatch\fP, \fBre2c:variable:yypmatch\fP عنصر پایه API با نام \fByypmatch\fP را تعریف می‌کند. .TP .B \fBre2c:yytarget\fP, \fBre2c:variable:yytarget\fP عنصر پایه API با نام \fByytarget\fP را تعریف می‌کند. .TP .B \fBre2c:yystable\fP, \fBre2c:variable:yystable\fP منسوخ شده است. .TP .B \fBre2c:yystate\fP, \fBre2c:variable:yystate\fP عنصر پایه API با نام \fByystate\fP را تعریف می‌کند. .TP .B \fBre2c:yyfill\fP, \fBre2c:variable:yyfill\fP عنصر پایه API با نام \fByyfill\fP را تعریف می‌کند. .TP .B \fBre2c:yyfill:check\fP اگر روی صفر تنظیم شود، از تولید بررسی پیش از \fBYYFILL\fP برای تعداد نویسه‌های ورودی (تعریف \fBYYLESSTHAN\fP در API عمومی و مقایسه مبتنی بر \fBYYLIMIT\fP در API اشاره‌گر C) جلوگیری می‌کند. مقدار پیش‌فرض غیرصفر است (بررسی را تولید می‌کند). .TP .B \fBre2c:yyfill:enable\fP اگر روی صفر تنظیم شود، تولید \fBYYFILL\fP را (همراه با بررسی آن) لغو می‌کند. این حالت باید زمانی استفاده شود که کل ورودی در یک بخش یکپارچه از حافظه جا می‌شود (نیازی به بافر کردن نیست) و بررسی‌های پایان ورودی به بررسی‌های \fBYYFILL\fP متکی نیستند (برای نمونه، اگر از نویسه نشانگر پایان / sentinel استفاده شود). برای اطمینان از اینکه تحلیل‌گر لغوی تولیدشده نمی‌تواند فراتر از پایان ورودی را بخواند، از هشدارها (گزینه \fB\-W\fP) و پیکربندی \fBre2c:sentinel\fP استفاده کنید. مقدار پیش‌فرض غیرصفر است (\fBYYFILL\fP فعال است). .TP .B \fBre2c:yyfill:parameter\fP اگر روی صفر تنظیم شود، از تولید پارامتر ارسالی به \fBYYFILL\fP جلوگیری می‌کند. این پارامتر حداقل تعداد نویسه‌هایی است که باید فراهم شوند. پیش‌فرض غیرصفر است (پارامتر تولید می‌شود). این پیکربندی را می‌توان با \fBre2c:YYFILL:naked\fP یا \fBre2c:api:style\fP بازنویسی کرد. .TP .B \fBre2c:yyfn:sep\fP جداکننده مورد استفاده در عناصر \fBYYFN\fP را مشخص می‌کند (پیش‌فرض نقطه\-ویرگول است). .TP .B \fBre2c:yyfn:throw\fP استثناهای پرتاب‌شده توسط تابع \fBYYFN\fP را مشخص می‌کند (پیش‌فرض خالی است، که به معنای پرتاب نشدن هیچ استثنایی است). .UNINDENT .SS "عبارت‌های منظم (Regular expressions)" .sp ابزار re2swift از نحو زیر برای عبارت‌های منظم استفاده می‌کند: .INDENT 0.0 .TP .B \fB\(dqfoo\(dq\fP ثابت رشته‌ای حساس به بزرگی و کوچکی حروف. .TP .B \fB\(aqfoo\(aq\fP ثابت رشته‌ای غیرحساس به بزرگی و کوچکی حروف. .TP .B \fB[a\-xyz]\fP, \fB[^a\-xyz]\fP کلاس نویسه (احتمالاً نفی‌شده). .TP .B \fB\&.\fP هر نویسه‌ای به جز خط جدید. .TP .B \fBR \e S\fP تفاضل کلاس‌های نویسه \fBR\fP و \fBS\fP\&. .TP .B \fBR*\fP صفر یا چند بار تکرار \fBR\fP\&. .TP .B \fBR+\fP یک یا چند بار تکرار \fBR\fP\&. .TP .B \fBR?\fP \fBR\fP اختیاری. .TP .B \fBR{n}\fP تکرار \fBR\fP دقیقاً \fBn\fP بار. .TP .B \fBR{n,}\fP تکرار \fBR\fP حداقل \fBn\fP بار. .TP .B \fBR{n,m}\fP تکرار \fBR\fP از \fBn\fP تا \fBm\fP بار. .TP .B \fB(R)\fP تنها همان \fBR\fP؛ پرانتزها برای تغییر اولویت استفاده می‌شوند. در صورت فعال بودن استخراج تطابق فرعی، \fB(R)\fP بسته به گزینه \fB\-\-invert\-captures\fP یک گروه ضبط‌کننده یا غیرضبط‌کننده است. .TP .B \fB(!R)\fP در صورت فعال بودن استخراج تطابق فرعی، \fB(!R)\fP بسته به گزینه \fB\-\-invert\-captures\fP یک گروه غیرضبط‌کننده یا ضبط‌کننده است. .TP .B \fBR S\fP الحاق: \fBR\fP و به دنبال آن \fBS\fP\&. .TP .B \fBR | S\fP جایگزین: \fBR یا S\fP\&. .TP .B \fBR / S\fP پیش‌نگری: \fBR\fP و به دنبال آن \fBS\fP، اما \fBS\fP مصرف نمی‌شود. .TP .B \fBname\fP عبارت منظم تعریف‌شده با نام \fBname\fP (یا رشته دقیق \fB\(dqname\(dq\fP در حالت سازگاری با Flex). .TP .B \fB{name}\fP عبارت منظم تعریف‌شده با نام \fBname\fP در حالت سازگاری با Flex. .TP .B \fB@stag\fP یک \fIs\-tag\fP: آخرین موقعیت ورودی که در آن \fB@stag\fP تطابق می‌یابد را در متغیری به نام \fBstag\fP ذخیره می‌کند. .TP .B \fB#mtag\fP یک \fIm\-tag\fP: تمامی موقعیت‌های ورودی که در آن‌ها \fB#mtag\fP تطابق می‌یابد را در متغیری به نام \fBmtag\fP ذخیره می‌کند. .TP .B \fB$\fP پایان ورودی. .UNINDENT .sp کلاس‌های نویسه و ثابت‌های رشته‌ای می‌توانند شامل توالی‌های گریز زیر باشند: \fB\ea\fP، \fB\eb\fP، \fB\ef\fP، \fB\en\fP، \fB\er\fP، \fB\et\fP، \fB\ev\fP، \fB\e\e\fP، گریزهای هشت‌هشتی \fB\eooo\fP و گریزهای شانزده‌شانزدهی \fB\exhh\fP، \fB\euhhhh\fP و \fB\eUhhhhhhhh\fP\&..SS "کنش‌ها (Actions)" .sp در اینجا فهرستی از کنش‌های از پیش تعریف‌شده که توسط re2swift پشتیبانی می‌شوند آمده است: .INDENT 0.0 .TP .B \fB!entry code\fP کنش ورودی (Entry action) یک بلوک از \fBcode\fP تعریف‌شده توسط کاربر را به وضعیت آغازین ماشین حالت متناهی کنونی مقید می‌کند. اگر از \fI\%start conditions\fP استفاده شود، کنش ورودی را می‌توان به‌صورت جداگانه برای هر شرط تنظیم کرد. این کنش ممکن است برای انجام مقداردهی اولیه، مانند ذخیره موقعیت آغازین یک لکسم (lexeme) استفاده شود. .TP .B \fB!pre_rule code\fP کنش پیش‌قاعده (Pre\-rule action) یک بلوک از \fBcode\fP تعریف‌شده توسط کاربر را به ابتدای کنش‌های معنایی تمام قواعد در بلوک کنونی (یا در صورت استفاده از \fI\%start conditions\fP، به شرط کنونی) اضافه می‌کند. این کنش می‌تواند برای فاکتورگیری بخش مشترک تمام کنش‌های معنایی (مانند ذخیره موقعیت پایانی یک لکسم) استفاده شود. .TP .B \fB!post_rule code\fP کنش پس‌قاعده (Post\-rule action) یک بلوک از \fBcode\fP تعریف‌شده توسط کاربر را به انتهای کنش‌های معنایی تمام قواعد در بلوک کنونی (یا در صورت استفاده از \fI\%start conditions\fP، به شرط کنونی) ضمیمه می‌کند. این کنش می‌تواند برای درج عبارت‌های تله (trap) که در برابر جریان کنترل ناخواسته محافظت می‌کنند، استفاده شود. .UNINDENT .SS "رهنمودها (Directives)" .sp در اینجا فهرست کاملی از رهنمودهای پشتیبانی‌شده توسط re2swift آمده است: .INDENT 0.0 .TP .B \fB!use:name ;\fP یک رهنمود درون‌بلوکیِ use که یک بلوک قواعد از پیش تعریف‌شده با \fBname\fP مشخص را در بلوک کنونی ادغام می‌کند. تعاریف نام‌گذاری‌شده، پیکربندی‌ها و قواعد بلوک مرجع به موارد فعلی اضافه می‌شوند. تداخلات میان قواعد و پیکربندی‌های هم‌پوشان به روش معمول حل می‌شوند: نخستین قاعده اولویت دارد، و آخرین پیکربندی بر موارد پیشین بازنویسی می‌شود. یک استثنا قواعد خاص \fB*\fP، \fB$\fP و \fB\fP هستند که برای آن‌ها تعریف محلی بلوک همواره اولویت دارد. یک رهنمود use را می‌توان در هر کجای یک بلوک قرار داد، و استفاده از چندین رهنمود use مجاز است. .TP .B \fB!include file ;\fP این رهنمود همانند بلوک \fBinclude\fP است: محتویات \fBfile\fP را عیناً به جای رهنمود درج می‌کند. .UNINDENT .SS "رابط برنامه (Program interface)" .sp کد تولیدشده به کمک \fIعناصر پایه (primitives)\fP که در مجموع به عنوان \fIAPI\fP شناخته می‌شوند، با برنامه بیرونی ارتباط برقرار می‌کند. اینکه کدام پایه‌ها باید برای یک برنامه خاص تعریف شوند به عوامل متعددی بستگی دارد، از جمله پیچیدگی عبارات باقاعده، نحوه نمایش ورودی، بافرینگ و استفاده از قابلیت‌های گوناگون. تمام پایه‌های ضروری باید توسط کاربر در قالب ماکروها، توابع، متغیرها یا هر شکل مناسب دیگری که کد تولیدشده را از نظر نحوی و معنایی صحیح سازد، تعریف شوند. re2swift تعاریف را بررسی نمی‌کند (و نمی‌تواند بررسی کند)، بنابراین اگر موردی جا افتاده باشد یا به نادرستی تعریف شده باشد، ممکن است برنامه تولیدشده با خطاهای زمان کامپایل یا زمان اجرا مواجه شود. این راهنما مثال‌هایی از تعاریف API در رایج‌ترین موارد ارائه می‌دهد. .sp ابزار re2swift دارای سه شیوه (flavor) از API است که مجموعه اصلی پایه‌های استفاده‌شده توسط یک برنامه را مشخص می‌کنند: .INDENT 0.0 .TP .B \fBSimple API\fP این حالت پیش‌فرض برای backend سوئیفت (Swift) است. این API از پایه‌های زیر تشکیل شده است: \fBYYINPUT\fP (که باید به‌صورت توالی از واحدهای کد، مانند یک رشته تعریف شود) و \fBYYCURSOR\fP، \fBYYMARKER\fP، \fBYYCTXMARKER\fP، \fBYYLIMIT\fP (که باید به‌صورت اندیس‌هایی در \fBYYINPUT\fP تعریف شوند). .nf .fi .sp .TP .B \fBRecord API\fP رابط Record API در مواردی مفید است که وضعیت تحلیل‌گر لغوی باید در یک شیء ذخیره شود. این حالت با گزینه \fB\-\-api record\fP یا پیکربندی \fBre2c:api = record\fP فعال می‌شود. این API شامل متغیر \fByyrecord\fP است (این نام را می‌توان با \fBre2c:YYRECORD\fP بازنویسی کرد) که باید به‌صورت یک ساختار (struct) یا کلاس (class) با فیلدهای \fByyinput\fP، \fByycursor\fP، \fByymarker\fP، \fByyctxmarker\fP و \fByylimit\fP تعریف شود (تنها فیلدهایی که توسط کد تولیدشده استفاده می‌شوند باید تعریف شوند، و نام‌های آن‌ها نیز قابل پیکربندی است). .nf .fi .sp .TP .B \fBGeneric API\fP این منعطف‌ترین API است. این حالت با گزینه \fB\-\-api generic\fP یا پیکربندی \fBre2c:api = generic\fP فعال می‌شود. این API شامل پایه‌های زیر برای عملیات عمومی است: \fBYYPEEK\fP، \fBYYSKIP\fP، \fBYYBACKUP\fP، \fBYYBACKUPCTX\fP، \fBYYSTAGP\fP، \fBYYSTAGN\fP، \fBYYMTAGP\fP، \fBYYMTAGN\fP، \fBYYRESTORE\fP، \fBYYRESTORECTX\fP، \fBYYRESTORETAG\fP، \fBYYSHIFT\fP، \fBYYSHIFTSTAG\fP، \fBYYSHIFTMTAG\fP، \fBYYLESSTHAN\fP، \fBYYEND\fP\&. برای مثال، اگر ورودی یک آرایه از بایت‌ها با پایان صفر به‌صورت \fBbuffer: [UInt8]\fP باشد، متغیرهای \fBcursor\fP، \fBlimit\fP، \fBmarker\fP و \fBctxmarker\fP از نوع \fBInt\fP نمایانگر موقعیت‌های ورودی باشند، و \fB\-1\fP نمایانگر موقعیت‌های نامعتبر باشد، یک Generic API می‌تواند به‌صورت زیر تعریف شود: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C /*!re2c re2c:YYPEEK = \(dqbuffer[cursor]\(dq; re2c:YYSKIP = \(dqcursor++\(dq; re2c:YYBACKUP = \(dqmarker = cursor\(dq; re2c:YYRESTORE = \(dqcursor = marker\(dq; re2c:YYBACKUPCTX = \(dqctxmarker = cursor\(dq; re2c:YYRESTORECTX = \(dqcursor = ctxmarker\(dq; re2c:YYRESTORETAG = \(dqcursor = ${tag}\(dq; re2c:YYLESSTHAN = \(dqlimit \- cursor < @@{len}\(dq; re2c:YYEND = \(dqlimit == cursor\(dq; re2c:YYSTAGP = \(dq@@{tag} = cursor\(dq; re2c:YYSTAGN = \(dq@@{tag} = \-1\(dq; re2c:YYSHIFT = \(dqcursor += @@{shift}\(dq; re2c:YYSHIFTSTAG = \(dq@@{tag} += @@{shift}\(dq; */ .ft P .fi .UNINDENT .UNINDENT .UNINDENT .sp در اینجا فهرست کاملی از پایه‌های API که ممکن است توسط کد تولیدشده جهت برقراری ارتباط با برنامه بیرونی استفاده شوند آمده است: .INDENT 0.0 .TP .B \fBYYCTYPE\fP نوع نویسه‌های ورودی (واحدهای کد). برای کدگذاری‌های ASCII، EBCDIC و UTF\-8 باید یک عدد صحیح بدون علامت ۱ بایتی باشد. برای UTF\-16 یا UCS\-2 باید عدد صحیح بدون علامت ۲ بایتی باشد. برای UTF\-32 باید عدد صحیح بدون علامت ۴ بایتی باشد. .TP .B \fBYYCURSOR\fP یک مقدار چپ (l\-value) که موقعیت کنونی ورودی را ذخیره می‌کند (یک اشاره‌گر یا آفست صحیح در \fBYYINPUT\fP). در ابتدا \fBYYCURSOR\fP باید به نخستین نویسه ورودی اشاره کند، و سپس توسط کد تولیدشده به جلو برده می‌شود. هنگامی که قاعده‌ای مطابقت یابد، موقعیت \fBYYCURSOR\fP نویسه پس از آخرین نویسه تطبیق‌یافته خواهد بود. .TP .B \fBYYLIMIT\fP یک مقدار راست (r\-value) که موقعیت پایان ورودی را ذخیره می‌کند (یک اشاره‌گر یا آفست صحیح در \fBYYINPUT\fP). در ابتدا \fBYYLIMIT\fP باید به موقعیت پس از آخرین نویسه ورودی موجود اشاره کند. این مقدار توسط کد تولیدشده تغییر داده نمی‌شود. تحلیل‌گر لغوی \fBYYCURSOR\fP را با \fBYYLIMIT\fP مقایسه می‌کند تا مشخص شود آیا نویسه‌های ورودی کافی باقی مانده‌اند یا خیر. .TP .B \fBYYMARKER\fP یک مقدار چپ (l\-value) که موقعیت آخرین قاعده تطبیق‌یافته را ذخیره می‌کند (یک اشاره‌گر یا آفست صحیح در \fBYYINPUT\fP). این مقدار برای بازیابی موقعیت \fBYYCURSOR\fP در صورتی که تطبیق طولانی‌تر با شکست مواجه شود و تحلیل‌گر لغوی نیاز به بازگشت به عقب (rollback) داشته باشد، استفاده می‌شود. مقداردهی اولیه نیاز نیست. .TP .B \fBYYCTXMARKER\fP یک مقدار چپ (l\-value) که موقعیت زمینه دنباله‌دار (trailing context) را ذخیره می‌کند (یک اشاره‌گر یا آفست صحیح در \fBYYINPUT\fP). به مقداردهی اولیه نیازی نیست. \fBYYCTXMARKER\fP تنها در صورتی نیاز است که از عملگر پیش‌نگری (lookahead) \fB/\fP استفاده شود. .TP .B \fBYYFILL\fP یک پایه Generic API با یک متغیر \fBlen\fP\&. پایه \fBYYFILL\fP باید دست‌کم \fBlen\fP نویسه ورودی بیشتر تأمین کند یا با شکست مواجه شود. اگر از \fBre2c:eof\fP استفاده شود، \fBlen\fP همیشه \fB1\fP است و \fBYYFILL\fP باید همواره به تابع فراخواننده بازگردد؛ مقدار بازگشتی صفر نشان‌دهنده موفقیت است. اگر از \fBre2c:eof\fP استفاده نشود، مقدار بازگشتی \fBYYFILL\fP نادیده گرفته می‌شود و نباید هنگام شکست بازگشتی داشته باشد. بیشینه مقدار \fBlen\fP برابر با \fBYYMAXFILL\fP است. .TP .B \fBYYFN\fP پایه‌ای که پیش‌نمونه (prototype) تابع را در مدل کد \fB\-\-recursive\-functions\fP تعریف می‌کند. مقدار آن باید آرایه‌ای از یک یا چند رشته باشد، که در آن هر رشته شامل دو یا سه مؤلفه است که توسط رشته مشخص‌شده در پیکربندی \fBre2c:fn:sep\fP (معمولاً یک نقطه‌ویرگول) از هم جدا شده‌اند. نخستین عنصر آرایه نام تابع و نوع بازگشتی را مشخص می‌کند (برای یک تابع void خالی است). عناصر بعدی آرگومان‌های تابع را تعریف می‌کنند: اول، عبارت مربوط به آرگومان مورد استفاده در بدنه تابع (معمولاً تنها یک نام)؛ دوم، نوع آرگومان؛ سوم، یک پارامتر صوری اختیاری (پیش‌فرض آن مؤلفه اول است \- معمولاً هر دو آرگومان و پارامتر شناسه یکسانی هستند). .TP .B \fBYYINPUT\fP یک مقدار راست (r\-value) که توالی نویسه‌های ورودی کنونی (رشته، بافر، و غیره) را ذخیره می‌کند. .TP .B \fBYYMAXFILL\fP یک ثابت صحیح برابر با بیشینه مقدار آرگومان ورودی به \fBYYFILL\fP\&. این مقدار را می‌توان با یک بلوک \fBmax\fP تولید کرد. .TP .B \fBYYLESSTHAN\fP یک پایه Generic API با یک متغیر \fBlen\fP\&. این پایه باید به‌صورت یک مقدار راست (r\-value) از نوع بولی تعریف شود که اگر و تنها اگر کمتر از \fBlen\fP نویسه ورودی باقی مانده باشد برابر با \fBtrue\fP است. .TP .B \fBYYEND\fP یک پایه Generic API بدون متغیر. این پایه باید به‌صورت یک مقدار راست (r\-value) از نوع بولی تعریف شود که اگر و تنها اگر به پایان \fIمنطقی\fP ورودی (بدون احتساب هرگونه پدینگ یا نمادهای نگهبان/sentinel) رسیده باشیم برابر با \fBtrue\fP است. \fBYYEND\fP برای پیاده‌سازی نماد \fB$\fP در عبارات باقاعده استفاده می‌شود. این پایه با \fBYYLESSTHAN\fP تفاوت دارد، که برای اطمینان از اینکه تحلیل‌گر لغوی فراتر از انتهای بافر را نخواند استفاده می‌شود. .UNINDENT.TP .B \fBYYPEEK\fP یک دستور اولیه (primitive) عمومی API بدون متغیر. باید به‌صورت یک r\-value از نوع \fBYYCTYPE\fP تعریف شود که برابر با نویسه در موقعیت فعلی ورودی است. .TP .B \fBYYSKIP\fP یک دستور اولیه عمومی API که باید موقعیت فعلی ورودی را به اندازهٔ یک واحد کد جلو ببرد. .TP .B \fBYYBACKUP\fP یک دستور اولیه عمومی API که باید موقعیت فعلی ورودی را ذخیره کند (تا بعداً با \fBYYRESTORE\fP بازیابی شود). .TP .B \fBYYRESTORE\fP یک دستور اولیه عمومی API که باید موقعیت فعلی ورودی را به مقدار ذخیره‌شده توسط \fBYYBACKUP\fP بازگرداند. .TP .B \fBYYBACKUPCTX\fP یک دستور اولیه عمومی API که باید موقعیت فعلی ورودی را به‌عنوان موقعیت بافت انتهایی (trailing context) ذخیره کند (تا بعداً با \fBYYRESTORECTX\fP بازیابی شود). .TP .B \fBYYRESTORECTX\fP یک دستور اولیه عمومی API که باید موقعیت بافت انتهایی ذخیره‌شده با \fBYYBACKUPCTX\fP را بازگرداند. .TP .B \fBYYRESTORETAG\fP یک دستور اولیه عمومی API با یک متغیر \fBtag\fP که باید موقعیت بافت انتهایی را به مقدار \fBtag\fP بازگرداند. .TP .B \fBYYSTAGP\fP یک دستور اولیه عمومی API با یک متغیر \fBtag\fP، که در آن \fBtag\fP می‌تواند یک اشاره‌گر یا آفست در \fBYYINPUT\fP باشد (برای جزئیات به بخش استخراج تطابق‌های فرعی مراجعه کنید). \fBYYSTAGP\fP باید \fBtag\fP را روی موقعیت فعلی ورودی تنظیم کند. .TP .B \fBYYSTAGN\fP یک دستور اولیه عمومی API با یک متغیر \fBtag\fP، که در آن \fBtag\fP می‌تواند یک اشاره‌گر یا آفست در \fBYYINPUT\fP باشد (برای جزئیات به بخش استخراج تطابق‌های فرعی مراجعه کنید). \fBYYSTAGN\fP باید \fBtag\fP را روی مقداری تنظیم کند که نشان‌دهندهٔ موقعیت ناموجود در ورودی است. .TP .B \fBYYMTAGP\fP یک دستور اولیه عمومی API با یک متغیر \fBtag\fP\&. \fBYYMTAGP\fP باید موقعیت فعلی را به تاریخچهٔ تطابق‌های فرعی \fBtag\fP الحاق کند (برای جزئیات به بخش استخراج تطابق‌های فرعی مراجعه کنید). .TP .B \fBYYMTAGN\fP یک دستور اولیه عمومی API با یک متغیر \fBtag\fP\&. \fBYYMTAGN\fP باید مقداری را که نشان‌دهندهٔ موقعیت ناموجود در ورودی است، به تاریخچهٔ تطابق‌های فرعی \fBtag\fP الحاق کند (برای جزئیات به بخش استخراج تطابق‌های فرعی مراجعه کنید). .TP .B \fBYYSHIFT\fP یک دستور اولیه عمومی API با یک متغیر \fBshift\fP که باید موقعیت فعلی ورودی را به اندازهٔ \fBshift\fP نویسه جابه‌جا کند (مقدار جابه‌جایی ممکن است منفی باشد). .TP .B \fBYYCOPYSTAG\fP یک دستور اولیه عمومی API با دو متغیر \fBlhs\fP و \fBrhs\fP که باید متغیر s\-tag سمت راست (\fBrhs\fP) را در متغیر s\-tag سمت چپ (\fBlhs\fP) رونوشت کند. برای بیشتر زبان‌ها این دستور اولیه دارای یک تعریف پیش‌فرض است که \fBlhs\fP را برابر \fBrhs\fP قرار می‌دهد. .TP .B \fBYYCOPYMTAG\fP یک دستور اولیه عمومی API با دو متغیر \fBlhs\fP و \fBrhs\fP که باید متغیر m\-tag سمت راست (\fBrhs\fP) را در متغیر m\-tag سمت چپ (\fBlhs\fP) رونوشت کند. برای بیشتر زبان‌ها این دستور اولیه دارای یک تعریف پیش‌فرض است که \fBlhs\fP را برابر \fBrhs\fP قرار می‌دهد. .TP .B \fBYYSHIFTSTAG\fP یک دستور اولیه عمومی API با دو متغیر \fBtag\fP و \fBshift\fP که باید \fBtag\fP را به اندازهٔ \fBshift\fP واحد کد جابه‌جا کند (مقدار جابه‌جایی ممکن است منفی باشد). .TP .B \fBYYSHIFTMTAG\fP یک دستور اولیه عمومی API با دو متغیر \fBtag\fP و \fBshift\fP که باید آخرین مقدار در تاریخچهٔ \fBtag\fP را به اندازهٔ \fBshift\fP واحد کد جابه‌جا کند (مقدار جابه‌جایی ممکن است منفی باشد). .TP .B \fBYYMAXNMATCH\fP یک ثابت عدد صحیح برابر با حداکثر تعداد گروه‌های تسخیرکنندهٔ POSIX در یک قاعده. این مقدار با یک بلوک \fBmaxnmatch\fP تولید می‌شود. .TP .B \fBYYCONDTYPE\fP نوع نوع شمارشی شرط (condition enum). می‌تواند با بلوک \fBconditions\fP یا گزینهٔ \fB\-\-header\fP تولید شود. .TP .B \fBYYGETACCEPT\fP یک دستور اولیه با یک متغیر \fBvar\fP که انتخاب‌گر عددیِ قاعدهٔ پذیرفته‌شده را ذخیره می‌کند. برای بیشتر زبان‌ها این دستور اولیه تعریفی پیش‌فرض دارد که از \fBvar\fP می‌خواند. .TP .B \fBYYSETACCEPT\fP یک دستور اولیه با دو متغیر: \fBvar\fP (یک l\-value که انتخاب‌گر عددی قاعدهٔ پذیرفته‌شده را ذخیره می‌کند) و \fBval\fP (مقدار انتخاب‌گر). برای بیشتر زبان‌ها این دستور اولیه تعریفی پیش‌فرض دارد که \fBvar\fP را برابر \fBval\fP قرار می‌دهد. .TP .B \fBYYGETCOND\fP یک r\-value از نوع \fBYYCONDTYPE\fP که برابر با شناسهٔ شرط فعلی است. .TP .B \fBYYSETCOND\fP یک دستور اولیه با یک متغیر \fBcond\fP که باید شناسهٔ شرط فعلی را روی \fBcond\fP تنظیم کند. .TP .B \fBYYGETSTATE\fP یک r\-value از نوع عدد صحیح که برابر با وضعیت فعلی تحلیل‌گر لغوی (lexer) است. مقدار آن باید به \fB\-1\fP مقداردهی اولیه شود. .TP .B \fBYYSETSTATE\fP یک دستور اولیه با یک متغیر \fBstate\fP که باید وضعیت فعلی تحلیل‌گر لغوی را روی \fBstate\fP تنظیم کند. .TP .B \fBYYDEBUG\fP این دستور اولیه فقط با گزینهٔ \fB\-d\fP یا \fB\-\-debug\-output\fP تولید می‌شود. هدف آن افزودن امکان ثبت وقایع (لاگین) به کد تولیدشده است (تعریف معمول \fBYYDEBUG\fP یک دستور چاپ است). عبارت‌های \fBYYDEBUG\fP در هر وضعیت تولید می‌شوند و دو متغیر دارند: \fBstate\fP (یا نمایهٔ وضعیت DFA یا \fB\-1\fP) و \fBsymbol\fP (نماد ورودی فعلی). .TP .B \fByyaccept\fP یک l\-value از نوع عددیِ صحیح بدون علامت که شمارهٔ آخرین قاعدهٔ منطبق‌شده را ذخیره می‌کند. تعریف توسط کاربر تنها با گزینهٔ \fB\-\-storable\-state\fP ضروری است. .TP .B \fByybm\fP جدولی حاوی نقشه‌های بیتی فشرده‌شده برای حداکثر ۸ گذار (که با گزینهٔ \fB\-\-bitmaps\fP استفاده می‌شود). این جدول شامل ۲۵۶ عنصر است و با واحدهای کد ۱ بایتی اندیس‌گذاری می‌شود. هر عنصر ۸ بیتی، مقادیر بولی را برای حداکثر ۸ گذار ترکیب می‌کند. بیت k\-اُم از عنصر n\-اُم درست (true) است اگر و تنها اگر n\-اُمین واحد کد در محدودهٔ k\-اُمین گذار باشد. ایدهٔ این نقشهٔ بیتی جایگزینی چندین شاخهٔ \fIif\fP یا حالت‌های \fIswitch\fP با یک بررسیِ تک‌بیتی در جدول است. .TP .B \fByych\fP یک l\-value از نوع \fBYYCTYPE\fP که نویسهٔ ورودی فعلی را ذخیره می‌کند. تعریف توسط کاربر تنها با گزینهٔ \fB\-f\fP \fB\-\-storable\-state\fP لازم است. .TP .B \fByyctable\fP جدول پرش تولیدشده برای توزیع شرط اولیه (که با ترکیب گزینه‌های \fB\-\-conditions\fP و \fB\-\-computed\-gotos\fP فعال می‌شود). .TP .B \fByyfill\fP یک l\-value که نتیجهٔ فراخوانی \fBYYFILL\fP را ذخیره می‌کند (این ممکن است برای زبان‌های تابعی محض لازم باشد، جایی که \fBYYFILL\fP تابعی مونادیک با مقدار بازگشتی پیچیده است). .TP .B \fByynmatch\fP یک l\-value از نوع عددیِ صحیح بدون علامت که تعداد گروه‌های تسخیرکنندهٔ POSIX را در قاعدهٔ منطبق‌شده ذخیره می‌کند. تنها با گزینهٔ \fB\-P\fP \fB\-\-posix\-captures\fP استفاده می‌شود. .TP .B \fByypmatch\fP آرایه‌ای از l\-valueها که برای نگهداری مقادیر برچسب مربوط به پرانتزهای تسخیرکننده در قاعدهٔ منطبق‌شده استفاده می‌شوند. طول آرایه باید حداقل \fByynmatch * 2\fP باشد (معمولاً \fBYYMAXNMATCH * 2\fP انتخاب مناسبی است). تنها با گزینهٔ \fB\-P\fP \fB\-\-posix\-captures\fP استفاده می‌شود. .TP .B \fByystable\fP منسوخ‌شده. .TP .B \fByystate\fP یک l\-value که با گزینهٔ \fB\-\-loop\-switch\fP برای ذخیرهٔ وضعیت فعلی DFA استفاده می‌شود. .TP .B \fByytarget\fP جدول پرشی که حاوی مقصدهای پرش (نشانی‌های برچسب) برای تمامی گذارها از یک وضعیت است. این جدول مختص هر وضعیت به‌صورت محلی است. تولید جدول‌های \fByytarget\fP با گزینهٔ \fB\-\-computed\-gotos\fP فعال می‌شود. .UNINDENT.SS "گزینه‌ها (OPTIONS)" .sp برخی از گزینه‌ها دارای \fI\%پیکربندی‌های\fP متناظر هستند، برخی دیگر سراسری بوده و پس از شروع خواندن فایل ورودی توسط re2c قابل تغییر نیستند. گزینه‌های اشکال‌زدایی (دیباگ) عموماً نیازمند ساخت re2c در پیکربندی دیباگ هستند. گزینه‌های داخلی برای آزمایش الگوریتم‌های به‌کاررفته در re2c مفیدند. .INDENT 0.0 .TP .B \fB\-? \-\-help \-h\fP نمایش پیام راهنما. .TP .B \fB\-\-api \fP مشخص کردن API مورد استفاده توسط کد تولیدشده جهت برقراری ارتباط با کد تعریف‌شده توسط کاربر. گزینهٔ \fBsimple\fP باید در موارد ساده استفاده شود؛ هنگامی که نیازی به پر کردن مجدد بافر و ذخیره‌سازی وضعیت تحلیل‌گر لغوی (lexer) نیست. گزینهٔ \fBrecord\fP باید زمانی استفاده شود که وضعیت لکسر باید در یک رکورد (struct، class و غیره) ذخیره شود. گزینهٔ \fBgeneric\fP باید در سناریوهای پیچیده‌ای به کار رود که دو API دیگر انعطاف‌پذیری کافی ندارند. .TP .B \fB\-\-bit\-vectors \-b\fP بهینه‌سازی پرش‌های شرطی با استفاده از ماسک‌های بیتی. این گزینه مستلزم \fB\-\-nested\-ifs\fP است\&. .TP .B \fB\-\-captures\fP, \fB\-\-leftmost\-captures\fP فعال‌سازی استخراج زیرتطابق با گروه‌های گیرندهٔ حریصانه‌ترینِ چپ‌ترین (leftmost greedy). نتیجه در آرایهٔ \fByybmatch\fP با ظرفیت \fB2 * YYMAXNMATCH\fP جمع‌آوری می‌شود، و \fByynmatch\fP به تعداد گروه‌ها برای قاعدهٔ منطبق‌شده تنظیم می‌گردد. .TP .B \fB\-\-captvars\fP, \fB\-\-leftmost\-captvars\fP فعال‌سازی استخراج زیرتطابق با گروه‌های گیرندهٔ حریصانه‌ترینِ چپ‌ترین (leftmost greedy). نتیجه در متغیرهای \fByytl\fP و \fByytr\fP برای گروه گیرندهٔ \fBk\fP\-اُم گردآوری می‌شود. .TP .B \fB\-\-case\-insensitive\fP در نظر گرفتن رشته‌های دارای تک‌نقل‌قول و دونقل‌قول به صورت غیرحساس به بزرگی و کوچکی حروف. .TP .B \fB\-\-case\-inverted\fP معکوس کردن معنای رشته‌های دارای تک‌نقل‌قول و دونقل‌قول: رشته‌های با تک‌نقل‌قول حساس به حروف و رشته‌های با دونقل‌قول غیرحساس به بزرگی و کوچکی حروف در نظر گرفته می‌شوند. .TP .B \fB\-\-case\-ranges\fP ادغام caseهای متوالی در دستور switch به یک بازه در قالب \fBlow ... high\fP\&. این نحو، یک افزونهٔ زبان C/C++ است که توسط کامپایلرهایی مانند GCC، Clang و Tcc پشتیبانی می‌شود. مزیت اصلی نسبت به استفاده از caseهای تکی، تولید کد کوچک‌تر و سرعت بالاتر در زمان تولید کد است، اگرچه برای برخی کامپایلرها مانند Tcc منجر به کاهش اندازهٔ فایل باینری نیز می‌شود. .TP .B \fB\-\-computed\-gotos \-g\fP بهینه‌سازی پرش‌های شرطی با استفاده از افزونهٔ غیراستاندارد \(dqcomputed goto\(dq (که باید توسط کامپایلر پشتیبانی شود). برنامه re2swift جدول‌های پرش را تنها در موارد پیچیده با تعداد زیادی شاخهٔ شرطی تولید می‌کند. آستانهٔ پیچیدگی با پیکربندی \fBcgoto:threshold\fP قابل تنظیم است. آفست‌های نسبی را می‌توان با پیکربندی \fBcgoto:relative\fP فعال کرد. این گزینه مستلزم \fB\-\-bit\-vectors\fP است\&. .TP .B \fB\-\-computed\-gotos\-relative\fP مشابه \-\-computed\-gotos، اما در عوض آفست‌های نسبی را برای جدول‌های پرش تولید می‌کند (که باید توسط کامپایلر پشتیبانی شود). این گزینه مستلزم \fB\-\-computed\-gotos\fP است\&. .TP .B \fB\-\-conditions \-\-start\-conditions \-c\fP فعال‌سازی پشتیبانی از \(dqشرایط\(dq مشابه Flex: چندین لکسر مرتبط درون یک بلوک. این یک جایگزین برای مشخص‌کردن دستی بلوک‌های مختلف re2swift متصل‌شده با \fBgoto\fP یا فراخوانی‌های توابع است. .TP .B \fB\-\-depfile FILE\fP نوشتن اطلاعات وابستگی در \fBFILE\fP در قالب یک قاعدهٔ Makefile به شکل \fB : [include\-file ...]\fP\&. این قابلیت امکان ردیابی وابستگی‌های ساخت را در حضور بلوک‌ها/دستورهای \fBinclude\fP فراهم می‌کند، به طوری که به‌روزرسانی فایل‌های include باعث تولید مجدد فایل خروجی می‌شود. این گزینه به گزینهٔ \fB\-\-output\fP وابسته است. .TP .B \fB\-\-ebcdic \-\-ecb \-e\fP تولید لکسری که ورودی را با کدگذاری EBCDIC می‌خواند. برنامه re2swift فرض می‌کند که محدودهٔ نویسه‌ها 0 \-\- 0xFF و اندازهٔ نویسه ۱ بایت است. .TP .B \fB\-\-empty\-class \fP تعیین نحوهٔ رفتار re2swift با کلاس‌های نویسهٔ خالی. با مقدار \fBmatch\-empty\fP (پیش‌فرض) کلاس خالی با ورودی خالی تطابق می‌یابد (که غیرمنطقی است، اما برای سازگاری با نسخه‌های قبلی حفظ شده است). با \fBmatch\-none\fP تطبیق کلاس خالی همیشه با شکست مواجه می‌شود. با \fBerror\fP کلاس خالی یک خطای کامپایل ایجاد می‌کند. .TP .B \fB\-\-encoding\-policy \fP تعیین نحوهٔ رفتار re2swift با جانشین‌های یونیکد (surrogates). با مقدار \fBfail\fP برنامه re2swift با مواجهه با یک جانشین، با خطا متوقف می‌شود. با \fBsubstitute\fP برنامه re2swift بدون هشدار جانشین‌ها را با کدپوینت خطای 0xFFFD جایگزین می‌کند. با \fBignore\fP (پیش‌فرض) re2swift با جانشین‌ها مانند کدپوینت‌های معمولی رفتار می‌کند. استاندارد یونیکد بیان می‌کند که جانشین‌های مستقل نامعتبر هستند، اما کتابخانه‌ها و برنامه‌های دنیای واقعی رفتارهای متفاوتی دارند. .TP .B \fB\-\-flex\-syntax \-F\fP پشتیبانی جزئی از نحو Flex: در این حالت تعاریف نام‌گذاری‌شده نیازی به علامت مساوی و سمی‌کولنِ پایانی ندارند، و در صورت استفاده باید درون آکوالاد قرار گیرند. نام‌های بدون آکوالاد به عنوان رشته‌های محصور در دونقل‌قول در نظر گرفته می‌شوند. .TP .B \fB\-\-goto\-label\fP استفاده از مدل کد \(dqgoto/label\(dq: کدگذاری DFA در قالب بلوک‌های کد برچسب‌دار متصل‌شده با انتقال‌های \fBgoto\fP میان بلوک‌ها. این گزینه تنها برای زبان‌هایی پشتیبانی می‌شود که دستور \fBgoto\fP دارند. .TP .B \fB\-\-header \-\-type\-header \-t HEADER\fP تولید یک فایل \fBHEADER\fP. محتوای فایل را می‌توان با استفاده از بلوک‌های ویژهٔ \fBheader:on\fP و \fBheader:off\fP تعیین کرد\&. در صورت استفاده از شرایط، شمارشگر مربوط به شرایط (enum) به طور خودکار به انتهای فایل سرایندِ تولیدشده اضافه خواهد شد (مگر اینکه یک بلوک صریح \fBconditions\fP وجود داشته باشد). .TP .B \fB\-I PATH\fP افزودن \fBPATH\fP به فهرست مسیرهایی که هنگام جستجوی فایل‌های include استفاده می‌شوند. این گزینه در ترکیب با بلوک یا دستور \fBinclude\fP مفید است. برنامه re2swift فایل \fBFILE\fP را در دایرکتوری فایل والد و در مسیرهای include تعیین‌شده با گزینهٔ \fB\-I\fP جستجو می‌کند. .TP .B \fB\-\-input \fP نام مستعار منسوخ‌شده برای \fB\-\-api\fP\&. گزینهٔ \fBdefault\fP متناظر با \fBsimple\fP است (در واقع برای اکثر بک‌اندها پیش‌فرض است، اما نه برای همه). گزینهٔ \fBcustom\fP متناظر با \fBgeneric\fP است\&. .TP .B \fB\-\-input\-encoding \fP مشخص کردن نحوهٔ تجزیهٔ عبارت‌های منظم توسط re2swift. با مقدار \fBascii\fP (پیش‌فرض) re2swift ورودی را به عنوان کدگذاری ASCII در نظر می‌گیرد: هر توالی از واحدهای کد، توالی از نویسه‌های مستقل ۱ بایتی است. با \fButf8\fP برنامه re2swift ورودی را به عنوان کدگذاری UTF-8 در نظر گرفته و نویسه‌های چندبایتی را تشخیص می‌دهد. .TP .B \fB\-\-invert\-captures\fP معکوس کردن معنای گروه‌های گیرنده و غیرگیرنده. به صورت پیش‌فرض \fB(...)\fP گیرنده و \fB(! ...)\fP غیرگیرنده است. با این گزینه \fB(! ...)\fP گیرنده و \fB(...)\fP غیرگیرنده خواهد بود. .TP .B \fB\-\-lang \fP مشخص کردن زبان مقصد. زبان‌های پشتیبانی‌شده عبارتند از C، D، Go، Haskell، Java، JS، OCaml، Python، Rust، Swift، V، Zig (زبان‌های بیشتر را می‌توان از طریق فایل‌های نحوِ تعریف‌شده توسط کاربر اضافه کرد؛ گزینهٔ \fB\-\-syntax\fP را ببینید). گزینهٔ \fBnone\fP پیکربندی‌های پیش‌فرض نحو را غیرفعال می‌کند تا زبان مقصد تعریف‌نشده باقی بماند. .TP .B \fB\-\-location\-format \fP تعیین قالب مکان در پیام‌ها. با \fBgnu\fP مکان‌ها به صورت \(aqfilename:line:column: ...\(aq چاپ می‌شوند. با \fBmsvc\fP مکان‌ها به صورت \(aqfilename(line,column) ...\(aq چاپ می‌شوند. پیش‌فرض \fBgnu\fP است\&. .TP .B \fB\-\-loop\-switch\fP استفاده از مدل کد \(dqloop/switch\(dq: کدگذاری DFA در قالب یک حلقه روی دستور switch، که در آن وضعیت‌های جداگانه همان caseهای switch هستند. وضعیت در یک متغیر \fByystate\fP ذخیره می‌شود\&. انتقال‌های بین وضعیت‌ها، \fByystate\fP را به برچسب case وضعیت مقصد به‌روزرسانی کرده و اجرا را به ابتدای حلقه ادامه می‌دهند. .TP .B \fB\-\-nested\-ifs \-s\fP استفاده از دستورات تو‌در‌توی \fBif\fP به جای دستورات \fBswitch\fP در پرش‌های شرطی. این کار معمولاً در کامپایلرهای غیربهینه‌ساز منجر به کدی کارآمدتر می‌شود. .TP .B \fB\-\-no\-debug\-info \-i\fP عدم درج دستورهای خط (line directives) در خروجی. این قابلیت زمانی که کد تولیدشده در یک سیستم کنترل نسخه نگهداری می‌شود مفید است (برای جلوگیری از diffهای حجیم خودکار روی تغییرات کوچک). .TP .B \fB\-\-no\-generation\-date\fP جلوگیری از چاپ تاریخ در فایل تولیدشده. .TP .B \fB\-\-no\-version\fP جلوگیری از چاپ نسخه در فایل تولیدشده. .TP .B \fB\-\-no\-unsafe\fP عدم تولید بسته‌بند \fBunsafe\fP روی \fBYYPEEK\fP (این گزینه مختص Rust است). به دلایل کارایی، \fBYYPEEK\fP باید از بررسی محدوده (bounds-checking) خودداری کند، زیرا لکسر پیش از این بررسی‌های پایان ورودی را به روشی کارآمدتر انجام می‌دهد. کاربر ممکن است تعریفی امن از \fBYYPEEK\fP ارائه دهد، یا تعریفی که تنها در بیلد انتشار (release) ناامن باشد، که در این حالت گزینهٔ \fB\-\-no\-unsafe\fP به جلوگیری از هشدارهای مربوط به بلوک‌های \fBunsafe\fP زاید کمک می‌کند. .TP .B \fB\-\-output \-o OUTPUT\fP مشخص کردن فایل \fBOUTPUT\fP. .TP .B \fB\-\-posix\-captures\fP, \fB\-P\fP فعال‌سازی استخراج زیرتطابق با گروه‌های گیرندهٔ سبک POSIX. نتیجه در آرایهٔ \fByybmatch\fP با ظرفیت \fB2 * YYMAXNMATCH\fP گردآوری شده، و \fByynmatch\fP به تعداد گروه‌ها برای قاعدهٔ منطبق تنظیم می‌شود. .TP .B \fB\-\-posix\-captvars\fP فعال‌سازی استخراج زیرتطابق با گروه‌های گیرندهٔ سبک POSIX. نتیجه در متغیرهای \fByytl\fP و \fByytr\fP برای گروه گیرندهٔ \fBk\fP\-اُم گردآوری می‌شود. .TP .B \fB\-\-recursive\-functions\fP استفاده از مدل کد مبتنی بر توابع هم‌بازگشتی (co-recursive)، که در آن هر وضعیت DFA یک تابع مجزاست که می‌تواند سایر توابع وضعیت یا خودش را فراخوانی کند. .TP .B \fB\-\-reusable \-r\fP از نگارش 2.2 منسوخ شده است (بلوک‌های با قابلیت استفاده مجدد اکنون به طور پیش‌فرض مجاز هستند). .TP .B \fB\-\-skeleton \-S\fP نادیده گرفتن کد واسط تعریف‌شده توسط کاربر و تولید یک برنامهٔ خودکفای \(dqاسکلت\(dq (skeleton). علاوه بر این، تولید فایل‌های ورودی با رشته‌های مشتق‌شده از گرامر منظم و نتایج تطابق فشرده‌شده که برای اعتبارسنجی رفتار برنامهٔ \(dqاسکلت\(dq روی تمام ورودی‌ها به کار می‌روند. این گزینه برای یافتن باگ‌ها در بهینه‌سازی‌ها و تولید کد مفید است. این گزینه تنها برای C پشتیبانی می‌شود..TP .B \fB\-\-storable\-state \-f\fP تولید یک تحلیل‌گر لغوی که می‌تواند وضعیت درونی خود را ذخیره کند. این ویژگی در تحلیل‌گرهای لغوی مبتنی بر مدل push مفید است که در هنگام عدم وجود ورودی کافی توسط برنامه‌ای بیرونی متوقف شده و پس از در دسترس قرار گرفتن ورودی بیشتر، اجرای آن‌ها از سر گرفته می‌شود. در این حالت، کاربران باید علاوه بر این، دستورات اولیهٔ \fBYYGETSTATE\fP و \fBYYSETSTATE\fP را تعریف کنند، و متغیرهای \fByych\fP، \fByyaccept\fP و \fBstate\fP باید بخشی از وضعیت ذخیره‌شدهٔ تحلیل‌گر لغوی باشند. .TP .B \fB\-\-syntax FILE\fP بارگذاری پیکربندی‌ها از \fBFILE\fP مشخص‌شده و اعمال آن‌ها روی فایل نحو پیش‌فرض. توجه داشته باشید که \fBFILE\fP می‌تواند تنها چند پیکربندی را تعریف کند (اگر برای اصلاح فایل نحو پیش‌فرض استفاده شود)، یا یک بک‌اند زبان کاملاً جدید را تعریف نماید (در حالت دوم توصیه می‌شود از گزینهٔ \fB\-\-lang none\fP استفاده شود). .TP .B \fB\-\-tags \-T\fP فعال‌سازی استخراج تطابق‌های فرعی با برچسب‌ها. .TP .B \fB\-\-ucs2 \-\-wide\-chars \-w\fP تولید یک تحلیل‌گر لغوی که ورودی با کدگذاری UCS2 را می‌خواند. re2swift فرض می‌کند که دامنهٔ نویسه‌ها 0 \-\- 0xFFFF و اندازهٔ نویسه ۲ بایت است. این گزینه مستلزم \fB\-\-nested\-ifs\fP است. .TP .B \fB\-\-utf8 \-\-utf\-8 \-8\fP تولید یک تحلیل‌گر لغوی که ورودی با کدگذاری UTF\-8 را می‌خواند. re2swift فرض می‌کند که دامنهٔ نویسه‌ها 0 \-\- 0x10FFFF و اندازهٔ نویسه ۱ بایت است. .TP .B \fB\-\-utf16 \-\-utf\-16 \-x\fP تولید یک تحلیل‌گر لغوی که ورودی با کدگذاری UTF16 را می‌خواند. re2swift فرض می‌کند که دامنهٔ نویسه‌ها 0 \-\- 0x10FFFF و اندازهٔ نویسه ۲ بایت است. این گزینه مستلزم \fB\-\-nested\-ifs\fP است. .TP .B \fB\-\-utf32 \-\-unicode \-u\fP تولید یک تحلیل‌گر لغوی که ورودی با کدگذاری UTF32 را می‌خواند. re2swift فرض می‌کند که دامنهٔ نویسه‌ها 0 \-\- 0x10FFFF و اندازهٔ نویسه ۴ بایت است. این گزینه مستلزم \fB\-\-nested\-ifs\fP است. .TP .B \fB\-\-verbose\fP چاپ یک پیام کوتاه در صورت موفقیت. .TP .B \fB\-\-vernum \-V\fP نمایش اطلاعات نسخه در قالب \fBMMmmpp\fP (نسخه اصلی، فرعی، وصله). .TP .B \fB\-\-version \-v\fP نمایش اطلاعات نسخه. .TP .B \fB\-\-single\-pass \-1\fP منسوخ شده است. کاری انجام نمی‌دهد (حالت تک‌گذره در حال حاضر پیش‌فرض است). .UNINDENT .INDENT 0.0 .TP .B \fB\-\-debug\-output \-d\fP درج فراخوانی‌های \fBYYDEBUG\fP در کد تولیدشده. این قابلیت برای ردگیری اجرای تحلیل‌گر لغوی مفید است. .TP .B \fB\-\-dump\-adfa\fP گزینهٔ اشکال‌زدایی: خروجی دادن DFA پس از تونل‌زنی (به قالب .dot). .TP .B \fB\-\-dump\-cfg\fP گزینهٔ اشکال‌زدایی: خروجی دادن گراف جریان کنترل متغیرهای برچسب (به قالب .dot). .TP .B \fB\-\-dump\-closure\-stats\fP گزینهٔ اشکال‌زدایی: خروجی دادن آمار تعداد وضعیت‌ها در بستار. .TP .B \fB\-\-dump\-dfa\-det\fP گزینهٔ اشکال‌زدایی: خروجی دادن DFA بلافاصله پس از قطعی‌سازی (به قالب .dot). .TP .B \fB\-\-dump\-dfa\-min\fP گزینهٔ اشکال‌زدایی: خروجی دادن DFA پس از کمینه‌سازی (به قالب .dot). .TP .B \fB\-\-dump\-dfa\-tagopt\fP گزینهٔ اشکال‌زدایی: خروجی دادن DFA پس از بهینه‌سازی‌های برچسب (به قالب .dot). .TP .B \fB\-\-dump\-dfa\-tree\fP گزینهٔ اشکال‌زدایی: خروجی دادن DFA در حال ساخت با وضعیت‌هایی که به صورت درخت‌های تاریخچهٔ برچسب نمایش داده شده‌اند (به قالب .dot). .TP .B \fB\-\-dump\-dfa\-raw\fP گزینهٔ اشکال‌زدایی: خروجی دادن DFA در حال ساخت با مجموعه‌وضعیت‌های بسط‌یافته (به قالب .dot). .TP .B \fB\-\-dump\-interf\fP گزینهٔ اشکال‌زدایی: خروجی دادن جدول تداخل حاصل از تحلیل زنده‌بودنِ متغیرهای برچسب. .TP .B \fB\-\-dump\-nfa\fP گزینهٔ اشکال‌زدایی: خروجی دادن NFA (به قالب .dot). .TP .B \fB\-\-emit\-dot \-D\fP به جای خروجی معمول، گراف تحلیل‌گر لغوی را در قالب .dot تولید می‌کند. خروجی را می‌توان با کمک Graphviz به یک تصویر تبدیل کرد (مانند \fBdot \-Tpng \-odfa.png dfa.dot\fP). .UNINDENT .INDENT 0.0 .TP .B \fB\-\-dfa\-minimization \fP گزینهٔ داخلی: الگوریتم کمینه‌سازی DFA مورد استفاده توسط re2swift\&. گزینهٔ \fBmoore\fP الگوریتم مور است (که پیش‌فرض است). گزینهٔ \fBtable\fP الگوریتم \(dqپر کردن جدول\(dq است. هر دو الگوریتم باید صرف‌نظر از نام‌گذاری مجدد وضعیت‌ها، DFA یکسانی تولید کنند؛ پر کردن جدول ساده‌تر و بسیار کندتر است و به عنوان پیاده‌سازی مرجع عمل می‌کند. .TP .B \fB\-\-eager\-skip\fP گزینهٔ داخلی: وادار کردن تحلیل‌گر لغوی تولیدشده به پیش بردن مشتاقانهٔ موقعیت ورودی \-\- بلافاصله پس از خواندن نماد ورودی. این گزینه رفتار پیش‌فرض را تغییر می‌دهد که در آن موقعیت ورودی به صورت تنبلانه \-\- پس از گذار به وضعیت بعدی \-\- به جلو برده می‌شود. .TP .B \fB\-\-no\-lookahead\fP گزینهٔ داخلی، منسوخ شده. در گذشته برای فعال‌سازی الگوریتم TDFA(0) به کار می‌رفت. بر خلاف TDFA(1)، الگوریتم TDFA(0) از پیش‌نگری یک‌نمادی استفاده نمی‌کند. این الگوریتم عملیات ثبات‌ها را به جای گذارهای خروجی، روی گذارهای ورودی اعمال می‌کند. ارزیابی‌ها نشان دادند که الگوریتم TDFA(0) کارایی کمتری نسبت به TDFA(1) دارد. .TP .B \fB\-\-no\-optimize\-tags\fP گزینهٔ داخلی: غیرفعال کردن بهینه‌سازی متغیرهای برچسب (مفید برای اشکال‌زدایی). .TP .B \fB\-\-posix\-closure \fP گزینهٔ داخلی: تعیین الگوریتم کوتاه‌ترین مسیر مورد استفاده برای ساخت بستار اپسیلون با معناشناسی رفع ابهام POSIX؛ مقدار \fBgor1\fP (پیش‌فرض) نشان‌دهندهٔ الگوریتم گلدبرگ\-رادزیک (Goldberg\-Radzik) است و \fBgtop\fP نشان‌دهندهٔ الگوریتم \(dqترتیب توپولوژیکی سراسری\(dq می‌باشد. .TP .B \fB\-\-posix\-prectable \fP گزینهٔ داخلی: تعیین الگوریتم مورد استفاده برای محاسبهٔ جدول اولویت POSIX. الگوریتم \fBcomplex\fP جدول اولویت را در یک پیمایش از درخت تاریخچهٔ برچسب محاسبه می‌کند و دارای پیچیدگی درجه دو بر حسب تعداد وضعیت‌های TNFA است؛ این حالت پیش‌فرض است. الگوریتم \fBnaive\fP در بدترین حالت دارای پیچیدگی درجه سه بر حسب تعداد وضعیت‌های TNFA است، اما بسیار ساده‌تر از \fBcomplex\fP بوده و ممکن است در موارد غیرپاتولوژیک کمی سریع‌تر باشد. .TP .B \fB\-\-stadfa\fP گزینهٔ داخلی، منسوخ شده. در گذشته برای فعال‌سازی الگوریتم staDFA به کار می‌رفت؛ تفاوت این الگوریتم با TDFA در این است که عملیات ثبات‌ها به جای قرارگیری روی گذارها، در وضعیت‌ها قرار می‌گیرند. ارزیابی‌ها نشان دادند که الگوریتم staDFA کارایی کمتری نسبت به TDFA دارد. .TP .B \fB\-\-fixed\-tags \fP گزینهٔ داخلی: مشخص می‌کند که آیا بهینه‌سازی برچسب‌های ثابت باید روی همهٔ برچسب‌ها اعمال شود (\fBall\fP)، روی هیچ‌کدام (\fBnone\fP)، یا فقط روی آن‌هایی که در الحاق سطح بالا قرار دارند (\fBtoplevel\fP). مقدار پیش‌فرض \fBall\fP است. برچسب‌های \(dqثابت\(dq برچسب‌هایی هستند که در فاصله‌ای معین نسبت به برچسبی دیگر (موسوم به \(dqپایه\(dq) قرار دارند. در چنین حالتی تنها برچسب پایه نیاز به ردیابی دارد، و مقدار برچسب ثابت را می‌توان از حاصل جمع مقدار برچسب پایه با یک آفست ایستا محاسبه کرد. برای برچسب‌هایی که درون ساختار انتخاب (alternative) یا تکرار قرار دارند، بررسی این موضوع نیز لازم است که آیا برچسب پایه مقداری معادل عدم تطابق دارد یا خیر (در این صورت برچسب ثابت نیز باید بدون در نظر گرفتن آفست، روی عدم تطابق تنظیم شود). برای برچسب‌های واقع در الحاق سطح بالا، این بررسی لازم نیست زیرا آن‌ها همیشه مطابقت دارند. .UNINDENT.SS "هشدارها (Warnings)" .sp هشدارها را می‌توان به‌صورت جداگانه فعال یا غیرفعال کرد و یا به یک خطا تبدیل نمود. .INDENT 0.0 .TP .B \fB\-W\fP فعال‌سازی تمام هشدارها. .TP .B \fB\-Werror\fP تبدیل هشدارها به خطا. توجه داشته باشید که این گزینه به‌تنهایی هیچ هشداری را فعال نمی‌کند؛ بلکه تنها بر هشدارهایی تأثیر می‌گذارد که تاکنون فعال شده‌اند یا بعداً فعال خواهند شد. .TP .B \fB\-W\fP فعال‌سازی \fBwarning\fP\&. .TP .B \fB\-Wno\-\fP غیرفعال‌سازی \fBwarning\fP\&. .TP .B \fB\-Werror\-\fP فعال‌سازی \fBwarning\fP و در نظر گرفتن آن به‌عنوان خطا (شامل \fB\-W\fP نیز می‌شود). .TP .B \fB\-Wno\-error\-\fP این \fBwarning\fP خاص را به‌عنوان خطا در نظر نگیر. این گزینه خودِ هشدار را غیرفعال نمی‌کند. .UNINDENT .INDENT 0.0 .TP .B \fB\-Wcondition\-order\fP هشدار در صورتی که برنامه تولیدشده فرضیات ضمنی درباره شماره‌گذاری شرط‌ها داشته باشد. کاربر باید از گزینه \fB\-\-header\fP یا بلوک \fBconditions\fP برای تولید نگاشت نام‌های شرط به اعداد استفاده کند و سپس نام‌های شرط تولیدشده به‌صورت خودکار را به کار ببرد. .TP .B \fB\-Wempty\-character\-class\fP هشدار در صورتی که یک عبارت باقاعده شامل یک کلاس نویسه خالی باشد. تلاش برای تطبیق یک کلاس نویسه خالی بی‌معنی است: این تطبیق همیشه باید با شکست مواجه شود. با این حال، به دلایل سازگاری با گذشته، re2swift کلاس‌های نویسه خالی را مجاز دانسته و با آن‌ها مانند رشته‌های خالی رفتار می‌کند. از گزینه \fB\-\-empty\-class\fP برای تغییر رفتار پیش‌فرض استفاده کنید. .TP .B \fB\-Wmatch\-empty\-string\fP هشدار در صورتی که یک قاعده تهی‌پذیر باشد (با یک رشته خالی تطبیق یابد). اگر تحلیل‌گر لغوی در یک حلقه اجرا شود و تطبیق خالی ناخواسته باشد، تحلیل‌گر لغوی ممکن است به‌طور غیرمنتظره در یک حلقه بی‌پایان گیر کند. .TP .B \fB\-Wswapped\-range\fP هشدار در صورتی که کران پایین یک بازه بزرگ‌تر از کران بالای آن باشد. رفتار پیش‌فرض جابه‌جا کردن بی‌سروصدای کران‌های بازه است. .TP .B \fB\-Wundefined\-control\-flow\fP هشدار در صورتی که برخی از رشته‌های ورودی باعث ایجاد جریان کنترل تعریف‌نشده در تحلیل‌گر لغوی شوند (الگوهای ناقص گزارش می‌شوند). این یک اشتباه رایج و خطرناک است. این مشکل را می‌توان به‌سادگی با افزودن قاعده پیش‌فرض \fB*\fP رفع کرد که کمترین اولویت را دارد، با هر واحد کد تطبیق می‌یابد، و همیشه یک واحد کد منفرد را مصرف می‌کند. .TP .B \fB\-Wunreachable\-rules\fP هشدار درباره قواعدی که توسط قواعد دیگر تحت‌الشعاع قرار گرفته‌اند و هرگز تطبیق نخواهند یافت. .TP .B \fB\-Wdeprecated\-eof_rule\fP هشدار درباره قواعد مستقل پایان ورودی \fB$\fP که با تغییرات آینده شکسته خواهند شد و نیاز به اصلاح دارند. در حال حاضر این قواعد هنگام تداخل با قواعد دیگر تقدم دارند، اما پس از معرفی نماد تعمیم‌یافته پایان ورودی \fB$\fP، ترتیب تقدم تغییر خواهد کرد و این قواعد توسط سایر قواعد تحت‌الشعاع قرار خواهند گرفت. .TP .B \fB\-Wuseless\-escape\fP هشدار در صورتی که نمادی گریزدهی شده باشد که نباید می‌شد. به‌طور پیش‌فرض، re2swift چنین گریزهایی را نادیده می‌گیرد، اما این مورد ممکن است نشان‌دهنده یک غلط تایپی یا خطایی در توالی گریز باشد. .TP .B \fB\-Wnondeterministic\-tags\fP هشدار در صورتی که یک برچسب دارای درجه \fBn\fP\-ام از غیرقطعی بودن باشد، جایی که \fBn\fP بزرگ‌تر از ۱ است. .TP .B \fB\-Wsentinel\-in\-midrule\fP هشدار در صورتی که نماد دیده‌بان در میانه یک قاعده رخ دهد \-\-\- این امر ممکن است باعث خواندن فراتر از انتهای بافر، خرابی‌ها یا خراب شدن حافظه در تحلیل‌گر لغوی تولیدشده شود. این هشدار تنها در صورتی کاربرد دارد که از روش دیده‌بان برای بررسی پایان ورودی استفاده شود. در صورت استفاده از پیکربندی \fBre2c:sentinel\fP، این هشدار به خطا تبدیل می‌شود. .TP .B \fB\-Wundefined\-syntax\-config\fP هشدار در صورتی که فایل نحو مشخص‌شده با گزینه \fB\-\-syntax\fP فاقد تعاریف برخی از پیکربندی‌ها باشد. این به نگهداری فایل‌های نحو تعریف‌شده توسط کاربر کمک می‌کند: اگر نسخه جدیدی پیکربندی‌هایی را اضافه کند، فایل نحو قدیمی هشداری صادر خواهد کرد و کاربر مطلع خواهد شد. اگر برخی از پیکربندی‌ها استفاده نمی‌شوند و نیازی به تعریف ندارند، باید به‌صراحت روی \fB\fP تنظیم شوند. .UNINDENT .SS "فایل‌های نحو (Syntax files)" .sp پشتیبانی از زبان‌های مختلف در re2c بر پایه ایده \fIفایل‌های نحو\fP استوار است. یک فایل نحو، فایلی پیکربندی است که نحو زبان مقصد را تعریف می‌کند \-\- نه کل زبان، بلکه بخش کوچکی از آن را که توسط کد تولیدشده استفاده می‌شود. فایل‌های نحو re2c را بسیار انعطاف‌پذیر می‌کنند، اما نباید به‌عنوان جایگزینی برای پیکربندی‌های \fBre2c:\fP استفاده شوند: هدف آن‌ها تعریف نحو زبان مقصد است، نه سفارشی‌سازی یک تحلیل‌گر لغوی خاص. همه زبان‌های پشتیبانی‌شده دارای فایل‌های نحو پیش‌فرضی هستند که بخشی از توزیع به شمار می‌روند (زیردایرکتوری \fBinclude/syntax\fP را ببینید)؛ آن‌ها همچنین در باینری re2swift تعبیه شده‌اند. کاربران می‌توانند یک فایل نحو سفارشی ارائه دهند که چند پیکربندی را برای یکی از زبان‌های پشتیبانی‌شده بازنویسی می‌کند، یا می‌توانند تمام پیکربندی‌ها را از نو تعریف کنند (در این صورت باید از گزینه \fB\-\-lang none\fP استفاده شود). فایل‌های نحو حاوی پیکربندی‌هایی از چهار نوع مختلف هستند: فهرست ویژگی‌ها، پیکربندی‌های زبان، پیکربندی‌های درجا و الگوهای کد. .sp \fBفهرست ویژگی‌ها (Feature lists)\fP .INDENT 0.0 .INDENT 3.5 چند پیکربندی فهرستی، ویژگی‌های گوناگون پشتیبانی‌شده توسط یک بک‌اند معین را تعریف می‌کنند، به‌گونه‌ای که re2swift در صورت تلاش کاربر برای فعال‌سازی یک ویژگی پشتیبانی‌نشده، خطای واضحی صادر کند: .INDENT 0.0 .TP .B \fBsupported_apis\fP فهرستی از APIهای پشتیبانی‌شده با عناصر ممکنِ \fBsimple\fP، \fBrecord\fP و \fBgeneric\fP\&. .TP .B \fBsupported_api_styles\fP فهرستی از شیوه‌های API پشتیبانی‌شده با عناصر ممکنِ \fBfunctions\fP و \fBfree\-form\fP\&. .TP .B \fBsupported_code_models\fP فهرستی از مدل‌های کد پشتیبانی‌شده با عناصر ممکنِ \fBgoto\-label\fP، \fBloop\-switch\fP و \fBrecursive\-functions\fP\&. .TP .B \fBsupported_targets\fP فهرستی از مقصدهای تولید کد پشتیبانی‌شده با عناصر ممکنِ \fBcode\fP، \fBdot\fP و \fBskeleton\fP\&. .TP .B \fBsupported_features\fP فهرستی از ویژگی‌های پشتیبانی‌شده با عناصر ممکنِ \fBnested\-ifs\fP، \fBbitmaps\fP، \fBcomputed\-gotos\fP، \fBcase\-ranges\fP، \fBmonadic\fP، \fBunsafe\fP، \fBtags\fP، \fBcaptures\fP و \fBcaptvars\fP\&. .UNINDENT .UNINDENT .UNINDENT .sp \fBپیکربندی‌های زبان (Language configurations)\fP .INDENT 0.0 .INDENT 3.5 چند پیکربندی بولی ویژگی‌هایی از زبان مقصد را توصیف می‌کنند که بر تجزیه‌کننده و تولیدکننده کد re2swift تأثیر می‌گذارند: .INDENT 0.0 .TP .B \fBsemicolons\fP غیرصفر اگر زبان پس از دستورها از نقطه‌ویرگول استفاده کند. .TP .B \fBbacktick_quoted_strings\fP غیرصفر اگر زبان دارای رشته‌های احاطه‌شده با بک‌تیک باشد. .TP .B \fBsingle_quoted_strings\fP غیرصفر اگر زبان دارای رشته‌های احاطه‌شده با تک‌نقل‌قول باشد. .TP .B \fBindentation_sensitive\fP غیرصفر اگر زبان به تورفتگی حساس باشد. .TP .B \fBwrap_blocks_in_braces\fP غیرصفر اگر دستورهای مرکب باید در آکوالد قرار گیرند. .UNINDENT .UNINDENT .UNINDENT .sp \fBپیکربندی‌های درجا (Inplace configurations)\fP .INDENT 0.0 .INDENT 3.5 فایل‌های نحو مقادیر اولیه تمام پیکربندی‌های \fBre2c:\fP را تعریف می‌کنند، زیرا ممکن است برای زبان‌های مختلف متفاوت باشند. برای مشاهده فهرست کامل تمام پیکربندی‌های درجا و معنای آن‌ها به بخش پیکربندی‌ها مراجعه کنید. .UNINDENT .UNINDENT .sp \fBالگوهای کد (Code templates)\fP .INDENT 0.0 .INDENT 3.5 الگوهای کد نحو زبان مقصد را تعریف می‌کنند. آن‌ها در یک زبان ویژه‌دامنه ساده با گرامر صوری زیر نوشته می‌شوند: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C code\-template :: name \(aq=\(aq code\-exprs \(aq;\(aq | CODE_TEMPLATE \(aq;\(aq | \(aq\(aq \(aq;\(aq code\-exprs :: | code\-exprs code\-expr code\-expr :: STRING | VARIABLE | optional | list optional :: \(aq(\(aq CONDITIONAL \(aq?\(aq code\-exprs \(aq)\(aq | \(aq(\(aq CONDITIONAL \(aq?\(aq code\-exprs \(aq:\(aq code\-exprs \(aq)\(aq list :: \(aq[\(aq VARIABLE \(aq:\(aq code\-exprs \(aq]\(aq | \(aq[\(aq VARIABLE \(aq{\(aq NUMBER \(aq}\(aq \(aq:\(aq code\-exprs \(aq]\(aq | \(aq[\(aq VARIABLE \(aq{\(aq NUMBER \(aq,\(aq NUMBER \(aq}\(aq \(aq:\(aq code\-exprs \(aq]\(aq .ft P .fi .UNINDENT .UNINDENT .sp یک الگوی کد توالی‌ای از رشته‌های لفظی، متغیرها، عناصر اختیاری و فهرست‌ها، یا ارجاعی به الگوی کد دیگر، یا مقدار ویژه \fB\fP است. متغیرها جای‌بان‌هایی هستند که در مرحله تولید کد جایگزین می‌شوند. متغیرهای فهرستی خاص هستند: هنگام بسط الگوهای فهرستی، re2swift عبارت‌های سمت راست دونقطه را چند بار تکرار می‌کند، و هر بار رخدادهای متغیر فهرست را با مقداری مخصوص به این تکرار جایگزین می‌سازد. فهرست‌ها دارای کران‌های اختیاری هستند (مقادیر منفی از انتها شمرده می‌شوند، مثلاً \fB\-1\fP به معنای آخرین عنصر است). نام‌های شرطی با یک نقطه شروع می‌شوند. هم شرط‌ها و هم متغیرها می‌توانند محلی (مخصوص به الگوی کد داده‌شده) یا سراسری (مجاز در تمام الگوهای کد) باشند. هنگامی که re2swift فایل نحو را می‌خواند، بررسی می‌کند که هر الگوی کد تنها از متغیرها و شرط‌هایی استفاده کند که در آن مجاز هستند. .sp به‌عنوان مثال، الگوی کد زیر ساختار if\-then\-else را برای یک زبان C\-مانند تعریف می‌کند: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C code:if_then_else = [branch{0}: topindent \(dqif \(dq cond \(dq {\(dq nl indent [stmt: stmt] dedent] [branch{1:\-1}: topindent \(dq} else\(dq (.cond ? \(dq if \(dq cond) \(dq {\(dq nl indent [stmt: stmt] dedent] topindent \(dq}\(dq nl; .ft P .fi .UNINDENT .UNINDENT .sp در اینجا \fBbranch\fP یک متغیر فهرستی است: \fBbranch{0}\fP به شاخه نخست بسط می‌یابد (که ویژه است، زیرا بخش \fBelse\fP ندارد)، و \fBbranch{1:\-1}\fP به تمام شاخه‌های باقی‌مانده (در صورت وجود) بسط پیدا می‌کند. \fBstmt\fP نیز یک متغیر فهرستی است: \fB[stmt: stmt]\fP یک فهرست تو‌در‌تو است که به فهرستی از دستورها در بدنه شاخه جاری بسط می‌یابد. \fBtopindent\fP، \fBindent\fP، \fBdedent\fP و \fBnl\fP متغیرهای سراسری هستند، و \fB\&.cond\fP یک شرط محلی است (معنای آن‌ها در ادامه شرح داده شده است). این الگوی کد می‌تواند کد زیر را تولید کند: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C if x { // do something } else if y { // do something else } else { // don\(aqt do anything } .ft P .fi .UNINDENT .UNINDENT .sp در ادامه فهرستی از تمام الگوهای کد پشتیبانی‌شده توسط re2swift به همراه متغیرها و شرط‌های محلی آن‌ها آورده شده است. توجه داشته باشید که یک تعریف خاص می‌تواند از متغیرها و شرط‌های محلی استفاده کند، اما ملزم به انجام آن نیست. هر الگوی کد بدون استفاده باید روی \fB\fP تنظیم شود. .INDENT 0.0.TP .B \fBcode:var_local\fP اعلان یا تعریف یک متغیر محلی. متغیرهای پشتیبانی‌شده: \fBtype\fP (نوع متغیر)، \fBname\fP (نام آن) و \fBinit\fP (مقدار اولیه، در صورت وجود). شرط‌ها: \fB\&.init\fP (اگر مقداردهی اولیه وجود داشته باشد، true). .TP .B \fBcode:var_global\fP مشابه \fBcode:var_local\fP، با این تفاوت که در سطح بالا (top\-level) استفاده می‌شود. .TP .B \fBcode:const_local\fP تعریف یک مقدار ثابت محلی. متغیرهای پشتیبانی‌شده: \fBtype\fP (نوع مقدار ثابت)، \fBname\fP (نام آن) و \fBinit\fP (مقدار اولیه). .TP .B \fBcode:const_global\fP مشابه \fBcode:const_local\fP، با این تفاوت که در سطح بالا (top\-level) استفاده می‌شود. .TP .B \fBcode:array_local\fP تعریف یک آرایه محلی (جدول). متغیرهای پشتیبانی‌شده: \fBtype\fP (نوع عناصر آرایه)، \fBname\fP (نام آرایه)، \fBsize\fP (اندازه آن)، \fBrow\fP (یک متغیر فهرستی که به خودی خود کدی تولید نمی‌کند، اما عبارت فهرست را به تعداد سطرهای جدول بسط می‌دهد) و \fBelem\fP (یک متغیر فهرستی که به تمام عناصر جدول در سطر فعلی بسط می‌یابد \-\- برای قرارگیری به‌صورت تودرتو در فهرست \fBrow\fP در نظر گرفته شده است). شرط پشتیبانی‌شده: \fB\&.const\fP (اگر آرایه تغییرناپذیر باشد، true). .TP .B \fBcode:array_global\fP مشابه \fBcode:array_local\fP، با این تفاوت که در سطح بالا (top\-level) استفاده می‌شود. .TP .B \fBcode:array_elem\fP ارجاع به عنصری از یک آرایه (جدول). متغیرهای پشتیبانی‌شده: \fBarray\fP (نام آرایه) و \fBindex\fP (اندیس عنصر). .TP .B \fBcode:enum\fP تعریف یک نوع شمارشی (ممکن است با استفاده از یک ساختار زبانی ویژه برای شمارش‌ها، یا صرفاً به‌صورت چند مقدار ثابت مستقل تعریف شود). متغیرهای پشتیبانی‌شده عبارتند از \fBtype\fP (نوع شمارشی تعریف‌شده توسط کاربر یا نوع ثابت‌ها)، \fBelem\fP (متغیر فهرستی که به نام هر عضو بسط می‌یابد) و \fBinit\fP (مقداردهی اولیه برای هر عضو). شرط‌ها: \fB\&.init\fP (اگر مقداردهی اولیه وجود داشته باشد، true). .TP .B \fBcode:enum_elem\fP عنصر نوع شمارشی (عضوی از یک نوع شمارشی تعریف‌شده توسط کاربر یا نام یک مقدار ثابت، بسته به نحوه تعریف \fBcode:enum\fP). متغیرهای پشتیبانی‌شده عبارتند از \fBname\fP (نام عنصر) و \fBtype\fP (نوع آن). .TP .B \fBcode:assign\fP دستور انتساب. متغیرهای پشتیبانی‌شده عبارتند از \fBlhs\fP (سمت چپ) و \fBrhs\fP (سمت راست). .TP .B \fBcode:type_int\fP نوع عدد صحیح علامت‌دار (signed integer). .TP .B \fBcode:type_uint\fP نوع عدد صحیح بدون علامت (unsigned integer). .TP .B \fBcode:type_yybm\fP نوع عناصر موجود در جدول \fByybm\fP. .TP .B \fBcode:type_yytarget\fP نوع عناصر موجود در جدول \fByytarget\fP. .TP .B \fBcode:type_yyctable\fP نوع عناصر موجود در جدول \fByyctable\fP. .TP .B \fBcode:cmp_eq\fP عملگر \(dqequals\(dq (مساوی). .TP .B \fBcode:cmp_ne\fP عملگر \(dqnot equals\(dq (نامساوی). .TP .B \fBcode:cmp_lt\fP عملگر \(dqless than\(dq (کوچک‌تر). .TP .B \fBcode:cmp_gt\fP عملگر \(dqgreater than\(dq (بزرگ‌تر). .TP .B \fBcode:cmp_le\fP عملگر \(dqless or equal\(dq (کوچک‌تر یا مساوی). .TP .B \fBcode:cmp_ge\fP عملگر \(dqgreater or equal\(dq (بزرگ‌تر یا مساوی). .TP .B \fBcode:if_then_else\fP دستور If\-then\-else با یک یا چند شاخه. متغیرهای پشتیبانی‌شده: \fBbranch\fP (یک متغیر فهرستی که به خودی خود کدی تولید نمی‌کند، اما عبارت فهرست را به تعداد شاخه‌ها بسط می‌دهد)، \fBcond\fP (شرط شاخه فعلی) و \fBstmt\fP (یک متغیر فهرستی که به تمام دستورهای موجود در شاخه فعلی بسط می‌یابد). شرط‌ها: \fB\&.cond\fP (اگر شاخه فعلی دارای شرط باشد، true)، \fB\&.many\fP (اگر بیش از یک شاخه وجود داشته باشد، true). .TP .B \fBcode:if_then_else_oneline\fP حالت خاصی از \fBcode:if_then_else\fP برای زمانی که تمام شاخه‌ها دستورهای تک‌خطی دارند. اگر این مورد \fB\fP باشد، به جای آن از \fBcode:if_then_else\fP استفاده می‌شود. .TP .B \fBcode:switch\fP یک دستور switch با یک یا چند حالت (case). متغیرهای پشتیبانی‌شده: \fBexpr\fP (عبارتی که روی آن switch انجام می‌شود) و \fBcase\fP (یک متغیر فهرستی که به تمام گروه‌های case همراه با بلوک‌های کدشان بسط می‌یابد). .TP .B \fBcode:switch_cases\fP گروهی از حالت‌های switch که به یک بلوک کد واحد نگاشت می‌شوند. متغیرهای پشتیبانی‌شده عبارتند از \fBcase\fP (یک متغیر فهرستی که به تمام حالت‌های این گروه بسط می‌یابد) و \fBstmt\fP (یک متغیر فهرستی که به تمام دستورهای موجود در بلوک کد بسط می‌یابد). .TP .B \fBcode:switch_cases_oneline\fP حالت خاصی از \fBcode:switch_cases\fP برای زمانی که بلوک کد شامل یک دستور تک‌خطی است. اگر این مورد \fB\fP باشد، به جای آن از \fBcode:switch_cases\fP استفاده می‌شود. .TP .B \fBcode:switch_case_range\fP یک حالت switch تکی که محدوده‌ای از مقادیر را پوشش می‌دهد (که ممکن است شامل یک مقدار واحد باشد). متغیر پشتیبانی‌شده: \fBval\fP (یک متغیر فهرستی که به تمام مقادیر موجود در محدوده بسط می‌یابد). شرط‌های پشتیبانی‌شده: \fB\&.many\fP (اگر بیش از یک مقدار در محدوده وجود داشته باشد، true) و \fB\&.char_literals\fP (اگر این یک switch روی نویسه‌های حرفی باشد، true \-\- برخی زبان‌ها نحو ویژه‌ای برای این حالت ارائه می‌دهند). .TP .B \fBcode:switch_case_default\fP حالت پیش‌فرض (default) در switch. .TP .B \fBcode:loop\fP حلقه‌ای که برای همیشه اجرا می‌شود (مگر اینکه از داخل بدنه حلقه متوقف شود). متغیرهای پشتیبانی‌شده: \fBlabel\fP (برچسب حلقه)، \fBstmt\fP (یک متغیر فهرستی که به تمام دستورهای بدنه حلقه بسط می‌یابد). .TP .B \fBcode:continue\fP دستور continue. متغیرهای پشتیبانی‌شده: \fBlabel\fP (برچسبی که اجرا باید از آن ادامه یابد). .TP .B \fBcode:goto\fP دستور goto. متغیرهای پشتیبانی‌شده: \fBlabel\fP (برچسب مقصد پرش). .TP .B \fBcode:cgoto\fP دستور \fBgoto\fP محاسباتی (computed goto). متغیرهای پشتیبانی‌شده: \fBarray\fP (جدول حاوی اطلاعات \fBgoto\fP محاسباتی)، \fBindex\fP (اندیس عنصر در جدول) و \fBbase\fP (برچسب پایه، تنها در صورتی استفاده می‌شود که \fB\&.cgoto.relative\fP برابر با true باشد). .TP .B \fBcode:cgoto:data\fP عبارت مقداردهی اولیه برای یک عنصر واحد در جدول \fBgoto\fP محاسباتی. متغیرهای پشتیبانی‌شده: \fBlabel\fP (برچسبی که برای مقداردهی اولیه عنصر فعلی استفاده می‌شود)، \fBtype\fP (نوع پایه‌ای عناصر موجود در جدول) و \fBbase\fP (برچسب پایه \- تنها در صورتی استفاده می‌شود که \fB\&.cgoto.relative\fP برابر با true باشد). .TP .B \fBcode:fndecl\fP اعلان تابع. متغیرهای پشتیبانی‌شده: \fBname\fP (نام تابع)، \fBtype\fP (نوع بازگشتی)، \fBthrow\fP (استثناهای پرتاب‌شده توسط این تابع، به پیکربندی \fBre2c:yyfn:throw\fP نگاشت می‌شود)، \fBarg\fP (یک متغیر فهرستی که به خودی خود کدی تولید نمی‌کند، اما عبارت فهرست را به تعداد آرگومان‌های تابع بسط می‌دهد)، \fBargname\fP (نام آرگومان فعلی)، \fBargtype\fP (نوع آرگومان فعلی). شرط: \fB\&.type\fP (اگر این یک تابع غیر void باشد، true). .TP .B \fBcode:fndef\fP مشابه \fBcode:fndecl\fP، اما برای تعریف تابع استفاده می‌شود، بنابراین یک متغیر فهرستی اضافی \fBstmt\fP دارد که به تمام دستورهای درون بدنه تابع بسط می‌یابد. .TP .B \fBcode:fncall\fP دستور فراخوانی تابع. متغیرهای پشتیبانی‌شده: \fBname\fP (نام تابع)، \fBretval\fP (مقدار سمت چپ یا l\-value که مقدار بازگشتی در آن ذخیره می‌شود، در صورت وجود) و \fBarg\fP (یک متغیر فهرستی که به تمام آرگومان‌های تابع بسط می‌یابد). شرط‌ها: \fB\&.args\fP (اگر تابع دارای آرگومان باشد، true) و \fB\&.retval\fP (اگر مقدار بازگشتی نیاز به ذخیره شدن داشته باشد، true). .TP .B \fBcode:tailcall\fP دستور فراخوانی دمدمی (tail call). متغیرهای پشتیبانی‌شده: \fBname\fP (نام تابع) و \fBarg\fP (یک متغیر فهرستی که به تمام آرگومان‌های تابع بسط می‌یابد). شرط‌ها: \fB\&.args\fP (اگر تابع دارای آرگومان باشد، true) و \fB\&.retval\fP (اگر این یک تابع غیر void باشد، true). .TP .B \fBcode:recursive_functions\fP بدنه برنامه با مدل کد \fB\-\-recursive\-functions\fP. متغیرهای پشتیبانی‌شده: \fBfn\fP (یک متغیر فهرستی که به خودی خود هیچ کدی تولید نمی‌کند، اما عبارت فهرست را به تعداد توابع بسط می‌دهد)، \fBfndecl\fP (اعلان تابع فعلی) و \fBfndef\fP (تعریف تابع فعلی). .TP .B \fBcode:fingerprint\fP اثر انگشت (fingerprint) در بالای فایل خروجی تولیدشده. متغیرهای پشتیبانی‌شده: \fBver\fP (نسخه re2swift که برای تولید این فایل استفاده شده است) و \fBdate\fP (تاریخ تولید). .TP .B \fBcode:line_info\fP قالب دستورالعمل‌های خط (اگر روی \fB\fP تنظیم شده باشد، هیچ دستورالعملی تولید نمی‌شود). متغیرهای پشتیبانی‌شده: \fBline\fP (شماره خط) و \fBfile\fP (نام فایل). .TP .B \fBcode:abort\fP دستوری که اجرای برنامه را بی‌درنگ متوقف (abort) می‌کند. .TP .B \fBcode:yydebug\fP دستور \fBYYDEBUG\fP، احتمالاً اختصاصی‌شده برای APIهای مختلف. متغیرهای پشتیبانی‌شده: \fBYYDEBUG\fP، \fByyrecord\fP، \fByych\fP (به پیکربندی‌های \fBre2c:\fP متناظر نگاشت می‌شوند)، \fBstate\fP (شماره وضعیت DFA)..TP .B \fBcode:yypeek\fP دستور \fBYYPEEK\fP، که ممکن است برای APIهای مختلف سفارشی‌سازی شده باشد. متغیرهای پشتیبانی‌شده: \fBYYPEEK\fP، \fBYYCTYPE\fP، \fBYYINPUT\fP، \fBYYCURSOR\fP، \fByyrecord\fP، \fByych\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP). شرط‌ها: \fB\&.cast\fP (درست اگر \fBre2c:yych:conversion\fP روی مقداری غیر از صفر تنظیم شده باشد). .TP .B \fBcode:yyskip\fP دستور \fBYYSKIP\fP، که ممکن است برای APIهای مختلف سفارشی‌سازی شده باشد. متغیرهای پشتیبانی‌شده: \fBYYSKIP\fP، \fBYYCURSOR\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP). .TP .B \fBcode:yybackup\fP دستور \fBYYBACKUP\fP، که ممکن است برای APIهای مختلف سفارشی‌سازی شده باشد. متغیرهای پشتیبانی‌شده: \fBYYBACKUP\fP، \fBYYCURSOR\fP، \fBYYMARKER\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP). .TP .B \fBcode:yybackupctx\fP دستور \fBYYBACKUPCTX\fP، که ممکن است برای APIهای مختلف سفارشی‌سازی شده باشد. متغیرهای پشتیبانی‌شده: \fBYYBACKUPCTX\fP، \fBYYCURSOR\fP، \fBYYCTXMARKER\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP). .TP .B \fBcode:yyskip_yypeek\fP دستور ترکیبی \fBcode:yyskip\fP و \fBcode:yypeek\fP (به‌طور پیش‌فرض \fBcode:yyskip\fP و به دنبال آن \fBcode:yypeek\fP). .TP .B \fBcode:yypeek_yyskip\fP دستور ترکیبی \fBcode:yypeek\fP و \fBcode:yyskip\fP (به‌طور پیش‌فرض \fBcode:yypeek\fP و به دنبال آن \fBcode:yyskip\fP). .TP .B \fBcode:yyskip_yybackup\fP دستور ترکیبی \fBcode:yyskip\fP و \fBcode:yybackup\fP (به‌طور پیش‌فرض \fBcode:yyskip\fP و به دنبال آن \fBcode:yybackup\fP). .TP .B \fBcode:yybackup_yyskip\fP دستور ترکیبی \fBcode:yybackup\fP و \fBcode:yyskip\fP (به‌طور پیش‌فرض \fBcode:yybackup\fP و به دنبال آن \fBcode:yyskip\fP). .TP .B \fBcode:yybackup_yypeek\fP دستور ترکیبی \fBcode:yybackup\fP و \fBcode:yypeek\fP (به‌طور پیش‌فرض \fBcode:yybackup\fP و به دنبال آن \fBcode:yypeek\fP). .TP .B \fBcode:yyskip_yybackup_yypeek\fP دستور ترکیبی \fBcode:yyskip\fP، \fBcode:yybackup\fP و \fBcode:yypeek\fP (به‌طور پیش‌فرض \(ga\(gacode:yyskip\(ga\(ga و به دنبال آن \fBcode:yybackup\fP و سپس \fBcode:yypeek\fP). .TP .B \fBcode:yybackup_yypeek_yyskip\fP دستور ترکیبی \fBcode:yybackup\fP، \fBcode:yypeek\fP و \fBcode:yyskip\fP (به‌طور پیش‌فرض \(ga\(gacode:yybackup\(ga\(ga و به دنبال آن \fBcode:yypeek\fP و سپس \fBcode:yyskip\fP). .TP .B \fBcode:yyrestore\fP دستور \fBYYRESTORE\fP، که ممکن است برای APIهای مختلف سفارشی‌سازی شده باشد. متغیرهای پشتیبانی‌شده: \fBYYRESTORE\fP، \fBYYCURSOR\fP، \fBYYMARKER\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP). .TP .B \fBcode:yyrestorectx\fP دستور \fBYYRESTORECTX\fP، که ممکن است برای APIهای مختلف سفارشی‌سازی شده باشد. متغیرهای پشتیبانی‌شده: \fBYYRESTORECTX\fP، \fBYYCURSOR\fP، \fBYYCTXMARKER\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP). .TP .B \fBcode:yyrestoretag\fP دستور \fBYYRESTORETAG\fP، که ممکن است برای APIهای مختلف سفارشی‌سازی شده باشد. متغیرهای پشتیبانی‌شده: \fBYYRESTORETAG\fP، \fBYYCURSOR\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBtag\fP (نام متغیر برچسب که برای بازیابی موقعیت استفاده می‌شود). .TP .B \fBcode:yyshift\fP دستور \fBYYSHIFT\fP، که ممکن است برای APIهای مختلف سفارشی‌سازی شده باشد. متغیرهای پشتیبانی‌شده: \fBYYSHIFT\fP، \fBYYCURSOR\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBoffset\fP (تعداد واحدهای کد برای انتقال موقعیت فعلی). .TP .B \fBcode:yyshiftstag\fP دستور \fBYYSHIFTSTAG\fP، که ممکن است برای APIهای مختلف سفارشی‌سازی شده باشد. متغیرهای پشتیبانی‌شده: \fBYYSHIFTSTAG\fP، \fByyrecord\fP، \fBnegative\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBtag\fP (متغیر برچسب که باید منتقل شود)، \fBoffset\fP (تعداد واحدهای کد برای انتقال). شرط‌ها: \fB\&.nested\fP (درست اگر این یک برچسب تو‌در‌تو باشد \-\- در این حالت ممکن است مقدار آن برابر با \fBre2c:tags:negative\fP باشد، که نباید منتقل شود). .TP .B \fBcode:yyshiftmtag\fP دستور \fBYYSHIFTMTAG\fP، که ممکن است برای APIهای مختلف سفارشی‌سازی شده باشد. متغیرهای پشتیبانی‌شده: \fBYYSHIFTMTAG\fP (نگاشت به پیکربندی متناظر \fBre2c:\fP)، \fBtag\fP (متغیر برچسب که باید منتقل شود)، \fBoffset\fP (تعداد واحدهای کد برای انتقال). .TP .B \fBcode:yystagp\fP دستور \fBYYSTAGP\fP، که ممکن است برای APIهای مختلف سفارشی‌سازی شده باشد. متغیرهای پشتیبانی‌شده: \fBYYSTAGP\fP، \fBYYCURSOR\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBtag\fP (متغیر برچسب که باید به‌روزرسانی شود). .TP .B \fBcode:yymtagp\fP دستور \fBYYMTAGP\fP، که ممکن است برای APIهای مختلف سفارشی‌سازی شده باشد. متغیرهای پشتیبانی‌شده: \fBYYMTAGP\fP (نگاشت به پیکربندی متناظر \fBre2c:\fP)، \fBtag\fP (متغیر برچسب که باید به‌روزرسانی شود). .TP .B \fBcode:yystagn\fP دستور \fBYYSTAGN\fP، که ممکن است برای APIهای مختلف سفارشی‌سازی شده باشد. متغیرهای پشتیبانی‌شده: \fBYYSTAGN\fP، \fBnegative\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBtag\fP (متغیر برچسب که باید به‌روزرسانی شود). .TP .B \fBcode:yymtagn\fP دستور \fBYYMTAGN\fP، که ممکن است برای APIهای مختلف سفارشی‌سازی شده باشد. متغیرهای پشتیبانی‌شده: \fBYYMTAGN\fP (نگاشت به پیکربندی متناظر \fBre2c:\fP)، \fBtag\fP (متغیر برچسب که باید به‌روزرسانی شود). .TP .B \fBcode:yycopystag\fP دستور \fBYYCOPYSTAG\fP، که ممکن است برای APIهای مختلف سفارشی‌سازی شده باشد. متغیرهای پشتیبانی‌شده: \fBYYCOPYSTAG\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBlhs\fP، \fBrhs\fP (متغیرهای برچسب سمت چپ و راست عملیات رونوشت). .TP .B \fBcode:yycopymtag\fP دستور \fBYYCOPYMTAG\fP، که ممکن است برای APIهای مختلف سفارشی‌سازی شده باشد. متغیرهای پشتیبانی‌شده: \fBYYCOPYMTAG\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBlhs\fP، \fBrhs\fP (متغیرهای برچسب سمت چپ و راست عملیات رونوشت). .TP .B \fBcode:yygetaccept\fP دستور \fBYYGETACCEPT\fP، که ممکن است برای APIهای مختلف سفارشی‌سازی شده باشد. متغیرهای پشتیبانی‌شده: \fBYYGETACCEPT\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBvar\fP (نگاشت به پیکربندی \fBre2c:yyaccept\fP). .TP .B \fBcode:yysetaccept\fP دستور \fBYYSETACCEPT\fP، که ممکن است برای APIهای مختلف سفارشی‌سازی شده باشد. متغیرهای پشتیبانی‌شده: \fBYYSETACCEPT\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBvar\fP (نگاشت به پیکربندی \fBre2c:yyaccept\fP) و \fBval\fP (مقدار عددی قاعده پذیرفته‌شده). .TP .B \fBcode:yygetcond\fP دستور \fBYYGETCOND\fP، که ممکن است برای APIهای مختلف سفارشی‌سازی شده باشد. متغیرهای پشتیبانی‌شده: \fBYYGETCOND\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBvar\fP (نگاشت به پیکربندی \fBre2c:yycond\fP). .TP .B \fBcode:yysetcond\fP دستور \fBYYSETCOND\fP، که ممکن است برای APIهای مختلف سفارشی‌سازی شده باشد. متغیرهای پشتیبانی‌شده: \fBYYSETCOND\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBvar\fP (نگاشت به پیکربندی \fBre2c:yycond\fP) و \fBval\fP (شناسه عددی شرط). .TP .B \fBcode:yygetstate\fP دستور \fBYYGETSTATE\fP، که ممکن است برای APIهای مختلف سفارشی‌سازی شده باشد. متغیرهای پشتیبانی‌شده: \fBYYGETSTATE\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBvar\fP (نگاشت به پیکربندی \fBre2c:yystate\fP). .TP .B \fBcode:yysetstate\fP دستور \fBYYSETSTATE\fP، که ممکن است برای APIهای مختلف سفارشی‌سازی شده باشد. متغیرهای پشتیبانی‌شده: \fBYYSETSTATE\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBvar\fP (نگاشت به پیکربندی \fBre2c:yystate\fP) و \fBval\fP (شماره وضعیت). .TP .B \fBcode:yylessthan\fP دستور \fBYYLESSTHAN\fP، که ممکن است برای APIهای مختلف سفارشی‌سازی شده باشد. متغیرهای پشتیبانی‌شده: \fBYYLESSTHAN\fP، \fBYYCURSOR\fP، \fBYYLIMIT\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBneed\fP (تعداد واحدهای کد برای مقایسه در برابر آن). شرط: \fB\&.many\fP (درست اگر مقدار \fBneed\fP بیشتر از یک باشد). .TP .B \fBcode:yyend\fP عبارت \fBYYEND\fP، که ممکن است برای APIهای مختلف سفارشی‌سازی شده باشد. متغیرهای پشتیبانی‌شده: \fBYYEND\fP، \fBYYCURSOR\fP، \fBYYLIMIT\fP\&. .TP .B \fBcode:yybm_filter\fP شرطی که برای پالایش مقادیر \fByych\fP که توسط جدول \fByybm\fP پوشش داده نشده‌اند استفاده می‌شود (همراه با گزینه \fB\-\-bitmaps\fP به کار می‌رود). متغیر پشتیبانی‌شده: \fByych\fP (نگاشت به پیکربندی \fBre2c:yych\fP). .TP .B \fBcode:yybm_match\fP قالب بررسی جدول \fByybm\fP (تولید‌شده با گزینه \fB\-\-bitmaps\fP). متغیرهای پشتیبانی‌شده: \fByybm\fP، \fByych\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBoffset\fP (آفست در جدول \fByybm\fP که باید به \fByych\fP افزوده شود) و \fBmask\fP (ماسک بیتی که باید روی ورودی جدول اعمال شود تا مقدار بولی مورد نیاز برای بررسی به دست آید) .TP .B \fBcode:yytarget_filter\fP شرطی که برای پالایش مقادیر \fByych\fP که توسط جدول \fByytarget\fP پوشش داده نشده‌اند استفاده می‌شود (همراه با گزینه \fB\-\-computed\-gotos\fP به کار می‌رود). متغیر پشتیبانی‌شده: \fByych\fP (نگاشت به پیکربندی \fBre2c:yych\fP). .UNINDENT .sp در اینجا فهرستی از تمام متغیرهای سراسری مجاز در فایل‌های نحو آورده شده است: .INDENT 0.0 .TP .B \fBnl\fP یک خط جدید. .TP .B \fBindent\fP متغیری که هیچ کدی تولید نمی‌کند، اما اثر جانبی افزایش سطح تورفتگی را به همراه دارد..TP .B \fBdedent\fP متغیری که کدی تولید نمی‌کند، اما دارای اثر جانبی کاهش سطح تورفتگی است. .TP .B \fBtopindent\fP رشتهٔ تورفتگی برای دستور جاری. سطح تورفتگی توسط تولیدکنندهٔ کد ردیابی شده و به‌طور خودکار به‌روزرسانی می‌شود. .UNINDENT .sp در اینجا فهرستی از تمام شرط‌های سراسری مجاز در فایل‌های نحو آمده است: .INDENT 0.0 .TP .B \fB\&.api.simple\fP درست است اگر از API ساده استفاده شود (\fB\-\-api simple\fP یا \fBre2c:api = simple\fP). .TP .B \fB\&.api.generic\fP درست است اگر از API عمومی استفاده شود (\fB\-\-api generic\fP یا \fBre2c:api = generic\fP). .TP .B \fB\&.api.record\fP درست است اگر از API رکورد استفاده شود (\fB\-\-api record\fP یا \fBre2c:api = record\fP). .TP .B \fB\&.api_style.functions\fP درست است اگر از سبک API تابع‌گونه استفاده شود (\fBre2c:api\-style = functions\fP). .TP .B \fB\&.api_style.freeform\fP درست است اگر از سبک API با فرم آزاد استفاده شود (\fBre2c:api\-style = free\-form\fP). .TP .B \fB\&.case_ranges\fP درست است اگر ویژگی بازه‌های case فعال باشد (\fB\-\-case\-ranges\fP یا \fBre2c:case\-ranges = 1\fP). .TP .B \fB\&.cgoto.relative\fP درست است اگر شکل نسبی \fBgoto\fP محاسباتی استفاده شود (\fB\-\-computed\-gotos\-relative\fP یا \fBre2c:cgoto:relative = 1\fP). .TP .B \fB\&.code_model.goto_label\fP درست است اگر مدل کد مبتنی بر goto/label استفاده شود (\fB\-\-goto\-label\fP). .TP .B \fB\&.code_model.loop_switch\fP درست است اگر مدل کد مبتنی بر loop/switch استفاده شود (\fB\-\-loop\-switch\fP). .TP .B \fB\&.code_model.recursive_functions\fP درست است اگر مدل کد مبتنی بر توابع بازگشتی استفاده شود (\fB\-\-recursive\-function\fP). .TP .B \fB\&.date\fP درست است اگر اثرانگشت تولیدشده باید شامل تاریخ تولید باشد. .TP .B \fB\&.loop_label\fP درست است اگر حلقه‌های تولیدشده توسط re2swift باید برچسب داشته باشند (\fBre2c:label:yyloop\fP روی یک رشتهٔ غیرخالی تنظیم شده باشد). .TP .B \fB\&.monadic\fP درست است اگر کد تولیدشده باید به‌صورت مونادیک باشد (\fBre2c:monadic = 1\fP). این مورد تنها برای زبان‌های تابعی خالص کاربرد دارد. .TP .B \fB\&.start_conditions\fP درست است اگر شرایط شروع فعال باشند (\fB\-\-start\-conditions\fP). .TP .B \fB\&.storable_state\fP درست است اگر وضعیت قابل ذخیره‌سازی فعال باشد (\fB\-\-storable\-state\fP). .TP .B \fB\&.unsafe\fP درست است اگر re2swift برای تولید کد سریع‌تر باید از بلوک‌های \(dqunsafe\(dq استفاده کند (\fB\-\-unsafe\fP، \fBre2c:unsafe = 1\fP). این مورد تنها برای زبان‌هایی که دارای ویژگی \(dqunsafe\(dq هستند کاربرد دارد. .TP .B \fB\&.version\fP درست است اگر اثرانگشت تولیدشده باید شامل نسخهٔ re2swift باشد. .TP .B \fB\&.yyfill.enable\fP درست است اگر \fBYYFILL\fP فعال باشد (\fBre2c:yyfill:enable = 1\fP). .TP .B \fB\&.yyfn.throw\fP درست است اگر پیکربندی \fBre2c:yyfn:throw\fP با یک رشتهٔ غیرخالی تعریف شده باشد. .UNINDENT .UNINDENT .UNINDENT .SH "مدیریت پایان ورودی (HANDLING THE END OF INPUT)" .sp یکی از مشکلات اصلی برای تحلیل‌گر واژگانی (lexer)، دانستن زمان توقف است. چند شرط برای خاتمه وجود دارد: .INDENT 0.0 .IP \(bu 2 تحلیل‌گر واژگانی ممکن است با قاعده‌ای تطابق یابد (شامل قاعدهٔ پیش‌فرض \fB*\fP) و به یک وضعیت پایانی برسد .IP \(bu 2 تحلیل‌گر واژگانی ممکن است در تطبیق با هر قاعده‌ای ناموفق باشد و به یک وضعیت پیش‌فرض برسد .IP \(bu 2 تحلیل‌گر واژگانی ممکن است به پایان ورودی برسد .UNINDENT .sp دو شرط نخست، تحلیل‌گر واژگانی را به شیوه‌ای «طبیعی» خاتمه می‌دهند: تحلیل‌گر به وضعیتی بدون گذارهای خروجی می‌رسد و تطبیق به‌طور خودکار متوقف می‌شود. شرط سوم، پایان ورودی، متفاوت است: این حالت ممکن است در هر وضعیتی رخ دهد و تحلیل‌گر واژگانی باید قادر به مدیریت آن باشد. بررسی پایان ورودی، روند کار عادی تحلیل‌گر واژگانی را دچار وقفه کرده و شاخه‌های شرطی را به برنامهٔ تولیدشده می‌افزاید؛ بنابراین لازم است تعداد چنین بررسی‌هایی به حداقل برسد. re2swift از چند روش مختلف برای مدیریت پایان ورودی پشتیبانی می‌کند. انتخاب روش مورد استفاده به پیچیدگی عبارات منظم، نیاز به بافرسازی، ملاحظات کارایی و سایر عوامل بستگی دارد. در ادامه فهرستی از این روش‌ها آمده است: .INDENT 0.0 .IP \(bu 2 \fBنویسهٔ نگهبان (Sentinel).\fP این روش نیاز به بررسی‌های پایان ورودی را به‌کلی برطرف می‌کند. این روش ساده و کارآمد است، اما محدود به مواردی است که یک نویسهٔ «نگهبان» طبیعی وجود داشته باشد که هرگز در ورودی معتبر رخ ندهد. این نویسه ممکن است همچنان در ورودی نامعتبر رخ دهد، اما نباید توسط عبارات منظم مجاز دانسته شود، مگر شاید به عنوان آخرین نویسهٔ یک قاعده. نویسهٔ نگهبان به انتهای ورودی ضمیمه شده و به عنوان یک سیگنال توقف عمل می‌کند: زمانی که تحلیل‌گر واژگانی این نویسه را بخواند، یا یک خطای نحوی است یا پایان ورودی. در هر دو حالت، تحلیل‌گر واژگانی باید متوقف شود. این روش زمانی استفاده می‌شود که \fBYYFILL\fP با \fBre2c:yyfill:enable = 0;\fP غیرفعال شده و \fBre2c:eof\fP مقدار پیش‌فرض \fB\-1\fP را داشته باشد. .nf .fi .sp .IP \(bu 2 \fBنویسهٔ نگهبان به همراه بررسی کران‌ها (Sentinel with bounds checks).\fP این روش همگانی (generic) است: امکان پردازش هر ورودی را بدون محدودیت روی عبارات منظم فراهم می‌کند. ایدهٔ کار کاهش تعداد بررسی‌های پایان ورودی با انجام آن‌ها تنها روی نویسه‌هایی خاص است. مشابه روش «نگهبان»، یکی از نویسه‌ها به عنوان «نگهبان» انتخاب شده و به انتهای ورودی ضمیمه می‌شود. با این حال، هیچ محدودیتی در مورد محل وقوع نویسهٔ نگهبان وجود ندارد (در واقع هر نویسه‌ای می‌تواند به عنوان نگهبان انتخاب شود). زمانی که تحلیل‌گر واژگانی این نویسه را می‌خواند، علاوه بر آن یک بررسی کران انجام می‌دهد. اگر موقعیت فعلی در محدودهٔ مجاز باشد، تحلیل‌گر واژگانی تطبیق را از سر گرفته و با نویسهٔ نگهبان مانند یک نویسهٔ معمولی رفتار می‌کند. در غیر این صورت، \fBYYFILL\fP را فراخوانی می‌کند (مگر اینکه غیرفعال شده باشد). اگر ورودی بیشتری ارائه شود، تحلیل‌گر واژگانی نویسهٔ پایانی را مجدداً تطبیق داده و به‌گونه‌ای ادامه می‌دهد که گویی نگهبان اصلاً وجود نداشته است. در غیر این صورت، باید پایان واقعی ورودی باشد و تحلیل‌گر واژگانی متوقف می‌شود. این روش زمانی استفاده می‌شود که \fBre2c:eof\fP مقداری غیرمنفی داشته باشد (باید روی مقدار عددیِ نویسهٔ نگهبان تنظیم شود). استفاده از \fBYYFILL\fP اختیاری است. .nf .fi .sp .IP \(bu 2 \fBبررسی کران‌ها به همراه لایه‌گذاری (Bounds checks with padding).\fP این روش همگانی است و ممکن است از روش «نگهبان به همراه بررسی کران‌ها» سریع‌تر باشد، اما پیچیده‌تر نیز هست. ایدهٔ کار این است که وضعیت‌های DFA به مؤلفه‌های قویاً همبند (SCCها) افراز شوند و برای هر SCC یک بررسی منفرد به اندازهٔ کافی نویسه تولید شود تا طولانی‌ترین مسیر بدون حلقه در این SCC را پوشش دهد. این کار تعداد بررسی‌ها را کاهش می‌دهد، اما مشکلی با تکواژهای (lexemes) کوتاه در انتهای ورودی ایجاد می‌کند، زیرا بررسی به نویسه‌های کافی برای پوشش طولانی‌ترین تکواژ نیاز دارد. این مشکل را می‌توان با لایه‌گذاری ورودی با چند نویسهٔ ساختگی که پسوند معتبری برای یک تکواژ تشکیل نمی‌دهند (تا تحلیل‌گر واژگانی نتواند با آن‌ها تطبیق یابد) برطرف کرد. طول لایه‌گذاری باید \fBYYMAXFILL\fP باشد که با یک بلوک \fBmax\fP تولید می‌شود. اگر ورودی کافی وجود نداشته باشد، تحلیل‌گر واژگانی \fBYYFILL\fP را فراخوانی می‌کند که باید حداقل تعداد نویسه‌های لازم را تأمین کند یا بازنگردد. این روش در صورتی به کار می‌رود که \fBYYFILL\fP فعال باشد و \fBre2c:eof\fP برابر \fB\-1\fP باشد (این پیکربندی پیش‌فرض است). .nf .fi .sp .IP \(bu 2 \fBبررسی‌های سفارشی (Custom checks).\fP رابط Generic API به کاربر اجازه می‌دهد عملیات پایه‌ای مانند خواندن یک نویسه را رونویسی کند، که امکان گنجاندن بررسی‌های پایان ورودی را به عنوان بخشی از آن‌ها فراهم می‌سازد. این رویکرد خطازاست و باید با احتیاط استفاده شود. برای استفاده از یک روش سفارشی، API عمومی را با \fB\-\-api custom\fP یا \fBre2c:api = custom;\fP فعال کرده و بررسی‌های پیش‌فرض کران‌ها را با \fBre2c:yyfill:enable = 0;\fP یا \fBre2c:yyfill:check = 0;\fP غیرفعال کنید. .UNINDENT .sp زیربخش‌های زیر شامل مثالی از هر روش هستند..SS نگهبان (Sentinel) .sp این مثال از یک نویسه نگهبان (sentinel character) برای مدیریت پایان ورودی استفاده می‌کند. این برنامه واژه‌های جداشده با فاصله را در یک رشته پایان‌یافته با null شمارش می‌کند. نویسه نگهبان null است: آخرین نویسه از هر رشته ورودی است، و در هیچ‌یک از قواعد در میانه یک لکسم (lexeme) مجاز دانسته نشده است (به‌ویژه، در بازه‌های نویسه‌ای که نادیده‌گرفتن آن آسان است گنجانده نشده است). اگر یک null در میانه رشته رخ دهد، یک خطای نحو (syntax error) است و لکسر با قاعده پیش‌فرض \fB*\fP تطابق می‌یابد، اما داده‌ای فراتر از پایان ورودی را نخواهد خواند و دچار فروپاشی (crash) نخواهد شد (از هشدار \fI\%\-Wsentinel\-in\-midrule\fP و پیکربندی \fBre2c:sentinel\fP برای راستی‌آزمایی این مورد استفاده کنید). پیکربندی \fBre2c:yyfill:enable = 0;\fP از تولید بررسی‌های محدوده (bounds checks) و فراخوانی‌های \fBYYFILL\fP جلوگیری می‌کند. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2swift $INPUT \-o $OUTPUT // Expects a null\-terminated string. func lex(_ yyinput: UnsafePointer) \-> Int? { var yycursor = 0, count = 0 loop: while true { /*!re2c re2c:yyfill:enable = 0; [a\-z]+ { count += 1 continue loop } [ ]+ { continue loop } [\ex00] { return count } * { return nil } */ } } func test(_ str: StaticString, _ expect: Int?) { assert(lex(str.utf8Start) == expect) } test(\(dq\(dq, 0) test(\(dqone two three\(dq, 3) test(\(dqf0ur\(dq, nil) .ft P .fi .UNINDENT .UNINDENT .SS نگهبان با بررسی‌های محدوده (Sentinel with bounds checks) .sp این مثال از نویسه نگهبان همراه با بررسی‌های محدوده برای مدیریت پایان ورودی استفاده می‌کند (این روش در نسخه 1.2 اضافه شد). این برنامه رشته‌های محصور در تک‌نقل‌قول (single\-quoted) که با فاصله از هم جدا شده‌اند را می‌شمارد. نویسه نگهبان null است که با پیکربندی \fBre2c:eof = 0;\fP تعیین می‌شود. همانند روش \fI\%sentinel\fP، نویسه null آخرین نویسه هر رشته ورودی است، اما در میانه یک قاعده نیز مجاز است (برای مثال، \fB\(aqaaa\e0aa\(aq\e0\fP ورودی معتبری است، اما \fB\(aqaaa\e0\fP یک خطای نحوی است). بررسی‌های محدوده در هر حالتی که یک نویسه ورودی را تطبیق می‌دهد تولید می‌شوند، اما دامنه آن‌ها به شاخه‌ای که null را مدیریت می‌کند محدود است. بررسی‌های محدوده با API عمومی به صورت \fBYYLIMIT <= YYCURSOR\fP یا \fBYYLESSTHAN(1)\fP هستند. اگر شرط بررسی برقرار (true) باشد، لکسر به پایان ورودی رسیده است و باید متوقف شود (از آنجا که ورودی در یک بافر جای می‌گیرد، \fBYYFILL\fP با \fBre2c:yyfill:enable = 0;\fP غیرفعال شده است؛ برای مشاهده مثالی که از \fBYYFILL\fP استفاده می‌کند، به بخش \fI\%YYFILL with sentinel\fP مراجعه کنید). رسیدن به پایان ورودی سه حالت را پیش می‌آورد: اگر لکسر در حالت اولیه باشد، با قاعده پایان ورودی \fB$\fP مطابقت می‌یابد؛ در غیر این صورت ممکن است به یک قاعده تطبیق‌یافته قبلی (از جمله قاعده پیش‌فرض \fB*\fP) بازگردد یا به یک حالت پیش‌فرض برود، که موجب هشدار \fI\%\-Wundefined\-control\-flow\fP می‌شود\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2swift $INPUT \-o $OUTPUT // Expects a null\-terminated string. func lex(_ yyinput: UnsafePointer, _ length: Int) \-> Int? { var yycursor = 0, yylimit = length, yymarker = 0 var count = 0 loop: while true { /*!re2c re2c:eof = 0; re2c:yyfill:enable = 0; str = [\(aq] ([^\(aq\e\e] | [\e\e][^])* [\(aq]; str { count += 1 continue loop } [ ]+ { continue loop } * { return nil } $ { return count } */ } } func test(_ str: StaticString, _ expect: Int?) { assert(lex(str.utf8Start, str.utf8CodeUnitCount) == expect) } test(\(dq\(dq, 0); test(\(dq\(aqqu\e0tes\(aq \(aqare\(aq \(aqfine: \e\e\(aq\(aq \(dq, 3); test(\(dq\(aqunterminated\e\e\(aq\(dq, nil); .ft P .fi .UNINDENT .UNINDENT .SS بررسی‌های محدوده با پدینگ (Bounds checks with padding) .sp این مثال از بررسی‌های محدوده به همراه پدینگ (padding) برای مدیریت پایان ورودی استفاده می‌کند (این روش به‌طور پیش‌فرض فعال است). این برنامه رشته‌های محصور در تک‌نقل‌قول که با فاصله جدا شده‌اند را می‌شمارد. یک پدینگ متشکل از نویسه‌های null به تعداد \fBYYMAXFILL\fP به انتهای ورودی افزوده شده است، که در آن مقدار \fBYYMAXFILL\fP به‌طور خودکار توسط یک بلوک \fBmax\fP تولید می‌شود. الزامی به استفاده از null برای پدینگ وجود ندارد \-\-\- تا زمانی که نویسه‌ها پسوند معتبری برای یک لکسم تشکیل ندهند، می‌توان از هر نویسه‌ای استفاده کرد (در این مثال، پدینگ نباید شامل تک‌نقل‌قول باشد، چرا که ممکن است با پسوند یک رشته محصور در تک‌نقل‌قول اشتباه گرفته شود). یک قاعده توقف (\(dqstop\(dq) وجود دارد که با نخستین نویسه پدینگ (null) تطبیق یافته و لکسر را خاتمه می‌دهد (توجه داشته باشید که بررسی می‌کند آیا null در ابتدای پدینگ قرار دارد یا خیر، در غیر این صورت یک خطای نحوی است). بررسی‌های محدوده تنها در برخی از حالت‌ها تولید می‌شوند که توسط مؤلفه‌های قویاً همبند خودکار (اتوماتون) زیرین تعیین می‌گردند. بررسی‌ها با API عمومی به صورت \fB(YYLIMIT \- YYCURSOR) < n\fP یا \fBYYLESSTHAN(n)\fP هستند، که در آن \fBn\fP حداقل تعداد نویسه‌های مورد نیاز برای ادامه کار لکسر است (این همچنین بدان معناست که بررسی محدوده بعدی حداکثر در \fBn\fP نویسه دیگر رخ خواهد داد). اگر شرط بررسی برقرار باشد، لکسر به پایان ورودی رسیده است و \fBYYFILL(n)\fP را فراخوانی می‌کند که یا باید حداقل \fBn\fP نویسه ورودی را فراهم کند یا بازگشتی نداشته باشد. در این مثال \fBYYFILL\fP همیشه ناموفق است و لکسر را با یک خطا متوقف می‌کند (که مشکلی نیست، زیرا ورودی درون یک بافر جا می‌شود). برای مثالی که بافر ورودی را با استفاده از \fBYYFILL\fP دوباره پر می‌کند، به بخش \fI\%YYFILL with padding\fP مراجعه کنید\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2swift $INPUT \-o $OUTPUT /*!max:re2c*/ func lex(_ str: UnsafeBufferPointer) \-> Int? { let length = str.count // Make a copy of the string with YYMAXFILL zeroes at the end. let yyinput = ContiguousArray(str) + repeatElement(0, count: yymaxfill) var yycursor = 0, yylimit = length + yymaxfill var count = 0 loop: while true { /*!re2c re2c:YYFILL = \(dqreturn nil\(dq; str = [\(aq] ([^\(aq\e\e] | [\e\e][^])* [\(aq]; str { count += 1 continue loop } [\ex00] { // Check that it\(aqs the sentinel, not some unexpected null. if yycursor \- 1 == length { return count } else { return nil } } [ ]+ { continue loop } * { return nil } */ } } func test(_ str: StaticString, _ expect: Int?) { str.withUTF8Buffer { assert(lex($0) == expect) } } test(\(dq\(dq, 0) test(\(dq\(aqqu\e0tes\(aq \(aqare\(aq \(aqfine: \e\e\(aq\(aq \(dq, 3) test(\(dq\(aqunterminated\e\e\(aq\(dq, nil) test(\(dq\(aqunexpected \e0 null\e\e\(aq\(dq, nil) .ft P .fi .UNINDENT .UNINDENT.SS "بررسی‌های سفارشی (Custom checks)" .sp این مثال از یک روش سفارشی مدیریت پایان ورودی (end\-of\-input) بر پایهٔ API عمومی (generic API) استفاده می‌کند. برنامه رشته‌های محصور در نقل‌قول تکی (single-quoted) را که با فاصله از هم جدا شده‌اند می‌شمارد. این برنامه مشابه مثال \fI\%sentinel\fP است، با این تفاوت که ورودی با نویسهٔ تهی پایان نیافته است (null\-terminated نیست). برای جبران نبود نویسهٔ نگهبان (sentinel) در انتهای ورودی، \fBYYPEEK\fP بازتعریف شده است تا پیش از خواندن نویسهٔ بعدی ورودی، یک بررسی محدوده (bounds check) انجام دهد. این روش ناکارآمد است زیرا بررسی‌ها بسیار مکرر انجام می‌شوند. اگر شرط بررسی برقرار نباشد، \fBYYPEEK\fP نویسهٔ واقعی را برمی‌گرداند؛ در غیر این صورت یک نویسهٔ نگهبان ساختگی بازمی‌گرداند. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2swift $INPUT \-o $OUTPUT import Foundation func lex(_ str: Data) \-> Int? { var cursor = 0, limit = str.count var count = 0 loop: while true { /*!re2c re2c:api = generic; re2c:yyfill:enable = 0; re2c:YYSKIP = \(dqcursor += 1\(dq; re2c:YYPEEK = \(dqcursor < limit ? str[cursor] : 0\(dq; // fake null [a\-z]+ { count += 1 continue loop } [\ex00] { return count } [ ]+ { continue loop } * { return nil} */ } } func test(_ str: String, _ expect: Int?) { // For the sake of example create a string without terminating null. assert(lex(Data(str.utf8)) == expect) } test(\(dq\(dq, 0) test(\(dqone two three \(dq, 3) test(\(dqf0ur\(dq, nil) .ft P .fi .UNINDENT .UNINDENT .SH "پر کردن مجدد بافر (BUFFER REFILLING)" .sp نیاز به بافرسازی زمانی رخ می‌دهد که ورودی را نتوان به‌طور یک‌جا در حافظه نگاشت کرد: یا بیش از حد بزرگ است، یا به صورت جریانی دریافت می‌شود (مانند خواندن از یک سوکت). تکنیک معمول در چنین مواردی، تخصیص یک بافر حافظه با اندازهٔ ثابت و پردازش ورودی در تکه‌هایی (chunks) است که در بافر جا می‌شوند. هنگامی که تکهٔ فعلی پردازش شد، به بیرون منتقل شده و داده‌های جدید وارد می‌شوند. در عمل این موضوع تا حدی پیچیده‌تر است، زیرا وضعیت تحلیل‌گر لغوی (lexer) تنها از یک موقعیت ورودی تشکیل نشده، بلکه شامل مجموعه‌ای از موقعیت‌های مرتبط است: .INDENT 0.0 .IP \(bu 2 مکان‌نما (cursor): نویسهٔ بعدی ورودی برای خواندن (\fBYYCURSOR\fP در API اشاره‌گر C یا \fBYYSKIP\fP/\fBYYPEEK\fP در generic API) .IP \(bu 2 حد (limit): موقعیتِ پس از آخرین نویسهٔ موجود ورودی (\fBYYLIMIT\fP در API اشاره‌گر C، یا مدیریت‌شده به‌طور ضمنی توسط \fBYYLESSTHAN\fP در generic API) .IP \(bu 2 نشانه‌گر (marker): موقعیت تازه‌ترین تطابق، در صورت وجود (\fBYYMARKER\fP در API پیش‌فرض یا \fBYYBACKUP\fP/\fBYYRESTORE\fP در generic API) .IP \(bu 2 توکن (token): ابتدای لکسم (lexeme) فعلی (در re2swift API ضمنی است، چرا که برای عملکرد عادی لکسر نیازی به آن نیست و می‌تواند توسط کاربر تعریف و به‌روزرسانی شود) .IP \(bu 2 نشانه‌گر زمینه (context marker): موقعیت زمینهٔ انتهایی (\fBYYCTXMARKER\fP در API اشاره‌گر C یا \fBYYBACKUPCTX\fP/\fBYYRESTORECTX\fP در generic API) .IP \(bu 2 متغیرهای برچسب (tag variables): موقعیت‌های زیرتطابق (تعریف‌شده با بلوک‌های \fBstags\fP و \fBmtags\fP و توابع اولیهٔ generic API شامل \fBYYSTAGP\fP/\fBYYSTAGN\fP/\fBYYMTAGP\fP/\fBYYMTAGN\fP) .UNINDENT .sp همهٔ این موارد در هر حالتی به کار نمی‌روند، اما در صورت استفاده، باید توسط \fBYYFILL\fP به‌روزرسانی شوند. تمام موقعیت‌های فعال در بازهٔ بین token و cursor قرار دارند؛ بنابراین هر چیزی میان ابتدای بافر و token را می‌توان دور ریخت، بازهٔ token تا limit باید به ابتدای بافر منتقل شود، و فضای خالی انتهای بافر باید با داده‌های جدید پر شود. برای جلوگیری از فراخوانی‌های مکرر \fBYYFILL\fP، بهتر است تا حد امکان نویسه‌های ورودی بیشتری پر شود (حتی اگر نویسه‌های کمتری برای از سرگیری لکسر کافی باشد). جزئیات پیاده‌سازی \fBYYFILL\fP بسته به روش مدیریت EOF مورداستفاده کمی متفاوت است: حالت قاعدهٔ EOF تا حدی ساده‌تر از حالت بررسی محدوده همراه با لایه‌گذاری (padding) است. همچنین توجه داشته باشید که اگر گزینهٔ \fB\-f \-\-storable\-state\fP استفاده شود، \fBYYFILL\fP معناشناسی کمی متفاوتی خواهد داشت (که در بخش مربوط به وضعیت قابل ذخیره شرح داده شده است). .SS "YYFILL با نویسهٔ نگهبان (YYFILL with sentinel)" .sp اگر از قاعدهٔ EOF استفاده شود، \fBYYFILL\fP یک سازوکار اولیّهٔ شبه‌تابع است که هیچ آرگومانی نمی‌پذیرد و مقداری بازمی‌گرداند که با صفر مقایسه می‌شود. فراخوانی \fBYYFILL\fP با شرط \fBYYLIMIT <= YYCURSOR\fP در API اشاره‌گر C و \fBYYLESSTHAN()\fP در generic API تحریک می‌شود. یک مقدار بازگشتی غیرصفر به این معنی است که \fBYYFILL\fP شکست خورده است. یک فراخوانی موفق \fBYYFILL\fP باید حداقل یک نویسه را تامین کرده و موقعیت‌های ورودی را بر این اساس تنظیم کند. Limit همیشه باید روی یک واحد پس از آخرین موقعیت ورودی در بافر تنظیم شود، و نویسهٔ موجود در موقعیت limit باید نماد نگهبان تعیین‌شده توسط پیکربندی \fBre2c:eof\fP باشد. تصاویر زیر مکان‌های نسبی موقعیت‌های ورودی در بافر را قبل و بعد از فراخوانی \fBYYFILL\fP نشان می‌دهند (نماد نگهبان با \fB#\fP مشخص شده است، و تصویر دوم حالتی را نشان می‌دهد که ورودی کافی برای پر کردن کل بافر وجود ندارد). .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C <\-\- shift \-\-> >\-A\-\-\-\-\-\-\-\-\-\-\-\-B\-\-\-\-\-\-\-\-\-C\-\-\-\-\-\-\-\-\-\-\-\-D#\-\-\-\-\-\-\-\-\-\-\-E\-> buffer token marker limit, cursor >\-A\-\-\-\-\-\-\-\-\-\-\-\-B\-\-\-\-\-\-\-\-\-C\-\-\-\-\-\-\-\-\-\-\-\-D\-\-\-\-\-\-\-\-\-\-\-\-E#\-> buffer, marker cursor limit token <\-\- shift \-\-> >\-A\-\-\-\-\-\-\-\-\-\-\-\-B\-\-\-\-\-\-\-\-\-C\-\-\-\-\-\-\-\-\-\-\-\-D#\-\-E (EOF) buffer token marker limit, cursor >\-A\-\-\-\-\-\-\-\-\-\-\-\-B\-\-\-\-\-\-\-\-\-C\-\-\-\-\-\-\-\-\-\-\-\-D\-\-\-E#........ buffer, marker cursor limit token .ft P .fi .UNINDENT .UNINDENT .sp در اینجا مثالی از برنامه‌ای آورده شده است که فایل ورودی \fBinput.txt\fP را در تکه‌های ۴۰۹۶ بایتی می‌خواند و از قاعدهٔ EOF استفاده می‌کند. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2swift $INPUT \-o $OUTPUT import Foundation struct Input { static let bufferSize = 4095 var file: FileHandle var yyinput = ContiguousArray(repeating: 0, count: Self.bufferSize + 1) var yylimit = Self.bufferSize var yycursor = Self.bufferSize var yymarker = Self.bufferSize var token = \-1 var eof = false } extension Input { mutating func lex() \-> Int? { var count = 0 loop: while true { self.token = self.yycursor /*!re2c re2c:api = record; re2c:eof = 0; re2c:yyrecord = \(dqself\(dq; re2c:YYFILL = \(dqself.fill() == .ok\(dq; str = [\(aq] ([^\(aq\e\e] | [\e\e][^])* [\(aq]; str { count += 1 continue loop } [ ]+ { continue loop } $ { return count } * { return nil } */ } } mutating func fill() \-> FillStatus { guard !self.eof else { return .eof } let shift = self.token let used = self.yylimit \- self.token let free = Self.bufferSize \- used // Error: Lexeme too long. In the real world we can reallocate a larger buffer. if self.token < 1 { return .longLexeme } // Shift buffer contents, discarding everything up to the current lexeme. self.yyinput.replaceSubrange(.. <\-\- need \-\-> >\-A\-\-\-\-\-\-\-\-\-\-\-\-B\-\-\-\-\-\-\-\-\-C\-\-\-\-\-D\-\-\-\-\-\-\-E\-\-\-F\-\-\-\-\-\-\-\-G\-> buffer token marker cursor limit >\-A\-\-\-\-\-\-\-\-\-\-\-\-B\-\-\-\-\-\-\-\-\-C\-\-\-\-\-D\-\-\-\-\-\-\-E\-\-\-F\-\-\-\-\-\-\-\-G\-> buffer, marker cursor limit token <\-\- shift \-\-> <\-\- need \-\-> >\-A\-\-\-\-\-\-\-\-\-\-\-\-B\-\-\-\-\-\-\-\-\-C\-\-\-\-\-D\-\-\-\-\-\-\-E\-F (EOF) buffer token marker cursor limit >\-A\-\-\-\-\-\-\-\-\-\-\-\-B\-\-\-\-\-\-\-\-\-C\-\-\-\-\-D\-\-\-\-\-\-\-E\-F############### buffer, marker cursor limit token <\- YYMAXFILL \-> .ft P .fi .UNINDENT .UNINDENT .sp در اینجا مثالی از برنامه‌ای آمده است که فایل ورودی \fBinput.txt\fP را در قطعات ۴۰۹۶ بایتی می‌خواند و از بررسی محدوده‌ها (bounds\-checking) به همراه لایه‌گذاری استفاده می‌کند. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2swift $INPUT \-o $OUTPUT import Foundation /*!max:re2c*/ struct Input { static let bufferSize = 4096 \- yymaxfill var file: FileHandle var yyinput = ContiguousArray(repeating: 0, count: Self.bufferSize + yymaxfill) var yylimit = Self.bufferSize var yycursor = Self.bufferSize var token = \-1 var eof = false } extension Input { mutating func lex() \-> Int? { var count = 0 loop: while true { self.token = self.yycursor /*!re2c re2c:api = record; re2c:yyrecord = \(dqself\(dq; re2c:YYFILL = \(dqif self.fill(@@) != .ok { return nil }\(dq; str = [\(aq] ([^\(aq\e\e] | [\e\e][^])* [\(aq]; [\ex00] { // Check that it is the sentinel, not some unexpected null. return self.token == self.yylimit \- yymaxfill ? count : nil; } str { count += 1 continue loop } [ ]+ { continue loop } * { return nil } */ } } mutating func fill(_ need: Int) \-> FillStatus { guard !self.eof else { return .eof } let shift = self.token let used = self.yylimit \- self.token let free = Self.bufferSize \- used // Error: Lexeme too long. In the real world we can reallocate a larger buffer. if self.token < need { return .longLexeme } // Shift buffer contents, discarding everything up to the current lexeme. self.yyinput.replaceSubrange(.. add zero padding // so that the lexer can access characters at the end of buffer. self.yylimit += read if read < free { self.eof = true self.yyinput.withUnsafeMutableBytes { _ = memset($0.baseAddress! + self.yylimit, 0, yymaxfill) } self.yylimit += yymaxfill } return .ok } enum FillStatus { case ok, eof, longLexeme } } let fileName = \(dqinput\(dq let content = \(dq\(aqqu\e0tes\(aq \(aqare\(aq \(aqfine: \e\e\(aq\(aq \(dq; // Prepare input file: a few times the size of the buffer, // containing strings with zeroes and escaped quotes. guard FileManager.default.createFile( atPath: fileName, contents: Data(String(repeating: content, count: Input.bufferSize).utf8) ) else { fatalError(\(dqfailed to write file \e\(dq\e(fileName)\e\(dq\(dq) } // Number of quoted strings written to file let count = 3 * Input.bufferSize // Initialize lexer state // This immediately triggers YYFILL, as the check \(gain.yycursor < in.yylimit\(ga fails. guard let file = FileHandle(forReadingAtPath: fileName) else { throw NSError(domain: NSCocoaErrorDomain, code: CocoaError.fileReadNoSuchFile.rawValue) } var \(gain\(ga = Input(file: file) // Run the lexer assert(\(gain\(ga.lex() == count) // Cleanup: remove input file try file.close() try FileManager.default.removeItem(atPath: fileName) .ft P .fi .UNINDENT .UNINDENT.SH "ویژگی‌ها (FEATURES)" .SS "بلوک‌های چندگانه (Multiple blocks)" .sp گاهی اوقات لازم است چندین تحلیل‌گر لغوی (lexer) مرتبط با یکدیگر داشته باشیم (برای مثال، اگر یک ماشین حالت سطح بالا وجود داشته باشد که بین حالت‌های مختلف لکسر گذار انجام می‌دهد). این کار می‌تواند با استفاده از چندین بلوک به‌هم‌پیوستهٔ re2swift پیاده‌سازی شود. گزینهٔ دیگر استفاده از \fI\%شرایط شروع (start conditions)\fP\& است. .sp پیاده‌سازی اتصالات بین بلوک‌ها به زبان مقصد بستگی دارد. در زبان‌هایی که دستور \fBgoto\fP دارند (مانند C/C++ و Go) می‌توان همهٔ بلوک‌ها را در یک تابع قرار داد، به طوری که پیشوند هر یک از آن‌ها یک برچسب باشد. گذار از یک بلوک به بلوک دیگر یک \fBgoto\fP ساده است\&. در زبان‌هایی که \fBgoto\fP ندارند (مانند Rust)، لازم است از یک حلقه به همراه switch روی متغیر حالت استفاده شود، مشابه حلقه/switch مربوط به \fByystate\fP که توسط re2swift تولید می‌شود؛ یا اینکه هر بلوک درون یک تابع قرار گرفته و از فراخوانی توابع استفاده گردد. .sp مثال زیر از چندین بلوک برای تجزیهٔ اعداد دودویی (binary)، هشت‌هشتی (octal)، ده‌دهی (decimal) و شانزده‌شانزدهی (hexadecimal) استفاده می‌کند. هر مبنا بلوک مخصوص به خود را دارد. بلوک اولیه مبنا را تعیین کرده و کنترل را به سایر بلوک‌ها هدایت می‌کند. پیکربندی‌های مشترک در یک بلوک مجزا در ابتدای برنامه تعریف شده‌اند؛ این پیکربندی‌ها توسط سایر بلوک‌ها به ارث برده می‌شوند. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2swift $INPUT \-o $OUTPUT func parseUInt32(_ yyinput: UnsafePointer) \-> UInt32? { var yycursor = 0, yymarker = 0 /*!re2c re2c:yyfill:enable = 0; \(dq0b\(dq / [01] { return parseBin() } \(dq0\(dq { return parseOct() } \(dq\(dq / [1\-9] { return parseDec() } \(dq0x\(dq / [0\-9a\-fA\-F] { return parseHex() } * { return nil } */ func add(_ accum: inout UInt64, _ charOrigin: UnicodeScalar, _ base: UInt64, _ offset: UInt64 = 0) { let digit = yyinput[yycursor \- 1] \- UInt8(ascii: charOrigin) accum = min(accum * base + UInt64(digit) + offset, UInt64(UInt32.max) + 1) } func parseBin() \-> UInt32? { var accum: UInt64 = 0 parse: while true { /*!re2c [01] { add(&accum, \(dq0\(dq, 2); continue parse } * { return UInt32(exactly: accum) } */ } } func parseOct() \-> UInt32? { var accum: UInt64 = 0 parse: while true { /*!re2c [0\-7] { add(&accum, \(dq0\(dq, 8); continue parse } * { return UInt32(exactly: accum) } */ } } func parseDec() \-> UInt32? { var accum: UInt64 = 0 parse: while true { /*!re2c [0\-9] { add(&accum, \(dq0\(dq, 10); continue parse } * { return UInt32(exactly: accum) } */ } } func parseHex() \-> UInt32? { var accum: UInt64 = 0 parse: while true { /*!re2c [0\-9] { add(&accum, \(dq0\(dq, 16); continue parse } [a\-f] { add(&accum, \(dqa\(dq, 16, 10); continue parse } [A\-F] { add(&accum, \(dqA\(dq, 16, 10); continue parse } * { return UInt32(exactly: accum) } */ } } } assert(parseUInt32(\(dq\(dq) == nil) assert(parseUInt32(\(dq1234567890\(dq) == 1234567890) assert(parseUInt32(\(dq0b1101\(dq) == 13) assert(parseUInt32(\(dq0x7Fe\(dq) == 2046) assert(parseUInt32(\(dq0644\(dq) == 420) assert(parseUInt32(\(dq9999999999\(dq) == nil) .ft P .fi .UNINDENT .UNINDENT .SS "شرایط شروع (Start conditions)" .sp شرایط شروع با گزینهٔ \fB\-\-start\-conditions\fP فعال می‌شوند. آن‌ها روشی برای کدگذاری چندین خودکارهٔ (اتوماتای) به‌هم‌پیوسته درون یک بلوک re2swift یکسان فراهم می‌کنند. .sp هر شرط متناظر با یک خودکارهٔ منفرد است و یک نام یکتا دارد که توسط کاربر مشخص می‌شود، و همچنین یک شمارهٔ داخلی یکتا که توسط re2swift تعریف می‌گردد\&. این شماره‌ها برای جابه‌جایی میان شرایط به کار می‌روند: کد تولیدشده از پیش‌ساخته‌های \fBYYGETCOND\fP و \fBYYSETCOND\fP برای دریافت شرط کنونی یا تنظیم آن به شمارهٔ داده‌شده استفاده می‌کند. برای تولید شناسه‌های عددی شرایط، از بلوک \fBconditions\fP، گزینهٔ \fB\-\-header\fP یا پیکربندی \fBre2c:header\fP استفاده کنید. پیکربندی \fBre2c:cond:enumprefix\fP پیشوند شناسه‌های تولیدشده را مشخص می‌کند. .sp در حالت شرط، هر قاعده باید دارای پیشوندی از فهرستی از نام‌های شرایط جداشده با کاما درون قلاب‌های شکسته، یا نویسهٔ عام \fB<*>\fP برای نشان دادن همهٔ شرایط باشد. نحو قواعد به‌صورت زیر گسترش می‌یابد: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .TP .B \fB< condition\-list > regular\-expression code\fP قاعده‌ای که در هر شرط موجود در \fBcondition\-list\fP ادغام می‌شود\&. این قاعده با \fBregular\-expression\fP مطابقت می‌یابد و \fBcode\fP مرتبط را اجرا می‌کند\&. .TP .B \fB< condition\-list > regular\-expression => condition code\fP قاعده‌ای که در هر شرط موجود در \fBcondition\-list\fP ادغام می‌شود\&. این قاعده با \fBregular\-expression\fP مطابقت می‌یابد، شرط کنونی را به \fBcondition\fP تنظیم می‌کند و \fBcode\fP مرتبط را اجرا می‌کند\&. .TP .B \fB< condition\-list > regular\-expression :=> condition\fP قاعده‌ای که در هر شرط موجود در \fBcondition\-list\fP ادغام می‌شود\&. این قاعده با \fBregular\-expression\fP مطابقت می‌یابد و بلافاصله به \fBcondition\fP گذار می‌کند (هیچ عمل معنایی وجود ندارد). .TP .B \fB< condition\-list > !action code\fP قاعده‌ای که \fBcode\fP را به مکان تعیین‌شده توسط \fBaction\fP در هر شرط موجود در \fBcondition\-list\fP پیوند می‌دهد (برای انواع مختلف کنش‌ها به بخش \fI\%actions\fP مراجعه کنید). .TP .B \fB code\fP قاعده‌ای که \fBcode\fP را به ابتدای کنش‌های معناییِ تمام قواعد برای هر شرط در \fBcondition\-list\fP اضافه می‌کند\&. این نحو منسوخ شده است و در عوض باید از کنش \fB!pre_rule\fP استفاده شود (دقیقاً همان کار را انجام می‌دهد). .TP .B \fB< > code\fP قاعده‌ای که یک شرط ورودی ویژه با شمارهٔ صفر و نام \fB\(dq0\(dq\fP ایجاد می‌کند که قبل از پرش به سایر شرایط، \fBcode\fP را اجرا می‌کند. این نحو منسوخ شده است و باید به جای آن از کنش \fB!entry\fP استفاده شود (کنترل دقیق‌تری فراهم می‌کند، زیرا کد می‌تواند بر مبنای هر شرط مشخص شود و می‌توان مستقیماً بدون گذر از توزیع شرط، به شروع شرط پرش کرد). .TP .B \fB< > => condition code\fP مشابه قاعدهٔ قبلی، با این تفاوت که \fBcondition\fP بعدی را تعیین می‌کند\&. .TP .B \fB< > :=> condition\fP مشابه قاعدهٔ قبلی، با این تفاوت که هیچ کد مرتبطی ندارد و بلافاصله به \fBcondition\fP پرش می‌کند\&. .UNINDENT .UNINDENT .UNINDENT .sp کدی که re2swift برای شرایط تولید می‌کند بستگی به این دارد که re2swift از روش goto/label استفاده می‌کند یا روش loop/switch برای کدگذاری خودکاره‌ها. .sp در زبان‌هایی که دستور \fBgoto\fP دارند (مانند C/C++ و Go)، شرایط به‌طور طبیعی به‌صورت بلوک‌هایی از کد با پیشوند برچسب‌هایی به فرم \fByyc_\fP پیاده‌سازی می‌شوند، که در آن \fBcond\fP نام یک شرط است (پیشوند برچسب را می‌توان با \fBre2c:cond:prefix\fP تغییر داد). گذارها بین شرایط با استفاده از \fBgoto\fP و برچسب‌های شرایط پیاده‌سازی می‌شوند. پیش از همهٔ شرایط، re2swift یک switch اولیه روی \fBYYGETSTATE\fP تولید می‌کند که به وضعیت شروع شرط کنونی پرش می‌کند. قواعد میان‌بُر \fB:=>\fP از switch اولیه گذر کرده و مستقیماً به شرط مشخص‌شده پرش می‌کنند (می‌توان از \fBre2c:cond:goto\fP برای تغییر رفتار پیش‌فرض استفاده کرد). قواعد دارای کنش‌های معنایی به‌طور خودکار به شرط بعدی پرش نمی‌کنند؛ این کار باید توسط کد کنش تعریف‌شده توسط کاربر انجام شود. .sp در زبان‌هایی که \fBgoto\fP ندارند (مانند Rust)، re2swift از متغیر \fByystate\fP برای ذخیرهٔ شماره‌های شرایط استفادهٔ مجدد می‌کند. هر شرط یک شناسهٔ عددی برابر با شمارهٔ وضعیت آغازین خود دریافت می‌کند، و یک switch بین شرایط هیچ تفاوتی با یک switch بین وضعیت‌های DFA یک شرط منفرد ندارد. نیازی به یک switch شرط اولیهٔ مجزا نیست. (از آنجا که رویکرد مشابهی برای پیاده‌سازی وضعیت‌های قابل ذخیره استفاده می‌شود، در صورتی که هم از وضعیت‌های قابل ذخیره و هم از شرایط استفاده شود، \fBYYGETCOND\fP/\fBYYSETCOND\fP زائد خواهند بود). .sp برنامهٔ زیر از شرایط شروع برای تجزیهٔ اعداد دودویی، هشت‌هشتی، ده‌دهی و شانزده‌شانزدهی استفاده می‌کند. یک بلوک منفرد وجود دارد که در آن هر مبنا شرط مخصوص به خود را دارد، و شرط اولیه به همهٔ آن‌ها متصل است. متغیر تعریف‌شده توسط کاربر \fBcond\fP شمارهٔ شرط کنونی را ذخیره می‌کند؛ این متغیر با شمارهٔ شرط اولیه‌ای که توسط بلوک \fBconditions\fP تولید شده است مقداردهی اولیه می‌شود. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2swift $INPUT \-o $OUTPUT \-c /*!conditions:re2c*/ func parseUInt32(_ yyinput: UnsafePointer) \-> UInt32? { var yycursor = 0, yymarker = 0, yycond = yycinit var accum: UInt64 = 0 loop: while true { /*!re2c re2c:yyfill:enable = 0; \(aq0b\(aq / [01] :=> bin \(dq0\(dq :=> oct \(dq\(dq / [1\-9] :=> dec \(aq0x\(aq / [0\-9a\-fA\-F] :=> hex [01] { add(\(dq0\(dq, 2); continue loop } [0\-7] { add(\(dq0\(dq, 8); continue loop } [0\-9] { add(\(dq0\(dq, 10); continue loop } [0\-9] { add(\(dq0\(dq, 16); continue loop } [a\-f] { add(\(dqa\(dq, 16, 10); continue loop } [A\-F] { add(\(dqA\(dq, 16, 10); continue loop } \(dq\ex00\(dq { return UInt32(exactly: accum) } <*> * { return nil } */ } func add(_ charOrigin: UnicodeScalar, _ base: UInt64, _ offset: UInt64 = 0) { let digit = yyinput[yycursor \- 1] \- UInt8(ascii: charOrigin) accum = min(accum * base + UInt64(digit) + offset, UInt64(UInt32.max) + 1) } } assert(parseUInt32(\(dq\(dq) == nil) assert(parseUInt32(\(dq1234567890\(dq) == 1234567890) assert(parseUInt32(\(dq0b1101\(dq) == 13) assert(parseUInt32(\(dq0x7Fe\(dq) == 2046) assert(parseUInt32(\(dq0644\(dq) == 420) assert(parseUInt32(\(dq9999999999\(dq) == nil) .ft P .fi .UNINDENT .UNINDENT.SS وضعیت قابل ذخیره‌سازی .sp با گزینهٔ \fB\-\-storable\-state\fP، ابزار re2swift تحلیل‌گر لغوی (lexer) تولید می‌کند که می‌تواند وضعیت فعلی خود را ذخیره کرده، به فراخواننده بازگردد، و بعداً عملیات را دقیقاً از همان‌جایی که رها کرده بود از سر بگیرد. حالت پیش‌فرضِ کارکرد در re2swift مدل \(dqpull\(dq (کِششی) است، که در آن تحلیل‌گر لغوی هر زمان که به ورودی بیشتری نیاز داشته باشد آن را «می‌کِشد». این ممکن است در مواردی که ورودی به صورت تکه‌تکه در دسترس قرار می‌گیرد غیرقابل‌قبول باشد (به عنوان مثال، اگر تحلیل‌گر لغوی توسط تجزیه‌کننده (parser) فراخوانی شود، یا اگر برنامهٔ تحلیل‌گر لغوی از طریق پروتکل سوکت با برنامهٔ دیگری ارتباط برقرار کند که باید پیش از ارسال پیام بعدی منتظر پاسخ از تحلیل‌گر لغوی بماند). ویژگی وضعیت قابل ذخیره‌سازی دقیقاً برای چنین مواردی در نظر گرفته شده است: این ویژگی امکان تولید تحلیل‌گرهای لغوی را فراهم می‌کند که در یک مدل \(dqpush\(dq (رانشی) کار می‌کنند. هنگامی که تحلیل‌گر لغوی به ورودی بیشتری نیاز دارد، وضعیت خود را ذخیره کرده و به فراخواننده بازمی‌گردد. بعداً، زمانی که ورودی بیشتری در دسترس قرار گرفت، فراخواننده تحلیل‌گر لغوی را دقیقاً از همان نقطه‌ای که متوقف شده بود از سر می‌گیرد. در مقایسه با مدل \(dqpull\(dq، چند تغییر لازم است: .INDENT 0.0 .IP \(bu 2 تعریف دستورهای اولیهٔ \fBYYSETSTATE()\fP و \fBYYGETSTATE(state)\fP\&. .IP \(bu 2 تعریف متغیرهای \fByych\fP، \fByyaccept\fP (در صورت استفاده) و \fBstate\fP به عنوان بخشی از وضعیت پایدار (persistent) تحلیل‌گر لغوی. متغیر \fBstate\fP باید با \fB\-1\fP مقداردهی اولیه شود\&. .IP \(bu 2 دستور \fBYYFILL\fP باید به جای تلاش برای تأمین ورودی بیشتر، به برنامهٔ بیرونی بازگردد. کد بازگشتی باید نشان دهد که تحلیل‌گر لغوی به ورودی بیشتری نیاز دارد. .IP \(bu 2 برنامهٔ بیرونی باید موقعیت‌هایی را که تحلیل‌گر لغوی به ورودی بیشتری نیاز دارد تشخیص داده و واکنش مناسب نشان دهد. .IP \(bu 2 استفادهٔ اختیاری از بلوک \fBgetstate\fP برای تولید سوییچِ \fBYYGETSTATE\fP جدا از تحلیل‌گر لغوی اصلی. این مورد فقط برای زبان‌هایی کار می‌کند که دارای \fBgoto\fP هستند (نه در حالت \fB\-\-loop\-switch\fP). .IP \(bu 2 استفاده از \fBre2c:eof\fP و روش \fI\%sentinel with bounds checks\fP برای مدیریت پایان ورودی. روش مبتنی بر لایه‌گذاری (padding) ممکن است کار نکند زیرا مشخص نیست چه زمانی باید لایه‌گذاری اضافه شود: پایان فعلی ورودی ممکن است پایان نهایی ورودی نباشد، و اضافه کردن زودهنگام لایه‌گذاری ممکن است نشانهٔ لغویِ حریصانه‌ای (greedy lexeme) را که تا حدی خوانده شده قطع کند. علاوه بر این، به دلیل منطق سطح‌بالای برنامه، دریافت ورودی بیشتر ممکن است به پردازش نشانهٔ لغوی در انتهای بافر بستگی داشته باشد (که از قبل به دلیل شرایط پایان ورودی مسدود شده است). .UNINDENT .sp در اینجا مثالی از یک تحلیل‌گر لغوی با مدل \(dqpush\(dq آورده شده است که خواندن بسته‌ها از یک سوکت را شبیه‌سازی می‌کند. تحلیل‌گر لغوی تا زمان رسیدن به پایان ورودی تکرار می‌شود و به تابع فراخواننده بازمی‌گردد. تابع فراخواننده با «ارسال» بستهٔ بعدی ورودی بیشتری فراهم کرده و تحلیل لغوی را از سر می‌گیرد. این فرایند زمانی که تمام بسته‌ها ارسال شدند، یا زمانی که خطایی رخ دهد، متوقف می‌شود. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2swift $INPUT \-o $OUTPUT \-f import Foundation func log(_ items: Any..., separator: String = \(dq \(dq, terminator: String = \(dq\en\(dq) { #if DEBUG var stderr = FileHandle.standardError print(items, separator: separator, terminator: terminator, to: &stderr) #endif } extension FileHandle: TextOutputStream { public func write(_ string: String) { self.write(Data(string.utf8)) } } struct State { // Use a small buffer to cover the case when a lexeme doesn\(aqt fit, // in a real world use case use a larger buffer. static let bufferSize = 10 let file: FileHandle // Extra \(aq\e0\(aq byte on buffer acts as terminator. var yyinput = ContiguousArray(repeating: 0, count: Self.bufferSize + 1) var yylimit = Self.bufferSize var yycursor = Self.bufferSize var yymarker = Self.bufferSize var token = Self.bufferSize var yystate = \-1 } extension State { mutating func lex(recv: inout Int) \-> Status { var yych: UInt8 = 0 lex: while true { self.token = self.yycursor /*!re2c re2c:api = record; re2c:eof = 0; re2c:variable:yyrecord = \(dqself\(dq; re2c:YYFILL = \(dqreturn .waiting\(dq; packet = [a\-z]+[;]; * { return .badPacket } $ { return .end } packet { recv += 1 continue lex } */ } } mutating func fill() \-> Status { let used = self.yylimit \- self.token let free = Self.bufferSize \- used // Error: No space. In the real world we can reallocate a larger buffer. if free < 1 { return .bigPacket } // Shift buffer contents, discarding everything up to the current lexeme. let shift = self.token self.yyinput.replaceSubrange(.. State.Status { // Create a \(dqsocket\(dq (open the same file for reading and writing). let fname: String = \(dqpipe\(dq guard FileManager.default.createFile(atPath: fname, contents: nil), let fw = FileHandle(forWritingAtPath: fname) else { fatalError(\(dqcannot open \(aq\e(fname)\(aq\(dq) } guard let fr = FileHandle(forReadingAtPath: fname) else { fatalError(\(dqcannot read file \(aq\e(fname)\(aq\(dq) } defer { // Cleanup: remove input file. do { try fw.close() try fr.close() try FileManager.default.removeItem(atPath: fname) } catch { fatalError(\(dqerror on file cleanup: \e(error.localizedDescription)\(dq) } } var state = State(file: fr) // Main loop. The buffer contains incomplete data which appears packet by // packet. When the lexer needs more input it saves its internal state and // returns to the caller which should provide more input and resume lexing. var send = 0, recv = 0 while true { switch state.lex(recv: &recv) { case .end: log(\(dqdone: got \e(recv)\(dq) assert(recv == send) return .end case .waiting: log(\(dqwaiting...\(dq) if send < packets.count { log(\(dqsent packet \e(send)\(dq) packets[send].withUTF8Buffer { do { try fw.write(contentsOf: $0) } catch { fatalError(\(dqcannot write to \e(fname): \e(error.localizedDescription)\(dq) } } send += 1 } let status = state.fill() state.yyinput.withUnsafeBytes { let buf = $0.bindMemory(to: CChar.self) log(\(dqqueue: \(aq\e(String(utf8String: buf.baseAddress!) ?? \(dq\(dq)\(aq\(dq) } if status == .bigPacket { log(\(dqerror: packet too big\(dq) return .bigPacket } assert(status == .ready) case .badPacket: log(\(dqerror: ill\-formed packet\(dq) return .badPacket default: fatalError(\(dqunreachable\(dq) } } } assert(test([]) == .end) assert(test([ \(dqzero;\(dq, \(dqone;\(dq, \(dqtwo;\(dq, \(dqthree;\(dq, \(dqfour;\(dq ]) == .end) assert(test([ \(dqzer0;\(dq ]) == .badPacket) assert(test([ \(dqlooooooooooong;\(dq ]) == .bigPacket) log(\(dqall tests completed successfully\(dq) .ft P .fi .UNINDENT .UNINDENT.SS بلوک‌های با قابلیت استفاده مجدد (Reusable blocks) .sp بلوک‌های چندبار مصرف به شکل \fB/*!rules:re2c[:] ... */\fP یا \fB%{rules[:] ... %}\fP را می‌توان به هر تعداد دفعات دوباره استفاده کرد و با سایر بلوک‌های re2swift ترکیب نمود. مقدار \fB\fP اختیاری است. یک بلوک قواعد را می‌توان در یک بلوک یا دستورالعمل \fBuse\fP به کار برد. کد یک بلوک قواعد در هر نقطه از استفاده تولید می‌شود. .sp بلوک‌های use با \fB/*!use:re2c[:] ... */\fP یا \fB%{use[:] ... %}\fP\& تعریف می‌شوند. مقدار \fB\fP اختیاری است: اگر مشخص نشده باشد، بلوک قواعد مرتبط، جدیدترین بلوک موجود خواهد بود (چه نام‌گذاری شده و چه بدون نام). یک بلوک use می‌تواند تعاریف نام‌گذاری‌شده، پیکربندی‌ها و قواعد خاص خودش را بیفزاید. یک مورد کاربرد مهم برای بلوک‌های use، تحلیل‌گر لغوی (lexer) است که از چندین کدگذاری ورودی مختلف پشتیبانی می‌کند: یک بلوک قواعد یکسان، چندین بار همراه با پیکربندی‌های مختص هر کدگذاری استفاده می‌شود (مثال زیر را ببینید). .sp دستورالعمل استفاده درون‌بلوکی \fB!use:;\fP می‌تواند از داخل یک بلوک re2swift به کار رود. این دستورالعمل، بلوک ارجاع‌شده \fB\fP را با بلوک فعلی ادغام می‌کند. اگر برخی از قواعد و پیکربندی‌های ادغام‌شده با موارد تعریف‌شده قبلی هم‌پوشانی داشته باشند، تداخل‌ها به شیوه معمول حل می‌شوند: نخستین قاعده تقدم دارد، و جدیدترین پیکربندی جایگزین موارد پیشین می‌شود. یک استثنا، قواعد ویژه \fB*\fP، \fB$\fP و (در حالت شرط) \fB\fP هستند که برای آن‌ها تعریف محلی بلوک، هرگونه تعریف به ارث‌رسیده را لغو می‌کند. دستورالعمل use امکان ترکیب بلوک‌های مختلف re2swift را با یکدیگر در یک بلوک فراهم می‌سازد (مثال زیر را ببینید). .sp بلوک‌های نام‌گذاری‌شده و دستورالعمل استفاده درون‌بلوکی در نسخه 2.2 برنامه re2swift اضافه شدند. از آن نسخه به بعد، بلوک‌های چندبار مصرف به‌طور پیش‌فرض مجاز هستند (نیازی به گزینه خاصی نیست). پیش از نسخه 2.2، حالت استفاده مجدد با گزینه \fB\-r \-\-reusable\fP فعال می‌شد. پیش از نسخه 1.2 بلوک‌های چندبار مصرف نمی‌توانستند با بلوک‌های عادی ترکیب شوند. .SS مثالی از یک دستورالعمل \fB!use\fP .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2swift $INPUT \-o $OUTPUT // This example shows how to combine reusable re2c blocks: two blocks // (\(aqcolors\(aq and \(aqfish\(aq) are merged into one. The \(aqsalmon\(aq rule occurs // in both blocks; the \(aqfish\(aq block takes priority because it is used // earlier. Default rule * occurs in all three blocks; the local (not // inherited) definition takes priority. /*!rules:re2c:colors * { fatalError(\(dqunreachable\(dq) } \(dqred\(dq | \(dqsalmon\(dq | \(dqmagenta\(dq { return .color } */ /*!rules:re2c:fish * { fatalError(\(dqunreachable\(dq) } \(dqhaddock\(dq | \(dqsalmon\(dq | \(dqeel\(dq { return .fish } */ func lex(_ yyinput: UnsafePointer) \-> What { var yycursor = 0, yymarker = 0 /*!re2c re2c:yyfill:enable = 0; !use:fish; !use:colors; * { return .dunno } // Overrides inherited \(aq*\(aq rules */ } enum What { case color, fish, dunno } assert(lex(\(dqsalmon\(dq) == .fish) assert(lex(\(dqwhat?\(dq) == .dunno) .ft P .fi .UNINDENT .UNINDENT .SS مثالی از یک بلوک \fB/*!use:re2c ... */\fP .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2swift $INPUT \-o $OUTPUT \-\-input\-encoding utf8 // This example supports multiple input encodings: UTF\-8 and UTF\-32. // Both lexers are generated from the same rules block, and the use // blocks add only encoding\-specific configurations. /*!rules:re2c re2c:yyfill:enable = 0; \(dq∀x ∃y\(dq { return true } * { return false } */ func lexUTF8(_ yyinput: [UInt8]) \-> Bool { var yycursor = 0, yymarker = 0 /*!use:re2c re2c:YYCTYPE = UInt8; re2c:encoding:utf8 = 1; */ } func lexUTF32(_ yyinput: [UInt32]) \-> Bool { var yycursor = 0, yymarker = 0 /*!use:re2c re2c:YYCTYPE = UInt32; re2c:encoding:utf32 = 1; */ } assert(lexUTF8([ 0xe2, 0x88, 0x80, 0x78, 0x20, 0xe2, 0x88, 0x83, 0x79 ])) // UTF\-8 assert(lexUTF32([ 0x00002200, 0x00000078, 0x00000020, 0x00002203, 0x00000079 ])) // UTF\-32 .ft P .fi .UNINDENT .UNINDENT .SS استخراج زیرتطابق (Submatch extraction) .sp برنامه re2swift دو گزینه برای استخراج زیرتطابق دارد. .INDENT 0.0 .TP .B \fBTags\fP گزینه اول استفاده از \fIبرچسب‌ها\fP (tags) مستقل به شکل \fB@stag\fP یا \fB#mtag\fP است، که در آن \fBstag\fP و \fBmtag\fP نام‌های اختیاری تعریف‌شده توسط کاربر هستند. برچسب‌ها با گزینه \fB\-T \-\-tags\fP یا پیکربندی \fBre2c:tags = 1\fP فعال می‌شوند. برچسب‌ها از لحاظ معنایی نشانگر موقعیت هستند: می‌توانند در هر کجای یک عبارت منظم درج شوند و به موقعیت متناظر (یا موقعیت‌های چندگانه) در رشته ورودی متصل گردند. \fIبرچسب‌های S\fP به آخرین موقعیت منطبق متصل می‌شوند و \fIبرچسب‌های m\fP به فهرستی از موقعیت‌ها متصل می‌گردند (ممکن است در زیرعبارت‌های تکرار استفاده شوند، جایی که یک موقعیت واحد در عبارت منظم با چندین موقعیت در رشته ورودی متناظر است). تمام برچسب‌ها باید توسط کاربر، یا به‌صورت دستی یا با کمک بلوک‌های \fBsvars\fP و \fBmvars\fP، تعریف شوند. اگر بیش از یک روش برای تطبیق برچسب‌ها با ورودی وجود داشته باشد، ابهام با استفاده از راهبرد ابهام‌زدایی چپ‌ترین حریصانه (leftmost greedy) برطرف می‌شود. .TP .B \fBCaptures\fP گزینه دوم استفاده از \fIگروه‌های گیرانداز\fP (capturing groups) است. آن‌ها با گزینه \fB\-\-captures\fP یا پیکربندی \fBre2c:captures = 1\fP فعال می‌شوند. دو گونه برای سیاست‌های مختلف رفع ابهام وجود دارد؛ \fB\-\-leftmost\-captures\fP (پیش‌فرض) برای سیاست چپ‌ترین حریصانه، و \fB\-\-posix\-captures\fP برای سیاست طولانی‌ترین تطابق POSIX است. در این حالت همه زیرعبارت‌های داخل پرانتز به عنوان گروه‌های گیرانداز در نظر گرفته می‌شوند و می‌توان از علامت تعجب برای مشخص کردن گروه‌های غیرگیرانداز استفاده کرد: \fB(! ... )\fP\&. با گزینه \fB\-\-invert\-captures\fP یا پیکربندی \fBre2c:invert\-captures = 1\fP، معنای علامت تعجب معکوس می‌شود. تعداد گروه‌ها برای قاعده منطبق در متغیر \fByynmatch\fP ذخیره می‌شود (کل عبارت منظم، گروه شماره صفر است)، و نتایج زیرتطابق در آرایه \fByypmatch\fP ذخیره می‌گردند. هم \fByynmatch\fP و هم \fByypmatch\fP باید توسط کاربر تعریف شوند و اندازه \fByypmatch\fP باید حداقل \fB[yynmatch * 2]\fP باشد. از بلوک \fBmaxnmatch\fP برای تعریف \fBYYMAXNMATCH\fP استفاده کنید، ثابتی که برابر با بیشینه مقدار \fByynmatch\fP در میان همه قواعد است. .TP .B \fBCaptvars\fP روش دیگر برای استفاده از گروه‌های گیرانداز، گزینه \fB\-\-captvars\fP یا پیکربندی \fBre2c:captvars = 1\fP است. تنها تفاوت با \fB\-\-captures\fP در نحوه ذخیره‌سازی نتایج زیرتطابق توسط کد تولیدشده است: به‌جای \fByynmatch\fP و \fByypmatch\fP، برنامه re2swift متغیرهای \fByytl\fP و \fByytr\fP را برای \fIk\fP\-امین گروه گیرانداز تولید می‌کند (کاربر باید این متغیرها را با استفاده از یک بلوک \fBsvars\fP اعلان کند). گیراندازی با متغیرها از دو سیاست رفع ابهام پشتیبانی می‌کند: \fB\-\-leftmost\-captvars\fP یا \fBre2c:leftmost\-captvars = 1\fP برای سیاست چپ‌ترین حریصانه (حالت پیش‌فرض) و \fB\-\-posix\-captvars\fP یا \fBre2c:posix\-captvars\fP برای سیاست طولانی‌ترین تطابق POSIX. .UNINDENT .sp در لایه‌های زیرین، تمام این گزینه‌ها به برچسب‌ها و \fI\%اتوماتای متناهی معین برچسب‌دار با پیش‌نگری\fP (Tagged Deterministic Finite Automata with Lookahead یا TDFA) تبدیل می‌شوند. ایده اصلی TDFA به حداقل رساندن سربار استخراج زیرتطابق است. در حالت حداقلی، اگر هیچ برچسب یا گروه گیراندازی در یک عبارت منظم وجود نداشته باشد، TDFA صرفاً یک DFA معمولی است. اگر تعداد برچسب‌ها در حد اعتدال باشد، سربار به‌ندرت محسوس است. اتوماتای TDFA تولیدشده از تعدادی \fIمتغیر برچسب\fP استفاده می‌کند که مستقیماً به برچسب‌ها نگاشت نمی‌شوند: یک متغیر واحد ممکن است برای برچسب‌های متفاوتی به کار رود، و یک برچسب ممکن است به چندین متغیر برای نگهداری تمام مقادیر ممکن خود نیاز داشته باشد. در نهایت، ابهام رفع شده و به ازای هر برچسب تنها یک متغیر نهایی باقی می‌ماند. متغیرهای برچسب باید با استفاده از بلوک‌های \fBstags\fP یا \fBmtags\fP تعریف شوند. اگر وضعیت لکسر ذخیره شود، متغیرهای برچسب نیز باید بخشی از آن باشند. آن‌ها همچنین باید توسط \fBYYFILL\fP به‌روزرسانی شوند. .sp برچسب‌های S از عملیات زیر پشتیبانی می‌کنند: .INDENT 0.0 .IP \(bu 2 ذخیره موقعیت ورودی در یک برچسب s: دستور \fBt = YYCURSOR\fP با API اشاره‌گر C یا عملیات تعریف‌شده توسط کاربر \fBYYSTAGP(t)\fP با API عمومی .IP \(bu 2 ذخیره مقدار پیش‌فرض در یک برچسب s: دستور \fBt = NULL\fP با API اشاره‌گر C یا عملیات تعریف‌شده توسط کاربر \fBYYSTAGN(t)\fP با API عمومی .IP \(bu 2 کپی یک برچسب s به دیگری: \fBt1 = t2\fP .UNINDENT .sp برچسب‌های M از عملیات زیر پشتیبانی می‌کنند: .INDENT 0.0 .IP \(bu 2 الحاق موقعیت ورودی به یک برچسب m: عملیات تعریف‌شده توسط کاربر \fBYYMTAGP(t)\fP هم با API پیش‌فرض و هم با API عمومی .IP \(bu 2 الحاق مقدار پیش‌فرض به یک برچسب m: عملیات تعریف‌شده توسط کاربر \fBYYMTAGN(t)\fP هم با API پیش‌فرض و هم با API عمومی .IP \(bu 2 کپی یک برچسب m به دیگری: \fBt1 = t2\fP .UNINDENT .sp برچسب‌های S را می‌توان به صورت مقادیر اسکالر (اشاره‌گرها یا آفست‌ها) پیاده‌سازی کرد. برچسب‌های M به نمایش پیچیده‌تری نیاز دارند، چرا که باید دنباله‌ای از مقادیر برچسب را ذخیره کنند. ساده‌ترین و ناکارآمدترین نمایش یک برچسب m، یک فهرست (آرایه، بردار) از مقادیر برچسب است؛ نمایش کارآمدتر، ذخیره تمام برچسب‌های m در یک درخت پیشوندی است که به صورت آرایه‌ای از گره‌های \fB(v, p)\fP نمایش داده می‌شود، که در آن \fBv\fP مقدار برچسب و \fBp\fP اشاره‌گری به گره والد است. .sp در اینجا یک مثال ساده از استفاده از برچسب‌های s برای تجزیه نسخه‌بندی معنایی متشکل از سه مؤلفه عددی آورده شده است: major، minor، patch (مورد آخر اختیاری است). برای یک مثال پیچیده‌تر که از \fBYYFILL\fP استفاده می‌کند، به بخش زیر مراجعه کنید. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2swift $INPUT \-o $OUTPUT struct SemVer: Equatable { var major: Int, minor: Int, patch: Int } func lex(_ yyinput: UnsafePointer) \-> SemVer? { let tagNone = \-1 var yycursor = 0, yymarker = 0 // Final tag variables available in semantic action. /*!svars:re2c format = \(dqvar @@ = tagNone\en\(dq; */ // Intermediate tag variables used by the lexer (must be autogenerated). /*!stags:re2c format = \(aqvar @@ = tagNone\en\(aq; */ /*!re2c re2c:yyfill:enable = 0; re2c:tags = 1; num = [0\-9]+; @t1 num @t2 \(dq.\(dq @t3 num @t4 (\(dq.\(dq @t5 num)? [\ex00] { let s2n = { (range: Range) in range.reduce(0) { accum, idx in accum * 10 + Int(yyinput[idx] \- UInt8(ascii: \(dq0\(dq)) } } return SemVer( major: s2n(t1..(repeating: 0, count: Self.bufferSize + 1) var yylimit = Self.bufferSize var yycursor = Self.bufferSize var yymarker = Self.bufferSize var token = Self.bufferSize // Intermediate tag variables must be part of the lexer state passed to YYFILL. // They don\(aqt correspond to tags and should be autogenerated by re2c. /*!stags:re2c format = \(dq var @@ = Self.tagNone\en\(dq; */ var eof = false let file: FileHandle } extension Input { mutating func lex() \-> [SemVer]? { var semVers = [SemVer]() semVers.reserveCapacity(Self.bufferSize) // Final tag variables available in semantic action. /*!svars:re2c format = \(dq var @@: Int\en\(dq; */ parse: while true { self.token = self.yycursor /*!re2c re2c:api = record; re2c:eof = 0; re2c:tags = 1; re2c:yyrecord = \(dqself\(dq; re2c:YYFILL = \(dqself.fill() == .ok\(dq; num = [0\-9]+; num @t1 \(dq.\(dq @t2 num @t3 (\(dq.\(dq @t4 num)? [\en] { semVers.append(SemVer( major: self.s2n(self.token..) \-> Int { self.yyinput[range].reduce(0) { accum, digit in accum * 10 + Int(digit \- UInt8(ascii: \(dq0\(dq)) } } mutating func fill() \-> FillStatus { guard !self.eof else { return .eof } let shift = self.token let used = self.yylimit \- self.token let free = Self.bufferSize \- used // Error: Lexeme too long. In the real world we could reallocate a larger buffer. guard self.token >= 1 else { return .longLexeme } // Shift buffer contents, discarding everything up to the current token. self.yyinput.replaceSubrange(..) \-> SemVer? { let tagNone = \-1 var yycursor = 0, yymarker = 0 // Final tag variables available in semantic action. /*!svars:re2c format = \(dq var @@: Int\en\(dq; */ // Intermediate tag variables used by the lexer (must be autogenerated). /*!stags:re2c format = \(dq var @@ = tagNone\en\(dq; */ /*!re2c re2c:yyfill:enable = 0; re2c:captvars = 1; num = [0\-9]+; (num) \(dq.\(dq (num) (\(dq.\(dq num)? [\ex00] { let _ = yytl0; _ = yytr0 // Some variables are unused. return SemVer( major: s2n(yytl1..) \-> Int { range.reduce(0) { accum, idx in accum * 10 + Int(yyinput[idx] \- UInt8(ascii: \(dq0\(dq)) } } } assert(lex(\(dq23.34\(dq) == SemVer(major: 23, minor: 34, patch: 0)) assert(lex(\(dq1.2.999\(dq) == SemVer(major: 1, minor: 2, patch: 999)) assert(lex(\(dq1.a\(dq) == nil) .ft P .fi .UNINDENT .UNINDENT .sp در اینجا مثالی از به‌کارگیری برچسب‌های m برای تجزیه یک نسخه با تعداد متغیری از مؤلفه‌ها آورده شده است. متغیرهای برچسب در یک ترای (trie) ذخیره می‌شوند. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2swift $INPUT \-o $OUTPUT import Foundation // Unbounded number of version components. struct Ver: Equatable { let components: [Int] } func parse(_ yyinput: UnsafePointer) \-> Ver? { let tagNone = \-1 var yycursor = 0, yymarker = 0 var mTagPool = [MTag]() // Final tag variables available in semantic action. /*!svars:re2c format = \(dq let @@: Int\en\(dq; */ /*!mvars:re2c format = \(dq let @@: MTag?\en\(dq; */ // Intermediate tag variables used by the lexer (must be autogenerated). /*!stags:re2c format = \(dq var @@ = tagNone\en\(dq; */ /*!mtags:re2c format = \(dq var @@: MTag? = nil\en\(dq; */ /*!re2c re2c:tags = 1; re2c:yyfill:enable = 0; re2c:YYSTAGP = \(dq@@ = yycursor\(dq; re2c:YYSTAGN = \(dq@@ = tagNone\(dq; re2c:YYMTAGP = \(dq@@ = add(tag: @@, value: yycursor)\(dq; re2c:YYMTAGN = \(dq@@ = add(tag: @@, value: tagNone)\(dq; num = [0\-9]+; @t1 num @t2 (\(dq.\(dq #t3 num #t4)* [\ex00] { var components = [s2n(t1..) \-> Int { range.reduce(0) { accum, idx in accum * 10 + Int(yyinput[idx] \- UInt8(ascii: \(dq0\(dq)) } } // Append a single value to an m\-tag history. func add(tag prevTag: MTag?, value: Int) \-> MTag { let tag = MTag(prev: prevTag, element: value) mTagPool.append(tag) return tag } } // An m\-tag tree is a way to store histories with an O(1) copy operation. // Histories naturally form a tree, as they have common start and fork at some // point. The tree is stored as an array of pairs (tag value, link to parent). // An m\-tag is represented with a single link in the tree (array index). class MTag { weak var prev: MTag? // Link of predecessor node or root (nil) var elem: Int // Tag value init(prev: MTag?, element: Int) { self.prev = prev self.elem = element } } assert(parse(\(dq1\(dq) == Ver(components: [1])) assert(parse(\(dq1.2.3.4.5.6.7\(dq) == Ver(components: [1, 2, 3, 4, 5, 6, 7])) assert(parse(\(dq1.2.\(dq) == nil) .ft P .fi .UNINDENT .UNINDENT.SS "پشتیبانی از کدگذاری (Encoding support)" .sp درک تفاوت میان \fBنقطه‌کدها (code points)\fP و \fBواحدهای کد (code units)\fP\& ضروری است. یک نقطه‌کد، یک شناسه عددی برای یک نماد است. یک واحد کد، کوچک‌ترین واحد ذخیره‌سازی در متن کدگذاری‌شده است. یک نقطه‌کد منفرد ممکن است با یک یا چند واحد کد نمایش داده شود. در یک کدگذاری با طول ثابت (fixed\-length)، تمام نقطه‌کدها با تعداد یکسانی از واحدهای کد نمایش داده می‌شوند. در یک کدگذاری با طول متغیر (variable\-length)، نقطه‌کدها ممکن است با تعداد متفاوتی از واحدهای کد نمایش یابند. توجه داشته باشید که قاعده «هر چیز» (\(dqany\(dq) یعنی \fB[^]\fP با هر نقطه‌کدی مطابقت دارد، اما لزوماً با هر واحد کدی مطابقت ندارد (تنها راه برای تطبیق با هر واحد کد بدون در نظر گرفتن نوع کدگذاری، قاعده پیش‌فرض \fB*\fP است). تحلیل‌گر لغوی (lexer) تولیدشده با جریانی از واحدهای کد کار می‌کند: \fByych\fP یک واحد کد را ذخیره می‌کند و \fBYYCTYPE\fP نوع واحد کد است. از سوی دیگر، عبارات باقاعده بر حسب نقطه‌کدها مشخص می‌شوند. هنگامی که re2swift عبارات باقاعده را به اتوماتا کامپایل می‌کند، نقطه‌کدها را به واحدهای کد ترجمه می‌نماید. این تبدیل عموماً یک نگاشت ساده نیست: در کدگذاری‌های با طول متغیر، یک محدوده نقطه‌کد منفرد ممکن است به یک گراف پیچیده از واحدهای کد تبدیل شود. کدگذاری‌های زیر پشتیبانی می‌شوند: .INDENT 0.0 .IP \(bu 2 \fBASCII\fP (به‌طور پیش‌فرض فعال است). یک کدگذاری با طول ثابت با فضای کد \fB[0\-255]\fP و نقطه‌کدها و واحدهای کد ۱ بایتی است. .IP \(bu 2 \fBEBCDIC\fP (با \fB\-\-ebcdic\fP یا \fBre2c:encoding:ebcdic\fP فعال می‌شود). یک کدگذاری با طول ثابت با فضای کد \fB[0\-255]\fP و نقطه‌کدها و واحدهای کد ۱ بایتی است. .IP \(bu 2 \fBUCS2\fP (با \fB\-\-ucs2\fP یا \fBre2c:encoding:ucs2\fP فعال می‌شود). یک کدگذاری با طول ثابت با فضای کد \fB[0\-0xFFFF]\fP و نقطه‌کدها و واحدهای کد ۲ بایتی است. .IP \(bu 2 \fBUTF8\fP (با \fB\-\-utf8\fP یا \fBre2c:encoding:utf8\fP فعال می‌شود). یک کدگذاری یونی‌کد با طول متغیر است. اندازه هر واحد کد ۱ بایت است. نقطه‌کدها با ۱ تا ۴ واحد کد نمایش داده می‌شوند. .IP \(bu 2 \fBUTF16\fP (با \fB\-\-utf16\fP یا \fBre2c:encoding:utf16\fP فعال می‌شود). یک کدگذاری یونی‌کد با طول متغیر است. اندازه هر واحد کد ۲ بایت است. نقطه‌کدها با ۱ تا ۲ واحد کد نمایش داده می‌شوند. .IP \(bu 2 \fBUTF32\fP (با \fB\-\-utf32\fP یا \fBre2c:encoding:utf32\fP فعال می‌شود). یک کدگذاری یونی‌کد با طول ثابت با فضای کد \fB[0\-0x10FFFF]\fP و نقطه‌کدها و واحدهای کد ۴ بایتی است. .UNINDENT .sp فایل‌های include شامل \fBinclude/unicode_blocks.re\fP، \fBinclude/unicode_categories.re\fP و \fBinclude/unicode_properties.re\fP تعاریف re2swift را برای بلوک‌ها، دسته‌بندی‌ها و ویژگی‌های شرح‌داده‌شده در استاندارد Unicode فراهم می‌کنند. .sp گزینه \fB\-\-input\-encoding\fP کدگذاری فایل مبدأ را مشخص می‌کند که می‌تواند برای فعال‌سازی لیترال‌های یونی‌کد در عبارات باقاعده به کار رود. برای مثال \fB\-\-input\-encoding utf8\fP به re2swift اعلام می‌کند که فایل مبدأ با فرمت UTF8 است (با \fB\-\-utf8\fP که کدگذاری متن ورودی را تعیین می‌کند تفاوت دارد). گزینه \fB\-\-encoding\-policy\fP روشی را تعیین می‌کند که re2swift با جانشین‌های یونی‌کد (نقطه‌کدهای موجود در محدوده \fB[0xD800\-0xDFFF]\fP) رفتار می‌کند. .sp در زیر نمونه‌ای از یک تحلیل‌گر لغوی برای شناسه‌های یونی‌کد با کدگذاری UTF8 آورده شده است. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2swift $INPUT \-o $OUTPUT \-8 \-i /*!include:re2c \(dqunicode_categories.re\(dq */ func lex(_ yyinput: UnsafePointer) \-> Bool { var yycursor = 0, yymarker = 0 /*!re2c re2c:yyfill:enable = 0; // Simplified \(dqUnicode Identifier and Pattern Syntax\(dq // (see https://unicode.org/reports/tr31) id_start = L | Nl | [$_]; id_continue = id_start | Mn | Mc | Nd | Pc | [\eu200D\eu05F3]; identifier = id_start id_continue*; identifier { return true } * { return false } */ } assert(lex(\(dq_Ыдентификатор\(dq)) assert(lex(\(dq識別子\(dq)) assert(!lex(\(dq+\(dq)) .ft P .fi .UNINDENT .UNINDENT .SS "فایل‌های ضمیمه (Include files)" .sp برنامه re2swift اجازه می‌دهد تا فایل‌های دیگر را با استفاده از بلوکی به قالب \fB/*!include:re2c FILE */\fP یا \fB%{include FILE %}\fP، یا یک دستورالعمل درون‌بلوکیِ \fB!include FILE ;\fP ضمیمه کنید، که در آن \fBFILE\fP مسیر فایلی است که باید اضافه شود. re2swift فایل‌های include را در دایرکتوری فایلی که شامل این دستور است و همچنین در مکان‌های include که با گزینه \fB\-I\fP مشخص می‌شوند جستجو می‌کند. بلوک‌ها/دستورالعمل‌های include در re2swift مشابه \fB#include\fP در C/C++ عمل می‌کنند: محتوای \fBFILE\fP عیناً در جای بلوک/دستورالعمل جای‌گذاری می‌شود. فایل‌های include ممکن است خودشان نیز شامل موارد include دیگری باشند. برای ردگیری وابستگی‌های ساخت فایل خروجی به فایل‌های include، از گزینه \fB\-\-depfile\fP استفاده کنید. برنامه re2swift تعدادی فایل include از پیش تعریف‌شده ارائه می‌دهد که در زیردایرکتوری \fBinclude/\fP پروژه یافت می‌شوند. این فایل‌ها حاوی تعاریفی هستند که ممکن است برای پروژه‌های دیگر مفید باشند (مانند دسته‌بندی‌های Unicode) و ساختاری شبیه به یک کتابخانه استاندارد برای re2swift\& تشکیل می‌دهند. در زیر مثالی از نحوه استفاده از فایل‌های include آورده شده است. .SS "فایل ضمیمه ۱ (definitions.swift)" .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C enum Result { case ok, fail } /*!re2c number = [1\-9][0\-9]*; */ .ft P .fi .UNINDENT .UNINDENT.SS فایل ضمیمه ۲ (extra_rules.re.inc) .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // floating\-point numbers frac = [0\-9]* \(dq.\(dq [0\-9]+ | [0\-9]+ \(dq.\(dq; exp = \(aqe\(aq [+\-]? [0\-9]+; float = frac exp? | [0\-9]+ exp; float { return .ok } .ft P .fi .UNINDENT .UNINDENT .SS فایل ورودی (Input file) .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2swift $INPUT \-o $OUTPUT \-i /*!include:re2c \(dqdefinitions.swift\(dq */ func lex(_ yyinput: UnsafePointer) \-> Result { var yycursor = 0, yymarker = 0 /*!re2c re2c:yyfill:enable = 0; * { return .fail } number { return .ok } !include \(dqextra_rules.re.inc\(dq; */ } assert(lex(\(dq123\(dq) == .ok) assert(lex(\(dq123.4567\(dq) == .ok) .ft P .fi .UNINDENT .UNINDENT .SS فایل‌های سرآیند (Header files) .sp ابزار re2swift به شما اجازه می‌دهد با استفاده از گزینهٔ \fB\-\-header\fP یا پیکربندی \fBre2c:header\fP و جفت‌بلوک‌هایی به شکل \fB/*!header:re2c:on*/\fP و \fB/*!header:re2c:off*/\fP، یا \fB%{header:on%}\fP و \fB%{header:off%}\fP\&، از روی فایل ورودی \fB\&.re\fP یک فایل سرآیند تولید کنید. بلوک نخست، آغاز فایل سرآیند و بلوک دوم، پایان آن را مشخص می‌کند. تمامی محتوای میان این بلوک‌ها توسط re2swift پردازش شده و کد تولیدشده در فایلی که با گزینهٔ \fB\-\-header\fP یا پیکربندی \fBre2c:header\fP مشخص شده نوشته می‌شود (یا در صورت عدم استفاده از گزینه یا پیکربندی، در \fBstdout\fP نوشته خواهد شد). فایل سرآیند تولیدشدهٔ خودکار ممکن است در مواردی نیاز باشد که re2swift برای تولید تعاریفی به کار می‌رود که باید از سایر واحدهای ترجمه (translation units) قابل مشاهده باشند. .sp در ادامه مثالی از تولید یک فایل سرآیند آورده شده است که شامل تعریف وضعیت لکسر به همراه متغیرهای برچسب (tag variables) است (تعداد متغیرها به گرامر منظم بستگی دارد و برای برنامه‌نویس مشخص نیست). .SS فایل ورودی (Input file) .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2swift $INPUT \-o $OUTPUT \-i \-\-header lexer/state.swift /*!header:re2c:on*/ struct LexerState { var yyinput: UnsafePointer var yycursor: Int /*!stags:re2c format = \(dqvar @@ = \-1\(dq; */ init(str: UnsafePointer, cur: Int = 0) { self.yyinput = str self.yycursor = cur } } /*!header:re2c:off*/ extension LexerState { mutating func lex() \-> Int { let t: Int /*!re2c re2c:header = \(dqlexer/state.swift\(dq; re2c:api = record; re2c:tags = 1; re2c:yyfill:enable = 0; re2c:yyrecord = \(dqself\(dq; [a]* @t [b]* { return t } */ } } @main struct Program { static func main() { let str: StaticString = \(dqab\(dq var state = LexerState(str: str.utf8Start) assert(state.lex() == 1) } } .ft P .fi .UNINDENT .UNINDENT .SS فایل سرآیند (Header file) .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C /* Generated by re2swift */ struct LexerState { var yyinput: UnsafePointer var yycursor: Int var yyt1 = \-1 init(str: UnsafePointer, cur: Int = 0) { self.yyinput = str self.yycursor = cur } } .ft P .fi .UNINDENT .UNINDENT.SS برنامه‌های اسکلتی (Skeleton programs) .sp با گزینهٔ \fB\-S, \-\-skeleton\fP، ابزار re2swift تمام کدهای غیر re2swift را نادیده می‌گیرد و یک برنامهٔ C خودکفا تولید می‌کند که می‌تواند در ادامه کامپایل و اجرا شود. این برنامه از کد تحلیل‌گر لغوی (lexer) و داده‌های ورودی تشکیل شده است. به ازای هر DFA ساخته‌شده (بلوک یا شرط)، re2swift یک تحلیل‌گر لغوی مستقل و دو فایل تولید می‌کند: یک فایل \fB\&.input\fP با رشته‌های مشتق‌شده از DFA و یک فایل \fB\&.keys\fP با نتایج تطابق مورد انتظار. برنامه هر تحلیل‌گر لغوی را روی فایل \fB\&.input\fP متناظر اجرا کرده و نتایج را با موارد مورد انتظار مقایسه می‌کند. برنامه‌های اسکلتی به چند دلیل بسیار مفید هستند: .INDENT 0.0 .IP \(bu 2 آن‌ها می‌توانند درستی بهینه‌سازی‌های گوناگون re2swift را بررسی کنند (داده‌ها در مراحل اولیهٔ فرایند، پیش از اعمال هرگونه تبدیل روی DFA تولید می‌شوند). .IP \(bu 2 تولید مجموعه‌ای از داده‌های ورودی با پوشش مناسب می‌تواند هم برای آزمایش و هم برای ارزیابی کارایی (benchmarking) مفید باشد. .IP \(bu 2 تولید برنامه‌های اجرایی خودکفا به شخص اجازه می‌دهد موارد آزمون کمینه‌شده (minimized test cases) به دست آورد (کد اصلی ممکن است بزرگ باشد یا وابستگی‌های زیادی داشته باشد). .UNINDENT .sp دشواریِ تولید داده‌های ورودی در این است که به‌جز در ساده‌ترین حالت‌ها، تعداد رشته‌های ورودیِ ممکن بیش از حد زیاد است (حتی اگر طول رشته محدود باشد). re2swift این دشواری را با تولید رشته‌های کافی برای پوشش تقریباً تمامی گذارهای DFA حل می‌کند. این ابزار از الگوریتم زیر استفاده می‌کند: ابتدا اسکلتی از DFA را می‌سازد. برای کدگذاری‌هایی با اندازه واحد کد 1\-بایتی (مانند ASCII، UTF\-8 و EBCDIC) اسکلت صرفاً یک رونوشت دقیق از DFA اصلی است. برای کدگذاری‌هایی با واحدهای کد چندبایتی، اسکلت رونوشتی از DFA با حذف برخی گذارها است: بدین صورت که re2swift حداکثر ۲۵۶ واحد کد را برای هر بازهٔ پیوسته و مجزا که با یک گذار DFA مطابقت دارد برمی‌گزیند. مقادیر انتخاب‌شده به‌طور یکنواخت توزیع شده‌اند و شامل کران‌های بازه نیز می‌شوند. re2swift به‌جای تلاش برای پوشش تمام مسیرهای ممکن در اسکلت (که کاری نشدنی است)، مسیرهای کافی برای پوشش همهٔ گذارهای اسکلت تولید می‌کند تا بدین ترتیب پرش‌های شرطی متناظر در تحلیل‌گر لغوی فعال شوند. پیاده‌سازی این الگوریتم به حدود 1 گیگابایت گذار محدود شده است و مقدار ثابتی حافظه مصرف می‌کند (re2swift به‌محض تولید داده‌ها، آن‌ها را در فایل می‌نویسد). .SS مصورسازی و اشکال‌زدایی (Visualization and debug) .sp با گزینهٔ \fB\-D, \-\-emit\-dot\fP، ابزار re2swift هیچ کدی تولید نمی‌کند؛ در عوض، DFA تولیدشده را در قالب DOT ذخیره (dump) می‌کند. می‌توان این خروجی را با استفاده از Graphviz یا کتابخانه‌ای دیگر به تصویری از DFA تبدیل کرد. توجه داشته باشید که این گزینه، DFA نهایی را پس از گذراندن شماری از بهینه‌سازی‌ها و تبدیل‌ها نشان می‌دهد. مراحل اولیه را می‌توان با گزینه‌های اشکال‌زدایی گوناگون مانند \fB\-\-dump\-nfa\fP، \fB\-\-dump\-dfa\-raw\fP و غیره ذخیره کرد (فهرست کامل گزینه‌ها را ببینید). .SH "همچنین ببینید (SEE ALSO)" .sp می‌توانید اطلاعات بیشتری دربارهٔ re2c در وبگاه رسمی بیابید: \fI\%http://re2c.org\fP\&. برنامه‌های مشابه عبارتند از flex(1)، lex(1)، quex(\fI\%http://quex.sourceforge.net\fP). .SH "نویسندگان (AUTHORS)" .sp re2swift در ابتدا توسط Peter Bumbulis (\fI\%peter@csg.uwaterloo.ca\fP) در سال ۱۹۹۳ نوشته شد. Marcus Boerger و Dan Nuffer چندین سال وقت صرف کردند تا ایدهٔ اصلی را به یک تولیدکنندهٔ کد آمادهٔ استفاده در محیط عملیاتی تبدیل کنند. از آن زمان، این پروژه توسط داوطلبان متعددی نگهداری و توسعه داده شده است، به‌ویژه: Brian Young (\fI\%bayoung@acm.org\fP)، \fI\%Marcus Boerger\fP، Dan Nuffer (\fI\%nuffer@users.sourceforge.net\fP)، \fI\%Ulya Trofimovich\fP (\fI\%skvadrik@gmail.com\fP)، \fI\%Serghei Iakovlev\fP، \fI\%Sergei Trofimovich\fP، \fI\%Petr Skocik\fP، \fI\%ligfx\fP \fI\%raekye\fP و \fI\%PolarGoose\fP\&. .\" Generated by docutils manpage writer. .