.\" 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 "RE2V" 1 "" "" "" .SH "نام (NAME)" re2v \- تولید تحلیل‌گرهای لغوی سریع برای V .SH "خلاصه دستور (SYNOPSIS)" .sp re2v \fB[ OPTIONS ]\fP \fB[ WARNINGS ]\fP \fBINPUT\fP .sp ورودی می‌تواند یک فایل یا \fB\-\fP برای stdin باشد. .SH "مقدمه (INTRODUCTION)" .sp ابزار re2v به عنوان یک پیش‌پردازنده عمل می‌کند. این ابزار فایل ورودی (که معمولاً یک برنامه به زبان V است، اما می‌تواند هر چیز دیگری نیز باشد) را خوانده و به دنبال بلوک‌های کدی می‌گردد که درون نشانگرهای آغاز/پایان با قالب خاص قرار گرفته‌اند. متن خارج از این بلوک‌ها عیناً به فایل خروجی کپی می‌شود. محتویات درون بلوک‌ها توسط re2v پردازش می‌گردد. این ابزار آن‌ها را به کد V ترجمه کرده و کد تولیدشده را به جای آن بلوک در خروجی قرار می‌دهد. .sp در اینجا مثالی از یک برنامه کوچک آورده شده است که بررسی می‌کند آیا یک رشته داده‌شده حاوی عدد بر مبنای ۱۰ (ده‌دهی) است یا خیر: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2v $INPUT \-o $OUTPUT \-i fn lex(yyinput string) { mut yycursor := 0 /*!re2c re2c:yyfill:enable = 0; [1\-9][0\-9]* { return } * { panic(\(dqerror!\(dq) } */ } fn main() { lex(\(dq1234\ex00\(dq) } .ft P .fi .UNINDENT .UNINDENT .sp در خروجی، re2v بلوک میانی را با کد تولیدشده جایگزین کرده است: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Code generated by re2v, DO NOT EDIT. // re2v $INPUT \-o $OUTPUT \-i fn lex(yyinput string) { mut yycursor := 0 mut yych := u8(0) yych = yyinput[yycursor] match yych { 0x31...0x39 { unsafe { goto yy2 } } else { unsafe { goto yy1 } } } yy1: yycursor += 1 panic(\(dqerror!\(dq) yy2: yycursor += 1 yych = yyinput[yycursor] match yych { 0x30...0x39 { unsafe { goto yy2 } } else { unsafe { goto yy3 } } } yy3: return } fn main() { lex(\(dq1234\ex00\(dq) } .ft P .fi .UNINDENT .UNINDENT.SH "مبانی (BASICS)" .sp یک برنامه re2v از دنباله‌ای از \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 نمایی کلی از نحو re2v برای عبارت‌های منظم ارائه می‌دهد. پس از تعریف، \fBname\fP می‌تواند در سایر عبارت‌های منظم و قواعد استفاده شود. بازگشت در تعاریف نام‌گذاری‌شده مجاز نیست و هر نام باید پیش از استفاده تعریف شود. یک بلاک تعاریف نام‌گذاری‌شده را از حوزه سراسری (global scope) به ارث می‌برد. بازتعریف نامی که در حوزه فعلی وجود دارد خطا است. .TP .B \fBconfiguration = value ;\fP یک \fIپیکربندی\fP امکان تغییر رفتار re2v و سفارشی‌سازی کد تولیدشده را فراهم می‌کند. برای مشاهده فهرست کامل پیکربندی‌های پشتیبانی‌شده توسط re2v به بخش \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 شامل تعاریف، پیکربندی‌ها، قواعد و دستورالعمل‌ها است. re2v عبارت‌های منظم مرتبط با هر قاعده را به یک اتوماتون متناهی قطعی کامپایل می‌کند، آن را در قالب پرش‌های شرطی در زبان مقصد کدگذاری کرده و بلاک را با کد تولیدشده جایگزین می‌کند. نام‌ها و پیکربندی‌های تعریف‌شده در یک بلاک سراسری به حوزه سراسری افزوده می‌شوند و برای بلاک‌های بعدی قابل مشاهده خواهند بود. در آغاز برنامه، حوزه سراسری با \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 برنامه re2v، بلاک‌های قواعد به گزینه \fB\-r \-\-reusable\fP نیاز داشتند. .TP .B \fB/*!use:re2c[:] ... */\fP or \fB%{use[:] ... %}\fP یک بلاک use که به یک بلاک قواعد تعریف‌شده از قبل ارجاع می‌دهد. اگر نام مشخص شده باشد، re2v به دنبال یک بلاک قواعد با این نام می‌گردد. در غیر این صورت، از جدیدترین بلاک قواعد استفاده می‌شود (خواه دارای نام باشد یا بدون نام). یک بلاک use می‌تواند تعاریف، پیکربندی‌ها و قواعد خاص خود را بیفزاید که به موارد موجود در بلاک قواعد مورد ارجاع اضافه می‌شوند. پیش از نسخه 2.2 برنامه re2v، بلاک‌های 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 تولیدشده توسط re2v بسط داده می‌شود. یک فهرست اختیاری از نام‌های بلاک مشخص می‌کند که هنگام محاسبه مجموعه متغیرهای برچسب، کدام بلاک‌ها باید لحاظ شوند (اگر فهرست خالی باشد، تمام بلاک‌ها لحاظ می‌شوند). دو پیکربندی اختیاری وجود دارد: \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) یا به‌طور ضمنی توسط re2v تولید شده است (با گزینه‌های \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 بلاکی که توزیع شرطی بر اساس وضعیت تحلیل‌گر لغوی را تولید می‌کند (به گزینه \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 بلاکی که شمارش وضعیت‌ها را تولید می‌کند (به گزینه \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 این بلاک آغاز فایل سرایند را مشخص می‌کند. تمام موارد پس از آن و تا بلاک \fBheader:off\fP بعدی، توسط re2v پردازش شده و در فایل سرایندی که با گزینه \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 در ادامه فهرست کاملی از پیکربندی‌های پشتیبانی‌شده توسط re2v آمده است: .INDENT 0.0 .TP .B \fBre2c:api\fP, \fBre2c:input\fP همانند گزینهٔ \fB\-\-api\fP. .TP .B \fBre2c:api:sigil\fP نشانه‌گذاری (\(dqسیجیل\(dq یا \(dqsigil\(dq) را مشخص می‌کند که برای جای‌نگهدارهای آرگومان در عناصر پایهٔ API استفاده می‌شود. مقدار پیش‌فرض \fB@@\fP است\&. یک جای‌نگهدار با سیجیل آغاز شده و پس از آن نام آرگومان درون آکولاد می‌آید. برای مثال، اگر سیجیل روی \fB$\fP تنظیم شود، جای‌نگهدارها به شکل \fB${name}\fP خواهند بود\&. رابط‌های برنامه‌نویسی دارای یک آرگومان می‌توانند از نمادگذاری کوتاه بدون درج نام در آکولاد استفاده کنند. این گزینه می‌تواند با گزینه‌های مربوط به هر یک از عناصر پایهٔ مجزای 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++ یا بستارها (closures) در Go و Rust دارند. در سبک آزاد (\fBfree\-form\fP)، عناصر پایهٔ 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 تودرتو و نقشه‌های بیتی (bitmaps) را فعال می‌سازد. مقدار پیش‌فرض \fB9\fP است\&. .TP .B \fBre2c:cond:abort\fP اگر روی یک مقدار عددی صحیح مثبت تنظیم شود، شاخهٔ پیش‌فرض (default case) در توزیع شرایط تولیدشده اجرای برنامه را متوقف (abort) می‌کند. .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 نماد نگهبان (sentinel) مورداستفاده به همراه قاعدهٔ پایان ورودی \fB$\fP را تعیین می‌کند. مقدار پیش‌فرض \fB\-1\fP است (قاعدهٔ \fB$\fP استفاده نمی‌شود). مقادیر دیگر شامل تمام واحدهای کد معتبر هستند. تنها اعداد ده‌دهی پشتیبانی می‌شوند. .TP .B \fBre2c:header\fP, \fBre2c:flags:type\-header\fP, \fBre2c:flags:t\fP نام فایل سرایند (header) تولیدشده را نسبت به دایرکتوری فایل خروجی مشخص می‌کند. همانند گزینهٔ \fB\-\-header\fP، با این تفاوت که مسیر فایل نسبی است. .TP .B \fBre2c:indent:string\fP رشتهٔ مورداستفاده برای دندانه‌گذاری را مشخص می‌کند. مقدار پیش‌فرض یک نویسهٔ تب منفرد \fB\(dq\et\(dq\fP است\&. رشتهٔ دندانه‌گذاری باید تنها شامل نویسه‌های فاصله خالی (whitespace) باشد. برای غیرفعال‌سازی کامل دندانه‌گذاری، این پیکربندی را روی یک رشتهٔ خالی تنظیم کنید. .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 عبارت مورد استفاده برای متغیرهای برچسب را مشخص می‌کند. به‌طور پیش‌فرض re2v عبارت‌هایی به شکل \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 است، و در صورت اشاره‌گر بودن، اشاره‌گر تهی (null pointer) خواهد بود). .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 است (در این حالت re2v فرض می‌کند که نماد نگهبان صفر است که متداول‌ترین حالت است). تنها اعداد ده‌دهی تشخیص داده می‌شوند. .TP .B \fBre2c:state:abort\fP اگر روی یک مقدار عددی صحیح مثبت تنظیم شود، شاخهٔ پیش‌فرض (default case) در توزیع وضعیت (state dispatch) تولیدشده، اجرای برنامه را لغو (abort) می‌کند، و یک شاخهٔ صریح \fB\-1\fP حاوی انتقال به ابتدای بلوک خواهد بود. .TP .B \fBre2c:state:nextlabel\fP کنترل می‌کند که آیا پس از سوییچ \fBYYGETSTATE\fP یک برچسب \fByyNext\fP قرار گیرد یا خیر (مقدار پیش‌فرض صفر است که متناظر با نبود برچسب است). در عوض می‌توان از \fBre2c:label:start\fP برای تولید یک برچسب شروع مشخص، یا از یک بلوک صریح \fBgetstate\fP برای تولید سوییچ \fBYYGETSTATE\fP به‌طور جداگانه از بلوک تحلیل‌گر لغوی استفاده کرد. .TP .B \fBre2c:unsafe\fP, \fBre2c:flags:unsafe\fP مشابه گزینهٔ \fB\-\-no\-unsafe\fP، اما می‌تواند بر مبنای هر بلوک پیکربندی شود. اگر روی صفر تنظیم شود، از تولید دربرگیرنده‌های \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 بازنویسی می‌کند\&. مقدار صفر متناظر با سبک فرم آزاد (free\-form) برای API است. .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 بازنویسی می‌کند\&. مقدار صفر متناظر با سبک فرم آزاد (free\-form) برای 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 بازنویسی می‌کند\&. مقدار صفر متناظر با سبک فرم آزاد (free\-form) برای 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 بازنویسی می‌کند\&. مقدار صفر متناظر با سبک فرم آزاد (free\-form) برای 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 بازنویسی می‌کند\&. مقدار صفر متناظر با سبک فرم آزاد (free\-form) برای 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 عنصر پایهٔ generic API با نام \fBYYSHIFTMTAG\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYSHIFTSTAG\fP, \fBre2c:define:YYSHIFTSTAG\fP عنصر پایهٔ generic API با نام \fBYYSHIFTSTAG\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYSTAGN\fP, \fBre2c:define:YYSTAGN\fP عنصر پایهٔ generic API با نام \fBYYSTAGN\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYSTAGP\fP, \fBre2c:define:YYSTAGP\fP عنصر پایهٔ generic 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 اگر روی مقداری غیر از صفر تنظیم شود، نگاشت‌های بیتی برای گزینهٔ \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 اگر روی مقداری غیر از صفر تنظیم شود، re2v هر بار که \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 در generic API و مقایسهٔ مبتنی بر \fBYYLIMIT\fP در C pointer API) را لغو می‌کند. مقدار پیش‌فرض مقداری غیر از صفر است (بررسی تولید می‌شود). .TP .B \fBre2c:yyfill:enable\fP اگر روی صفر تنظیم شود، مانع تولید \fBYYFILL\fP (همراه با بررسی آن) می‌شود. این تنظیم باید زمانی استفاده شود که کل ورودی در یک بخش از حافظه جا شود (نیازی به بافرسازی نیست) و بررسی‌های پایان ورودی به بررسی‌های \fBYYFILL\fP وابسته نباشند (برای مثال، اگر از یک نویسهٔ نگهبان استفاده شود). برای اطمینان از این که تحلیل‌گر واژگانی (lexer) تولیدشده فراتر از انتهای ورودی را نمی‌خواند، از هشدارها (گزینهٔ \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 ابزار re2v از ساختار نحوی زیر برای عبارت‌های باقاعده استفاده می‌کند: .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\-\-invert\-captures\fP، نماد \fB(R)\fP یک گروه ضبط‌کننده یا غیرضبط‌کننده خواهد بود. .TP .B \fB(!R)\fP در صورت فعال بودن استخراج تطابق فرعی، بسته به گزینهٔ \fB\-\-invert\-captures\fP، نماد \fB(!R)\fP یک گروه غیرضبط‌کننده یا ضبط‌کننده خواهد بود. .TP .B \fBR S\fP الحاق: \fBR\fP و به دنبال آن \fBS\fP\&. .TP .B \fBR | S\fP جایگزین: \fBR یا S\fP\&. .TP .B \fBR / S\fP دید رو به جلو (Lookahead): \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 در اینجا فهرستی از کنش‌های از پیش تعریف‌شده که توسط re2v پشتیبانی می‌شوند آمده است: .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 statements) به منظور محافظت در برابر جریان کنترل ناخواسته استفاده کرد. .UNINDENT.SS "دستورالعمل‌ها (Directives)" .sp اینجا فهرست کاملی از دستورالعمل‌های پشتیبانی‌شده توسط re2v آمده است: .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 شناخته می‌شوند، با برنامه بیرونی ارتباط برقرار می‌کند. این‌که کدام پریمیتیوها باید برای یک برنامه خاص تعریف شوند به عوامل متعددی بستگی دارد، از جمله پیچیدگی عبارات منظم، نحوه نمایش ورودی، بافرینگ و استفاده از ویژگی‌های گوناگون. تمام پریمیتیوهای ضروری باید توسط کاربر در قالب ماکروها، توابع، متغیرها یا هر شکل مناسب دیگری که کد تولیدشده را از نظر نحوی و معنایی درست می‌سازد، تعریف شوند. re2v تعاریف را بررسی نمی‌کند (و نمی‌تواند بررسی کند)، بنابراین اگر چیزی وجود نداشته باشد یا نادرست تعریف شده باشد، ممکن است برنامه تولیدشده خطاهای زمان کامپایل (compile\-time) یا زمان اجرا (run\-time) داشته باشد. این راهنما مثال‌هایی از تعاریف API در رایج‌ترین موارد ارائه می‌دهد. .sp برنامه re2v دارای سه حالت (flavor) برای API است که مجموعه اصلی پریمیتیوهای استفاده‌شده توسط برنامه را مشخص می‌کنند: .INDENT 0.0 .TP .B \fBSimple API\fP این API پیش‌فرض برای بک‌اند V است. این رابط از پریمیتیوهای زیر تشکیل شده است: \fBYYINPUT\fP (که باید به عنوان توالی‌ای از واحدهای کد، مانند یک رشته تعریف شود) و \fBYYCURSOR\fP، \fBYYMARKER\fP، \fBYYCTXMARKER\fP، \fBYYLIMIT\fP (که باید به‌صورت اندیس‌هایی در \fBYYINPUT\fP تعریف شوند). .nf .fi .sp .TP .B \fBRecord API\fP رابط Record API در مواردی مفید است که وضعیت لکسر باید در یک struct ذخیره شود. این رابط با گزینه \fB\-\-api record\fP یا پیکربندی \fBre2c:api = record\fP فعال می‌شود. این API شامل متغیر \fByyrecord\fP است (این نام را می‌توان با \fBre2c:yyrecord\fP بازنویسی کرد) که باید به عنوان یک struct با فیلدهای \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 فعال می‌شود. این رابط شامل پریمیتیوهایی برای عملیات عمومی است: \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\&. .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 تنها در صورتی نیاز است که عملگر پیش‌نگری \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 یک پریمیتیو که پیش‌نمونه تابع (function 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 از نوع بولی تعریف شود که برابر با \fBtrue\fP است اگر و تنها اگر کمتر از \fBlen\fP کاراکتر ورودی باقی مانده باشد. .TP .B \fBYYEND\fP یک پریمیتیو Generic API بدون متغیر. باید به عنوان یک r\-value از نوع بولی تعریف شود که برابر با \fBtrue\fP است اگر و تنها اگر انتهای \fIمنطقی\fP ورودی فرارسیده باشد (بدون در نظر گرفتن هرگونه نویسه‌های فاصله‌پرکن یا نشانگرهای نگهبان). \fBYYEND\fP برای پیاده‌سازی نماد \fB$\fP در عبارات منظم به کار می‌رود. این پریمیتیو با \fBYYLESSTHAN\fP که برای اطمینان از فراتر نرفتن خواندن لکسر از انتهای بافر استفاده می‌شود، تفاوت دارد. .TP .B \fBYYPEEK\fP یک پریمیتیو Generic API بدون متغیر. باید به عنوان یک r\-value از نوع \fBYYCTYPE\fP تعریف شود که برابر با کاراکتر موجود در موقعیت فعلی ورودی است. .TP .B \fBYYSKIP\fP یک پریمیتیو Generic API که باید موقعیت فعلی ورودی را به اندازه یک واحد کد به جلو ببرد. .TP .B \fBYYBACKUP\fP یک پریمیتیو Generic API که باید موقعیت فعلی ورودی را ذخیره کند (تا بعداً با \fBYYRESTORE\fP بازیابی شود). .TP .B \fBYYRESTORE\fP یک پریمیتیو Generic API که باید موقعیت ورودی فعلی را به مقدار ذخیره‌شده توسط \fBYYBACKUP\fP بازیابی کند. .TP .B \fBYYBACKUPCTX\fP یک پریمیتیو Generic API که باید موقعیت ورودی فعلی را به عنوان موقعیت بافت پس‌آیند (trailing context) ذخیره کند (تا بعداً با \fBYYRESTORECTX\fP بازیابی شود). .TP .B \fBYYRESTORECTX\fP یک پریمیتیو Generic API که باید موقعیت بافت پس‌آیند ذخیره‌شده توسط \fBYYBACKUPCTX\fP را بازیابی کند..TP .B \fBYYRESTORETAG\fP یک پریمیتیو عمومی API با یک متغیر \fBtag\fP که باید موقعیت زمینهٔ پسین (trailing context) را به مقدار \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 واحد کد (code unit) جابه‌جا کند (مقدار جابه‌جایی ممکن است منفی باشد). .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 از نوع صحیح که برابر با وضعیت فعلی تحلیل‌گر لغوی است. این متغیر باید روی \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 باید در موارد ساده‌ای استفاده شود که نیازی به پر کردن مجدد بافر و ذخیرهٔ وضعیت تحلیل‌گر واژگانی نیست. گزینهٔ \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 فعال‌سازی استخراج تطبیق فرعی با گروه‌های تسخیرکنندهٔ حریصانه از چپ‌ترین حالت. نتیجه برای \fBk\fP\-امین گروه تسخیرکننده در متغیرهای \fByytl\fP و \fByytr\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 (که باید توسط کامپایلر پشتیبانی شود). re2v جدول‌های پرش را تنها در موارد پیچیده با انشعاب‌های شرطی فراوان تولید می‌کند. آستانهٔ پیچیدگی را می‌توان با پیکربندی \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 فعال‌سازی پشتیبانی از \(dqconditions\(dq مشابه Flex: چندین تحلیل‌گر واژگانی مرتبط با یکدیگر در یک بلوک. این گزینه جایگزینی برای تعیین دستی بلوک‌های مختلف re2v متصل‌شده با \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 می‌خواند. re2v فرض می‌کند که بازهٔ نویسه‌ها 0 \-\- 0xFF و اندازهٔ نویسه ۱ بایت است. .TP .B \fB\-\-empty\-class \fP تعیین نحوهٔ برخورد re2v با کلاس‌های نویسهٔ خالی. با \fBmatch\-empty\fP (پیش‌فرض)، کلاس خالی با ورودی خالی تطبیق می‌یابد (که غیرمنطقی است، اما سازگار با گذشته است). با \fBmatch\-none\fP کلاس خالی همواره در تطبیق ناموفق است. با \fBerror\fP کلاس خالی یک خطای کامپایل ایجاد می‌کند. .TP .B \fB\-\-encoding\-policy \fP تعیین نحوهٔ برخورد re2v با جانشین‌های یونیکد (Unicode surrogates). با \fBfail\fP در صورت مواجهه با یک جانشین، re2v با خطا متوقف می‌شود. با \fBsubstitute\fP برنامهٔ re2v بدون هشدار جانشین‌ها را با نقطه کد خطای 0xFFFD جایگزین می‌کند. با \fBignore\fP (پیش‌فرض) re2v با جانشین‌ها به عنوان نقاط کد معمولی رفتار می‌کند. استاندارد یونیکد بیان می‌کند که جانشین‌های مستقل نامعتبر هستند، اما کتابخانه‌ها و برنامه‌های دنیای واقعی رفتارهای متفاوتی دارند. .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 مفید است. re2v فایل \fBFILE\fP را در دایرکتوری فایل والد و در مکان‌های include مشخص‌شده با گزینهٔ \fB\-I\fP جستجو می‌کند. .TP .B \fB\-\-input \fP نام مستعار منسوخ‌شده برای \fB\-\-api\fP\&. گزینهٔ \fBdefault\fP متناظر با \fBsimple\fP است (در واقع برای بیشتر backendها پیش‌فرض است، اما نه برای همه). گزینهٔ \fBcustom\fP متناظر با \fBgeneric\fP است\&. .TP .B \fB\-\-input\-encoding \fP مشخص کردن نحوهٔ تجزیهٔ عبارت‌های باقاعده توسط re2v. با \fBascii\fP (پیش‌فرض) re2v با ورودی به عنوان کدگذاری‌شده با ASCII رفتار می‌کند: هر دنباله‌ای از واحدهای کد، دنباله‌ای از نویسه‌های ۱ بایتی مستقل است. با \fButf8\fP برنامهٔ re2v با ورودی به عنوان کدگذاری‌شده با UTF8 رفتار کرده و نویسه‌های چندبایتی را تشخیص می‌دهد. .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 خودکفا. علاوه بر این، فایل‌های ورودی را با رشته‌های مشتق‌شده از گرامر باقاعده و نتایج تطابق فشرده‌شده تولید می‌کند که برای تأیید رفتار برنامهٔ \(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 را می‌خواند. re2v فرض می‌کند که بازهٔ نویسه‌ها 0 \-\- 0xFFFF و اندازهٔ نویسه ۲ بایت است. این گزینه مستلزم \fB\-\-nested\-ifs\fP\& است. .TP .B \fB\-\-utf8 \-\-utf\-8 \-8\fP تولید یک تحلیل‌گر لغوی که ورودی را در کدگذاری UTF\-8 می‌خواند. re2v فرض می‌کند که بازهٔ نویسه‌ها 0 \-\- 0x10FFFF و اندازهٔ نویسه ۱ بایت است. .TP .B \fB\-\-utf16 \-\-utf\-16 \-x\fP تولید یک تحلیل‌گر لغوی که ورودی با کدگذاری UTF16 را می‌خواند. re2v فرض می‌کند که بازهٔ نویسه‌ها 0 \-\- 0x10FFFF و اندازهٔ نویسه ۲ بایت است. این گزینه مستلزم \fB\-\-nested\-ifs\fP\& است. .TP .B \fB\-\-utf32 \-\-unicode \-u\fP تولید یک تحلیل‌گر لغوی که ورودی با کدگذاری UTF32 را می‌خواند. re2v فرض می‌کند که بازهٔ نویسه‌ها 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 مورد استفاده توسط re2v\&. گزینهٔ \fBmoore\fP الگوریتم مور (پیش‌فرض) است. گزینهٔ \fBtable\fP الگوریتم \(dqپر کردن جدول\(dq است. هر دو الگوریتم باید تا حد برچسب‌گذاری مجدد وضعیت‌ها، DFA یکسانی تولید کنند؛ الگوریتم پر کردن جدول ساده‌تر و بسیار کُندتر بوده و به عنوان یک پیاده‌سازی مرجع عمل می‌کند. .TP .B \fB\-\-eager\-skip\fP گزینهٔ داخلی: وادار کردن تحلیل‌گر لغوی تولیدشده به پیشروی مشتاقانهٔ موقعیت ورودی \-\- بلافاصله پس از خواندن نماد ورودی. این گزینه رفتار پیش‌فرض را که در آن موقعیت ورودی با تأخیر (lazily) \-\- پس از انتقال به وضعیت بعدی \-\- پیش می‌رود تغییر می‌دهد. .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 (پیش‌فرض) نشان‌دهندهٔ الگوریتم گلدبرگ\-رادزیک، و \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) قرار دارند. در چنین مواردی فقط برچسب پایه نیاز به ردیابی دارد، و مقدار برچسب ثابت می‌تواند از روی مقدار برچسب پایه به‌علاوهٔ یک انحراف (offset) ایستا محاسبه شود. برای برچسب‌هایی که تحت شروط جایگزین یا تکرار هستند، بررسی اینکه آیا برچسب پایه مقدار عدم تطابق دارد یا خیر نیز لازم است (در این صورت برچسب ثابت نیز باید بدون در نظر گرفتن مقدار انحراف، روی عدم تطابق تنظیم شود). برای برچسب‌های موجود در الحاق بالاترین سطح، این بررسی لازم نیست زیرا آن‌ها همیشه مطابقت دارند. .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 هشدار در صورتی که یک عبارت باقاعده شامل یک ردهٔ نویسه‌ای خالی باشد. تلاش برای تطبیق یک ردهٔ نویسه‌ای خالی معنایی ندارد: همیشه باید با شکست مواجه شود. با این حال، به دلایل سازگاری با گذشته، re2v رده‌های نویسه‌ای خالی را مجاز دانسته و با آن‌ها مانند رشته‌های خالی رفتار می‌کند. برای تغییر رفتار پیش‌فرض از گزینهٔ \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 هشدار در صورتی که یک نماد گریز (escape) داده شود در حالی که نیازی به آن نبوده است. به‌طور پیش‌فرض، re2v چنین گریزهایی را بدون صدا نادیده می‌گیرد، اما این موضوع می‌تواند نشان‌دهندهٔ یک غلط املایی یا خطا در توالی گریز باشد. .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فایل‌های نحو (syntax files)\fP بنا شده است\&. یک فایل نحو، فایلی پیکربندی است که نحو زبان مقصد را تعریف می‌کند \-\- نه کل زبان، بلکه بخش کوچکی از آن را که توسط کد تولیدشده استفاده می‌شود. فایل‌های نحو re2c را بسیار انعطاف‌پذیر می‌کنند، اما نباید به عنوان جایگزینی برای پیکربندی‌های \fBre2c:\fP استفاده شوند: هدف آن‌ها تعریف نحو زبان مقصد است، نه سفارشی‌سازی یک تحلیل‌گر لغوی (lexer) خاص. تمام زبان‌های پشتیبانی‌شده دارای فایل‌های نحو پیش‌فرضی هستند که بخشی از توزیع به شمار می‌روند (زیردایرکتوری \fBinclude/syntax\fP را ببینید)؛ آن‌ها همچنین در فایل باینری re2v نیز تعبیه شده‌اند. کاربران می‌توانند یک فایل نحو سفارشی ارائه دهند که چند پیکربندی را برای یکی از زبان‌های پشتیبانی‌شده بازنویسی می‌کند، یا می‌توانند همه پیکربندی‌ها را بازتعریف کنند (در این حالت گزینه \fB\-\-lang none\fP باید استفاده شود). فایل‌های نحو شامل پیکربندی‌هایی از چهار نوع مختلف هستند: فهرست ویژگی‌ها، پیکربندی‌های زبان، پیکربندی‌های درجا و الگوهای کد. .sp \fBفهرست ویژگی‌ها (Feature lists)\fP .INDENT 0.0 .INDENT 3.5 چند پیکربندی فهرستی، ویژگی‌های گوناگون پشتیبانی‌شده توسط یک backend مشخص را تعریف می‌کنند تا در صورتی که کاربر تلاش کند یک ویژگی پشتیبانی‌نشده را فعال سازد، re2v بتواند خطای روشنی ارائه دهد: .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 فهرستی از مقصدهای تولید کد (codegen) پشتیبانی‌شده با عناصر ممکن \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 چند پیکربندی بولی ویژگی‌هایی از زبان مقصد را توصیف می‌کنند که بر تجزیه‌کننده (parser) و تولیدکننده کد re2v تأثیر می‌گذارند: .INDENT 0.0 .TP .B \fBsemicolons\fP غیرصفر در صورتی که زبان پس از دستورها (statements) از نقطه\-ویرگول استفاده کند. .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 الگوهای کد نحو زبان مقصد را تعریف می‌کنند. آن‌ها در یک زبان ویژه‌دامنه (DSL) ساده با دستور زبان صوری زیر نوشته می‌شوند: .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 است\&. متغیرها جای‌نماهایی (placeholders) هستند که در طول فاز تولید کد جایگزین می‌شوند. متغیرهای فهرست خاص هستند: هنگام بسط دادن الگوهای فهرست، re2v عبارت‌های سمت راست دونقطه را چند بار تکرار می‌کند و هر بار رخدادهای متغیر فهرست را با مقداری مخصوص این تکرار جایگزین می‌سازد. فهرست‌ها دارای کران‌های اختیاری هستند (مقادیر منفی از انتها شمارش می‌شوند، برای نمونه \fB\-1\fP به معنای آخرین عنصر است). نام‌های شرطی با یک نقطه شروع می‌شوند. هر دوی شرط‌ها و متغیرها می‌توانند محلی (مخصوص الگوی کد داده‌شده) یا سراسری (مجاز در تمام الگوهای کد) باشند. هنگامی که re2v فایل نحو را می‌خواند، بررسی می‌کند که هر الگوی کد فقط از متغیرها و شرط‌هایی استفاده کند که در آن مجاز هستند. .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 در ادامه فهرستی از تمام الگوهای کد پشتیبانی‌شده توسط re2v به همراه متغیرها و شرط‌های محلی آن‌ها آورده شده است. توجه داشته باشید که یک تعریف خاص ممکن است، اما مجبور نیست که از متغیرها و شرط‌های محلی استفاده کند. هر الگوی کد استفاده‌نشده باید روی \fB\fP تنظیم شود\&. .INDENT 0.0.TP .B \fBcode:var_local\fP اعلان یا تعریف یک متغیر محلی. متغیرهای پشتیبانی‌شده: \fBtype\fP (نوع متغیر)، \fBname\fP (نام آن) و \fBinit\fP (مقدار اولیه، در صورت وجود). شرط‌ها: \fB\&.init\fP (در صورت وجود مقداردهی اولیه، درست است). .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 (در صورتی که آرایه تغییرناپذیر باشد، درست است). .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 (در صورت وجود مقداردهی اولیه، درست است). .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 نوع عدد صحیح علامت‌دار. .TP .B \fBcode:type_uint\fP نوع عدد صحیح بدون علامت. .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 عملگر \(dqبرابر\(dq. .TP .B \fBcode:cmp_ne\fP عملگر \(dqنابرابر\(dq. .TP .B \fBcode:cmp_lt\fP عملگر \(dqکوچک‌تر از\(dq. .TP .B \fBcode:cmp_gt\fP عملگر \(dqبزرگ‌تر از\(dq. .TP .B \fBcode:cmp_le\fP عملگر \(dqکوچک‌تر یا مساوی\(dq. .TP .B \fBcode:cmp_ge\fP عملگر \(dqبزرگ‌تر یا مساوی\(dq. .TP .B \fBcode:if_then_else\fP دستور If\-then\-else با یک یا چند شاخه. متغیرهای پشتیبانی‌شده: \fBbranch\fP (یک متغیر فهرستی که خود کدی تولید نمی‌کند، اما عبارت فهرست را به تعداد شاخه‌ها بسط می‌دهد)، \fBcond\fP (شرط شاخه جاری) و \fBstmt\fP (یک متغیر فهرستی که به تمام دستورات در شاخه جاری بسط می‌یابد). شرط‌ها: \fB\&.cond\fP (در صورتی که شاخه جاری دارای شرط باشد، درست است)، \fB\&.many\fP (در صورتی که بیش از یک شاخه وجود داشته باشد، درست است). .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 یک case منفرد در switch که بازه‌ای از مقادیر را پوشش می‌دهد (احتمالاً شامل یک مقدار منفرد). متغیر پشتیبانی‌شده: \fBval\fP (یک متغیر فهرستی که به تمام مقادیر موجود در بازه بسط می‌یابد). شرط‌های پشتیبانی‌شده: \fB\&.many\fP (در صورتی که بیش از یک مقدار در بازه وجود داشته باشد، درست است) و \fB\&.char_literals\fP (در صورتی که این یک switch روی نویسه‌های حرفی باشد، درست است \-\- برخی زبان‌ها نحو ویژه‌ای برای این حالت ارائه می‌دهند). .TP .B \fBcode:switch_case_default\fP مورد پیش‌فرض switch (بخش default). .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 محاسبه‌شده. متغیرهای پشتیبانی‌شده: \fBarray\fP (جدول حاوی اطلاعات \fBgoto\fP محاسبه‌شده)، \fBindex\fP (شاخص عنصر در جدول) و \fBbase\fP (برچسب پایه، تنها در صورتی استفاده می‌شود که \fB\&.cgoto.relative\fP درست باشد). .TP .B \fBcode:cgoto:data\fP عبارت مقداردهی اولیه برای یک عنصر واحد در جدول \fBgoto\fP محاسبه‌شده. متغیرهای پشتیبانی‌شده: \fBlabel\fP (برچسبی که برای مقداردهی اولیه عنصر جاری استفاده می‌شود)، \fBtype\fP (نوع زیرین عناصر در جدول) و \fBbase\fP (برچسب پایه \- تنها در صورتی استفاده می‌شود که \fB\&.cgoto.relative\fP درست باشد). .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 باشد، درست است). .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 (در صورتی که تابع دارای آرگومان باشد، درست است) و \fB\&.retval\fP (در صورتی که مقدار بازگشتی نیاز به ذخیره شدن داشته باشد، درست است). .TP .B \fBcode:tailcall\fP دستور فراخوانی دم (tail call). متغیرهای پشتیبانی‌شده: \fBname\fP (نام تابع) و \fBarg\fP (یک متغیر فهرستی که به تمام آرگومان‌های تابع بسط می‌یابد). شرط‌ها: \fB\&.args\fP (در صورتی که تابع دارای آرگومان باشد، درست است) و \fB\&.retval\fP (در صورتی که این یک تابع غیر void باشد، درست است). .TP .B \fBcode:recursive_functions\fP بدنه برنامه با مدل کد \fB\-\-recursive\-functions\fP. متغیرهای پشتیبانی‌شده: \fBfn\fP (یک متغیر فهرستی که خود کدی تولید نمی‌کند، اما عبارت فهرست را به تعداد توابع بسط می‌دهد)، \fBfndecl\fP (اعلان تابع جاری) و \fBfndef\fP (تعریف تابع جاری)..TP .B \fBcode:fingerprint\fP اثر انگشت در بالای فایل خروجی تولیدشده. متغیرهای پشتیبانی‌شده: \fBver\fP (نسخه re2v که برای تولید این فایل استفاده شد) و \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 یک خط جدید (newline). .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 درست است اگر حلقه‌های تولیدشده توسط re2v باید دارای برچسب باشند (\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 درست است اگر re2v برای تولید کد سریع‌تر باید از بلوک‌های \(dqunsafe\(dq استفاده کند (\fB\-\-unsafe\fP، \fBre2c:unsafe = 1\fP). این تنها برای زبان‌هایی که دارای ویژگی \(dqunsafe\(dq هستند کاربرد دارد. .TP .B \fB\&.version\fP درست است اگر اثرانگشت تولیدشده باید حاوی نسخهٔ re2v باشد. .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 دو شرط نخست، تحلیل‌گر را به روشی «طبیعی» خاتمه می‌دهند: تحلیل‌گر به وضعیتی بدون هیچ گذار خروجی می‌رسد و تطبیق به‌طور خودکار متوقف می‌شود. شرط سوم، یعنی پایان ورودی، متفاوت است: این حالت ممکن است در هر وضعیتی رخ دهد و تحلیل‌گر باید قادر به مدیریت آن باشد. بررسی پایان ورودی، روند عادی کار تحلیل‌گر را متوقف می‌کند و انشعاب‌های شرطی به برنامه تولیدشده می‌افزاید؛ بنابراین لازم است تعداد این بررسی‌ها به حداقل برسد. re2v از چندین روش مختلف برای مدیریت پایان ورودی پشتیبانی می‌کند. این‌که از کدام روش استفاده شود، به پیچیدگی عبارات منظم (regular expressions)، نیاز به بافرسازی، ملاحظات کارایی و عوامل دیگر بستگی دارد. در ادامه فهرستی از این روش‌ها آورده شده است: .INDENT 0.0 .IP \(bu 2 \fBSentinel (دیده‌بان).\fP این روش نیاز به بررسی‌های پایان ورودی را به‌کلی برطرف می‌کند. این روش ساده و کارآمد است، اما محدود به مواردی است که یک نویسهٔ «دیده‌بان» طبیعی وجود داشته باشد که هرگز در ورودی معتبر رخ ندهد. این نویسه ممکن است همچنان در ورودی‌های نامعتبر وجود داشته باشد، اما نباید در عبارات منظم مجاز شمرده شود، مگر شاید به عنوان آخرین نویسهٔ یک قاعده. نویسهٔ دیده‌بان به انتهای ورودی الحاق می‌شود و نقش یک سیگنال توقف را ایفا می‌کند: هنگامی که تحلیل‌گر لغوی این نویسه را بخواند، یا یک خطای نحوی رخ داده است یا پایان ورودی فرا رسیده است. در هر دو حالت، تحلیل‌گر باید متوقف شود. این روش در صورتی به کار می‌رود که \fBYYFILL\fP با \fBre2c:yyfill:enable = 0;\fP غیرفعال شده و \fBre2c:eof\fP دارای مقدار پیش‌فرض \fB\-1\fP\& باشد. .nf .fi .sp .IP \(bu 2 \fBSentinel with bounds checks (دیده‌بان با بررسی مرزها).\fP این روش عمومی است: امکان مدیریت هر ورودی را بدون محدودیت روی عبارات منظم فراهم می‌کند. ایدهٔ این روش کاهش تعداد بررسی‌های پایان ورودی با انجام آن‌ها تنها روی نویسه‌هایی مشخص است. مشابه روش «دیده‌بان»، یکی از نویسه‌ها به عنوان «دیده‌بان» انتخاب شده و به انتهای ورودی الحاق می‌شود. با این حال، هیچ محدودیتی برای محل وقوع دیده‌بان وجود ندارد (در واقع هر نویسه‌ای می‌تواند به عنوان دیده‌بان انتخاب شود). هنگامی که تحلیل‌گر این نویسه را بخواند، علاوه بر آن بررسی مرز (bounds check) را نیز انجام می‌دهد. اگر موقعیت فعلی درون مرزها باشد، تحلیل‌گر تطبیق را از سر می‌گیرد و با نویسهٔ دیده‌بان مانند یک نویسهٔ عادی رفتار می‌کند. در غیر این صورت، \fBYYFILL\fP را فراخوانی می‌کند (مگر اینکه غیرفعال شده باشد). اگر ورودی بیشتری ارائه شود، تحلیل‌گر نویسهٔ آخر را دوباره تطبیق داده و چنان ادامه می‌دهد که گویی دیده‌بانی وجود نداشته است. در غیر این صورت، این حالت باید پایان واقعی ورودی باشد و تحلیل‌گر متوقف می‌شود. این روش زمانی استفاده می‌شود که \fBre2c:eof\fP مقداری غیرمنفی داشته باشد (باید روی مقدار عددی دیده‌بان تنظیم شود). استفاده از \fBYYFILL\fP اختیاری است. .nf .fi .sp .IP \(bu 2 \fBBounds checks with padding (بررسی مرزها با لایه‌گذاری).\fP این روش عمومی است و ممکن است سریع‌تر از روش «دیده‌بان با بررسی مرزها» باشد، اما پیچیده‌تر نیز هست. ایدهٔ این روش، افراز وضعیت‌های DFA به مؤلفه‌های قویاً متصل (SCCها) و ایجاد یک بررسی واحد برای هر SCC به تعداد نویسه‌های کافی است تا طولانی‌ترین مسیر بدون حلقه در این SCC پوشش داده شود. این کار تعداد بررسی‌ها را کاهش می‌دهد، اما برای نشانه‌های لغوی (lexemes) کوتاه در پایان ورودی مشکلی ایجاد می‌کند، زیرا بررسی به نویسه‌های کافی برای پوشش طولانی‌ترین نشانه نیاز دارد. این مشکل را می‌توان با لایه‌گذاری (padding) ورودی با چند نویسهٔ ساختگی که پسوند نشانه‌ای معتبر تشکیل نمی‌دهند (به‌طوری که تحلیل‌گر نتواند آن‌ها را تطبیق دهد) برطرف کرد. طول لایه‌گذاری باید برابر با \fBYYMAXFILL\fP باشد که با یک بلوک \fBmax\fP تولید می‌شود. اگر ورودی کافی نباشد، تحلیل‌گر \fBYYFILL\fP را فراخوانی می‌کند که باید حداقل تعداد نویسه‌های مورد نیاز را فراهم سازد یا این‌که بازگشتی نداشته باشد. این روش در صورتی به کار می‌رود که \fBYYFILL\fP فعال باشد و \fBre2c:eof\fP برابر \fB\-1\fP باشد (این پیکربندی پیش‌فرض است). .nf .fi .sp .IP \(bu 2 \fBCustom 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) برای مدیریت پایان ورودی استفاده می‌کند. این برنامه کلمات جداشده با فاصله را در یک رشتهٔ پایان‌یافته با null می‌شمارد. سنتینل همان null است: آخرین نویسهٔ هر رشتهٔ ورودی است و طبق هیچ‌یک از قواعد در میانهٔ یک جزء واژگانی (lexeme) مجاز نیست (به‌ویژه در بازه‌های نویسه‌ای که نادیده گرفتن آن آسان است گنجانده نشده است). اگر یک null در میانهٔ یک رشته رخ دهد، یک خطای نحوی است و تحلیل‌گر لغوی با قاعدهٔ پیش‌فرض \fB*\fP تطابق می‌یابد، اما فراتر از انتهای ورودی را نمی‌خواند و دچار فروپاشی (crash) نمی‌شود (از هشدار \fI\%\-Wsentinel\-in\-midrule\fP و پیکربندی \fBre2c:sentinel\fP برای بررسی این موضوع استفاده کنید). پیکربندی \fBre2c:yyfill:enable = 0;\fP از تولید بررسی‌های محدوده و فراخوانی‌های \fBYYFILL\fP جلوگیری می‌کند. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2v $INPUT \-o $OUTPUT // Expect a null\-terminated string. fn lex(yyinput string) int { mut yycursor := 0 mut count := 0 loop: /*!re2c re2c:yyfill:enable = 0; * { return \-1 } [\ex00] { return count } [a\-z]+ { count += 1; unsafe { goto loop } } [ ]+ { unsafe { goto loop } } */ } fn main() { assert lex(\(dq\e0\(dq) == 0 assert lex(\(dqone two three\e0\(dq) == 3 assert lex(\(dqf0ur\e0\(dq) == \-1 } .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 هستند. اگر شرط بررسی درست باشد، تحلیل‌گر لغوی به پایان ورودی رسیده است و باید متوقف شود (\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 // re2v $INPUT \-o $OUTPUT // Expects a null\-terminated string. fn lex(yyinput string) int { mut yycursor, mut yymarker := 0, 0 yylimit := yyinput.len \- 1 // yylimit points at the terminating null mut count := 0 loop: /*!re2c re2c:eof = 0; re2c:yyfill:enable = 0; str = [\(aq] ([^\(aq\e\e] | [\e\e][^])* [\(aq]; * { return \-1 } $ { return count } str { count += 1; unsafe { goto loop } } [ ]+ { unsafe { goto loop } } */ } fn main() { assert lex(\(dq\e0\(dq) == 0 assert lex(\(dq\(aqqu\e0tes\(aq \(aqare\(aq \(aqfine: \e\e\(aq\(aq \e0\(dq) == 3 assert lex(\(dq\(aqunterminated\e\e\(aq\e0\(dq) == \-1 } .ft P .fi .UNINDENT .UNINDENT.SS بررسی مرزها با لایه‌گذاری (Bounds checks with padding) .sp این مثال از بررسی مرزها با لایه‌گذاری برای مدیریت پایان ورودی استفاده می‌کند (این روش به‌طور پیش‌فرض فعال است). این برنامه رشته‌های محصور در نقل‌قول تکی را که با فاصله از هم جدا شده‌اند، می‌شمارد. یک لایه‌گذاری به اندازهٔ \fBYYMAXFILL\fP نویسهٔ null به انتهای ورودی افزوده شده است، که مقدار \fBYYMAXFILL\fP در آن به‌طور خودکار با یک بلوک \fBmax\fP تولید می‌شود. استفاده از null برای لایه‌گذاری الزامی نیست \-\-\- تا زمانی که نویسه‌ها پسوند یک واژهٔ (lexeme) معتبر را نسازند، می‌توان از هر نویسه‌ای استفاده کرد (در این مثال، لایه‌گذاری نباید شامل نقل‌قول تکی باشد، چرا که ممکن است با پسوند یک رشتهٔ محصور در نقل‌قول تکی اشتباه گرفته شود). یک قاعدهٔ «توقف» (\(dqstop\(dq) وجود دارد که با نخستین نویسهٔ لایه‌گذاری (null) تطبیق می‌یابد و تحلیل‌گر لغوی (lexer) را پایان می‌دهد (دقت کنید این قاعده بررسی می‌کند که آیا null در ابتدای لایه‌گذاری قرار دارد یا خیر، در غیر این صورت یک خطای نحو خواهد بود). بررسی‌های مرز تنها در برخی حالت‌ها تولید می‌شوند که توسط مؤلفه‌های قویاً همبند خودکارهٔ (اتوماتون) زیرین تعیین می‌گردند. بررسی‌ها به شکل \fB(YYLIMIT \- YYCURSOR) < n\fP یا در API عمومی به صورت \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 // re2v $INPUT \-o $OUTPUT /*!max:re2c*/ // Expects yymaxfill\-padded string. fn lex(str string) int { // Pad string with yymaxfill zeroes at the end. mut yyinput := []u8{len: str.len + yymaxfill} copy(mut &yyinput, str.bytes()) mut yycursor := 0 yylimit := yyinput.len mut count := 0 loop: /*!re2c re2c:YYFILL = \(dqreturn \-1\(dq; str = [\(aq] ([^\(aq\e\e] | [\e\e][^])* [\(aq]; [\ex00] { // Check that it is the sentinel, not some unexpected null. if yycursor \- 1 == str.len { return count } else { return \-1 } } str { count += 1; unsafe { goto loop } } [ ]+ { unsafe { goto loop } } * { return \-1 } */ } fn main() { assert lex(\(dq\(dq) == 0 assert lex(\(dq\(aqqu\e0tes\(aq \(aqare\(aq \(aqfine: \e\e\(aq\(aq \(dq) == 3 assert lex(\(dq\(aqunterminated\e\e\(aq\(dq) == \-1 assert lex(\(dq\(aqunexpected \e00 null\e\e\(aq\(dq) == \-1 } .ft P .fi .UNINDENT .UNINDENT .SS بررسی‌های سفارشی (Custom checks) .sp این مثال از یک روش سفارشی برای مدیریت پایان ورودی بر پایهٔ API عمومی استفاده می‌کند. این برنامه رشته‌های محصور در نقل‌قول تکی را که با فاصله از هم جدا شده‌اند، می‌شمارد. این برنامه مشابه مثال \fI\%sentinel\fP است، با این تفاوت که ورودی با null خاتمه نیافته است. برای جبران نبودِ نویسهٔ نگهبان (sentinel) در انتهای ورودی، \fBYYPEEK\fP بازتعریف شده است تا پیش از خواندن نویسهٔ بعدی ورودی، یک بررسی مرز انجام دهد. این روش ناکارآمد است زیرا بررسی‌ها بسیار مکرر انجام می‌شوند. اگر شرط بررسی برقرار نباشد، \fBYYPEEK\fP نویسهٔ واقعی را برمی‌گرداند؛ در غیر این صورت یک نویسهٔ نگهبان ساختگی برمی‌گرداند. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2v $INPUT \-o $OUTPUT // Returns \(dqfake\(dq terminating null if cursor has reached limit. fn peek(str string, cur int) u8 { return if cur >= str.len { u8(0) } /* fake null */ else { return str[cur] } } // Expects a string without terminating null. fn lex(str string) int { mut cur := 0 mut count := 0 loop: /*!re2c re2c:api = generic; re2c:yyfill:enable = 0; re2c:YYPEEK = \(dqpeek(str, cur)\(dq; re2c:YYSKIP = \(dqcur += 1\(dq; * { return \-1 } [\ex00] { return count } [a\-z]+ { count += 1; unsafe { goto loop } } [ ]+ { unsafe { goto loop } } */ } fn main() { assert lex(\(dq\(dq) == 0 assert lex(\(dqone two three\(dq) == 3 assert lex(\(dqf0ur\(dq) == \-1 } .ft P .fi .UNINDENT .UNINDENT.SH "پر کردن مجدد بافر (BUFFER REFILLING)" .sp نیاز به بافرسازی زمانی رخ می‌دهد که ورودی را نتوان به‌طور یک‌جا در حافظه نگاشت کرد: یا ورودی بسیار بزرگ است، یا به صورت جریانی دریافت می‌شود (مانند خواندن از یک سوکت). روش معمول در چنین مواردی، تخصیص یک بافر حافظه با اندازهٔ ثابت و پردازش ورودی در تکه‌هایی است که درون بافر جای می‌گیرند. هنگامی که تکهٔ فعلی پردازش شد، به بیرون منتقل شده و داده‌های جدید وارد می‌شوند. در عمل این موضوع تا حدی پیچیده‌تر است، زیرا وضعیت تحلیل‌گر واژگانی (lexer) تنها از یک موقعیت ورودی تشکیل نشده، بلکه شامل مجموعه‌ای از موقعیت‌های وابسته به یکدیگر است: .INDENT 0.0 .IP \(bu 2 مکان‌نما (cursor): نویسهٔ بعدی ورودی برای خوانده شدن (\fBYYCURSOR\fP در API اشاره‌گر C یا \fBYYSKIP\fP/\fBYYPEEK\fP در API عمومی) .IP \(bu 2 حد (limit): موقعیت پس از آخرین نویسهٔ در دسترس ورودی (\fBYYLIMIT\fP در API اشاره‌گر C، که به‌طور ضمنی توسط \fBYYLESSTHAN\fP در API عمومی مدیریت می‌شود) .IP \(bu 2 نشانگر (marker): موقعیت تازه‌ترین تطابق، در صورت وجود (\fBYYMARKER\fP در API پیش‌فرض یا \fBYYBACKUP\fP/\fBYYRESTORE\fP در API عمومی) .IP \(bu 2 توکن (token): آغاز تک‌واژهٔ (lexeme) کنونی (در API مربوط به re2v ضمنی است، زیرا برای عملکرد عادی لکسر نیازی به آن نیست و می‌تواند توسط کاربر تعریف و به‌روزرسانی شود) .IP \(bu 2 نشانگر زمینه (context marker): موقعیت زمینهٔ انتهایی (\fBYYCTXMARKER\fP در API اشاره‌گر C یا \fBYYBACKUPCTX\fP/\fBYYRESTORECTX\fP در API عمومی) .IP \(bu 2 متغیرهای برچسب (tag variables): موقعیت‌های زیرتطابق (تعریف‌شده با بلوک‌های \fBstags\fP و \fBmtags\fP و عملگرهای پایهٔ API عمومی شامل \fBYYSTAGP\fP/\fBYYSTAGN\fP/\fBYYMTAGP\fP/\fBYYMTAGN\fP) .UNINDENT .sp همهٔ این موارد در هر حالتی به کار نمی‌روند، اما در صورت استفاده، باید توسط \fBYYFILL\fP به‌روزرسانی شوند. تمام موقعیت‌های فعال در بخشی بین token و cursor قرار دارند، بنابراین هر چیزی که بین ابتدای بافر و token قرار دارد را می‌توان دور ریخت، بخش بین token تا limit باید به ابتدای بافر منتقل شود، و فضای خالی انتهای بافر باید با داده‌های جدید پر شود. برای جلوگیری از فراخوانی‌های مکرر \fBYYFILL\fP بهتر است تا جای ممکن نویسه‌های ورودی بیشتری پر شود (حتی اگر نویسه‌های کمتری برای از سرگیری لکسر کافی باشد). جزئیات پیاده‌سازی \fBYYFILL\fP بسته به روش مدیریت EOF مورد استفاده کمی متفاوت است: حالت قاعدهٔ EOF تا حدی ساده‌تر از حالت بررسی مرزها با پدینگ (bounds\-checking with padding) است. همچنین توجه داشته باشید که در صورت استفاده از گزینهٔ \fB\-f \-\-storable\-state\fP، دستور \fBYYFILL\fP بار معنایی کمی متفاوتی خواهد داشت (که در بخش وضعیت قابل ذخیره شرح داده شده است). .SS "YYFILL با نگه‌بان (YYFILL with sentinel)" .sp اگر از قاعدهٔ EOF استفاده شود، \fBYYFILL\fP یک سازوکار تابعی پایه (function\-like primitive) است که هیچ آرگومانی نمی‌پذیرد و مقداری را برمی‌گرداند که در برابر صفر بررسی می‌شود. فراخوانی \fBYYFILL\fP توسط شرط \fBYYLIMIT <= YYCURSOR\fP در API اشاره‌گر C و \fBYYLESSTHAN()\fP در API عمومی فعال می‌شود. مقدار بازگشتی غیرصفر به این معناست که \fBYYFILL\fP ناموفق بوده است. یک فراخوانی موفق \fBYYFILL\fP باید حداقل یک نویسه را فراهم کرده و موقعیت‌های ورودی را بر این اساس تنظیم کند. حد (Limit) همیشه باید بر روی یک موقعیت پس از آخرین موقعیت ورودی در بافر تنظیم شود، و نویسهٔ موجود در موقعیت limit باید نماد نگه‌بان (sentinel) مشخص‌شده توسط پیکربندی \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 // re2v $INPUT \-o $OUTPUT import os import strings const bufsize = 4096 struct State { file os.File mut: yyinput []u8 yycursor int yymarker int yylimit int token int eof bool } fn fill(mut st &State) int { if st.eof { return \-1 } // unexpected EOF // Error: lexeme too long. In real life can reallocate a larger buffer. if st.token < 1 { return \-2 } // Shift buffer contents (discard everything up to the current token). copy(mut &st.yyinput, st.yyinput[st.token..st.yylimit]) st.yycursor \-= st.token st.yymarker \-= st.token st.yylimit \-= st.token st.token = 0 // Fill free space at the end of buffer with new data from file. pos := st.file.tell() or { 0 } if n := st.file.read_bytes_into(u64(pos), mut st.yyinput[st.yylimit..bufsize]) { st.yylimit += n } st.yyinput[st.yylimit] = 0 // append sentinel symbol // If read less than expected, this is the end of input. st.eof = st.yylimit < bufsize return 0 } fn lex(mut yyrecord &State) int { mut count := 0 loop: yyrecord.token = yyrecord.yycursor /*!re2c re2c:api = record; re2c:eof = 0; re2c:YYFILL = \(dqfill(mut yyrecord) == 0\(dq; str = [\(aq] ([^\(aq\e\e] | [\e\e][^])* [\(aq]; * { return \-1 } $ { return count } str { count += 1; unsafe { goto loop } } [ ]+ { unsafe { goto loop } } */ } fn main() { fname := \(dqinput\(dq 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. mut fw := os.create(fname)! fw.write_string(strings.repeat_string(content, bufsize))! fw.close() count := 3 * bufsize // number of quoted strings written to file // Prepare lexer state: all offsets are at the end of buffer. mut fr := os.open(fname)! mut st := &State{ file: fr, // Sentinel at \(gayylimit\(ga offset is set to zero, which triggers YYFILL. yyinput: []u8{len: bufsize + 1}, yycursor: bufsize, yymarker: bufsize, yylimit: bufsize, token: bufsize, eof: false, } // Run the lexer. n := lex(mut &st) if n != count { panic(\(dqexpected $count, got $n\(dq) } // Cleanup: remove input file. fr.close() os.rm(fname)! } .ft P .fi .UNINDENT .UNINDENT.SS "YYFILL همراه با پدینگ (padding)" .sp در حالت پیش‌فرض (زمانی که از قاعدهٔ EOF استفاده نمی‌شود)، \fBYYFILL\fP یک سازهٔ اولیه شبه‌تابع است که یک آرگومان می‌پذیرد و هیچ مقداری را برنمی‌گرداند. فراخوانی \fBYYFILL\fP توسط شرط \fB(YYLIMIT \- YYCURSOR) < n\fP در رابط برنامه‌نویسی اشاره‌گر C و \fBYYLESSTHAN(n)\fP در رابط کاربری عمومی (generic API) راه‌اندازی می‌شود. آرگومان ارسال‌شده به \fBYYFILL\fP حداقل تعداد نویسه‌هایی است که باید فراهم شوند. اگر نتواند این نویسه‌ها را تأمین کند، \fBYYFILL\fP نباید به تحلیل‌گر لغوی (lexer) بازگردد (به همین دلیل بهتر است به صورت یک ماکرو پیاده‌سازی شود که در صورت شکست، از تابع فراخواننده بازگردد). در صورت فراخوانی موفقیت‌آمیز \fBYYFILL\fP، موقعیت حد (limit) باید روی یکی پس از آخرین موقعیت ورودی در بافر، یا در انتهای پدینگ \fBYYMAXFILL\fP تنظیم شود (در حالتی که \fBYYFILL\fP حداقل \fBn\fP نویسه را با موفقیت خوانده باشد، اما این مقدار برای پر کردن کل بافر کافی نباشد). تصاویر زیر موقعیت‌های نسبی ورودی در بافر را قبل و بعد از فراخوانی \fBYYFILL\fP نشان می‌دهند (پدینگ \fBYYMAXFILL\fP در تصویر دوم با نمادهای \fB#\fP مشخص شده است). .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C <\-\- shift \-\-> <\-\- 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 // re2v $INPUT \-o $OUTPUT import os import strings /*!max:re2c*/ const bufsize = 4096 struct State { file os.File mut: yyinput []u8 yycursor int yylimit int token int eof bool } fn fill(mut st &State, need int) int { if st.eof { return \-1 } // unexpected EOF // Error: lexeme too long. In real life can reallocate a larger buffer. if st.token < need { return \-2 } // Shift buffer contents (discard everything up to the current token). copy(mut &st.yyinput, st.yyinput[st.token..st.yylimit]) st.yycursor \-= st.token st.yylimit \-= st.token st.token = 0 // Fill free space at the end of buffer with new data from file. pos := st.file.tell() or { 0 } if n := st.file.read_bytes_into(u64(pos), mut st.yyinput[st.yylimit..bufsize]) { st.yylimit += n } // If read less than expected, this is the end of input. if st.yylimit < bufsize { st.eof = true for i := 0; i < yymaxfill; i += 1 { st.yyinput[st.yylimit + i] = 0 } st.yylimit += yymaxfill } return 0 } fn lex(mut yyrecord &State) int { mut count := 0 loop: yyrecord.token = yyrecord.yycursor /*!re2c re2c:api = record; re2c:YYFILL = \(dqr := fill(mut yyrecord, @@); if r != 0 { return r }\(dq; str = [\(aq] ([^\(aq\e\e] | [\e\e][^])* [\(aq]; [\ex00] { // Check that it is the sentinel, not some unexpected null. return if yyrecord.token == (yyrecord.yylimit \- yymaxfill) { count } else { \-1 } } str { count += 1; unsafe { goto loop } } [ ]+ { unsafe { goto loop } } * { return \-1 } */ } fn main() { fname := \(dqinput\(dq 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. mut fw := os.create(fname)! fw.write_string(strings.repeat_string(content, bufsize))! fw.close() count := 3 * bufsize // number of quoted strings written to file // Prepare lexer state: all offsets are at the end of buffer. // This immediately triggers YYFILL, as the YYLESSTHAN condition is true. mut fr := os.open(fname)! mut st := &State{ file: fr, yyinput: []u8{len: bufsize + yymaxfill}, yycursor: bufsize, yylimit: bufsize, token: bufsize, eof: false, } // Run the lexer. n := lex(mut &st) if n != count { panic(\(dqexpected $count, got $n\(dq) } // Cleanup: remove input file. fr.close() os.rm(fname)! } .ft P .fi .UNINDENT .UNINDENT.SH "ویژگی‌ها (FEATURES)" .SS "بلوک‌های چندگانه" .sp گاهی اوقات لازم است چندین تحلیل‌گر لغوی (lexer) به هم مرتبط وجود داشته باشند (برای مثال، اگر یک ماشین حالت سطح‌بالا وجود داشته باشد که بین حالت‌های مختلف لکسر جابه‌جا می‌شود). این کار را می‌توان با استفاده از چندین بلوک متصل به هم در re2v پیاده‌سازی کرد. گزینه دیگر استفاده از \fI\%start conditions\fP است\&. .sp پیاده‌سازی اتصالات بین بلوک‌ها به زبان مقصد بستگی دارد. در زبان‌هایی که دارای دستور \fBgoto\fP هستند (مانند C/C++ و Go) می‌توان همه بلوک‌ها را در یک تابع قرار داد و پیش از هر کدام یک برچسب (label) مشخص کرد. انتقال از یک بلوک به بلوک دیگر با یک \fBgoto\fP ساده انجام می‌شود\&. در زبان‌هایی که فاقد \fBgoto\fP هستند (مانند Rust)، استفاده از یک حلقه به همراه switch روی متغیر حالت ضروری است، مشابه حلقه/switch مربوط به \fByystate\fP که توسط re2v تولید می‌شود؛ یا اینکه هر بلوک داخل یک تابع قرار داده شود و از فراخوانی توابع استفاده گردد. .sp مثال زیر از چندین بلوک برای تجزیه اعداد دودویی (binary)، هشت‌هشتی (octal)، ده‌دهی (decimal) و شانزده‌شانزدهی (hexadecimal) استفاده می‌کند. هر مبنا بلوک مخصوص به خود را دارد. بلوک اولیه مبنا را تعیین کرده و کنترل را به سایر بلوک‌ها هدایت می‌کند. پیکربندی‌های مشترک در یک بلوک جداگانه در ابتدای برنامه تعریف شده‌اند؛ این پیکربندی‌ها توسط سایر بلوک‌ها به ارث برده می‌شوند. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2v $INPUT \-o $OUTPUT \-i const u32_lim = u64(1) << 32 fn parse_u32(yyinput string) ?u32 { mut yycursor, mut yymarker := 0, 0 mut n := u64(0) mut yych := 0 adddgt := fn (num u64, base u64, digit u8) u64 { n := num * base + u64(digit) return if n >= u32_lim { u32_lim } else { n } } /*!re2c re2c:yyfill:enable = 0; re2c:yych:emit = 0; end = \(dq\ex00\(dq; \(aq0b\(aq / [01] { unsafe{ goto bin } } \(dq0\(dq { unsafe{ goto oct } } \(dq\(dq / [1\-9] { unsafe{ goto dec } } \(aq0x\(aq / [0\-9a\-fA\-F] { unsafe{ goto hex } } * { return none } */ bin: /*!re2c end { unsafe{ goto end } } [01] { n = adddgt(n, 2, yyinput[yycursor\-1] \- 48); unsafe{ goto bin } } * { return none } */ oct: /*!re2c end { unsafe{ goto end } } [0\-7] { n = adddgt(n, 8, yyinput[yycursor\-1] \- 48); unsafe{ goto oct } } * { return none } */ dec: /*!re2c end { unsafe{ goto end } } [0\-9] { n = adddgt(n, 10, yyinput[yycursor\-1] \- 48); unsafe{ goto dec } } * { return none } */ hex: /*!re2c end { unsafe{ goto end } } [0\-9] { n = adddgt(n, 16, yyinput[yycursor\-1] \- 48); unsafe{ goto hex } } [a\-f] { n = adddgt(n, 16, yyinput[yycursor\-1] \- 87); unsafe{ goto hex } } [A\-F] { n = adddgt(n, 16, yyinput[yycursor\-1] \- 55); unsafe{ goto hex } } * { return none } */ end: if n < u32_lim { return u32(n) } return none } fn main() { test := fn (num ?u32, str string) { if n := parse_u32(str) { if m := num { if n != m { panic(\(dqwrong number\(dq) } } } else { if _ := num { panic(\(dqexpected none\(dq) } } } test(1234567890, \(dq1234567890\e0\(dq) test(13, \(dq0b1101\e0\(dq) test(0x7fe, \(dq0x007Fe\e0\(dq) test(0o644, \(dq0644\e0\(dq) test(none, \(dq9999999999\e0\(dq) test(none, \(dq123??\e0\(dq) } .ft P .fi .UNINDENT .UNINDENT.SS شرایط آغازین (Start conditions) .sp شرایط آغازین با گزینهٔ \fB\-\-start\-conditions\fP فعال می‌شوند. آنها روشی برای کدگذاری چندین اتوماتون مرتبط در یک بلوک re2v واحد فراهم می‌کنند. .sp هر شرط متناظر با یک اتوماتون منفرد است و یک نام یکتا دارد که توسط کاربر مشخص می‌شود و یک شمارهٔ داخلی یکتا دارد که توسط re2v\& تعریف می‌گردد. این شماره‌ها برای جابه‌جایی میان شرایط استفاده می‌شوند: کد تولیدشده از اعمال اولیهٔ \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 کدی که re2v برای شرایط تولید می‌کند بستگی به این دارد که آیا re2v از رویکرد goto/label یا رویکرد loop/switch برای کدگذاری اتوماتا استفاده می‌کند یا خیر. .sp در زبان‌هایی که دارای دستور \fBgoto\fP هستند (مانند C/C++ و Go)، شرایط به‌طور طبیعی به صورت بلوک‌هایی از کد با برچسب‌هایی به شکل \fByyc_\fP پیاده‌سازی می‌شوند، که در آن \fBcond\fP نام شرط است (پیشوند برچسب را می‌توان با \fBre2c:cond:prefix\fP تغییر داد). گذارها میان شرایط با استفاده از \fBgoto\fP و برچسب‌های شرایط پیاده‌سازی می‌شوند. پیش از تمام شرایط، re2v یک switch اولیه روی \fBYYGETSTATE\fP تولید می‌کند که به وضعیت آغازین شرط کنونی پرش می‌کند. قواعد میان‌بر \fB:=>\fP از switch اولیه گذر کرده و مستقیماً به شرط تعیین‌شده پرش می‌کنند (می‌توان از \fBre2c:cond:goto\fP برای تغییر رفتار پیش‌فرض استفاده کرد). قواعد دارای اعمال معنایی به‌طور خودکار به شرط بعدی پرش نمی‌کنند؛ این کار باید توسط کد عمل تعریف‌شده توسط کاربر انجام شود. .sp در زبان‌هایی که فاقد \fBgoto\fP هستند (مانند Rust)، ابزار re2v متغیر \fByystate\fP را برای ذخیرهٔ شماره‌های شرایط بازاستفاده می‌کند. هر شرط یک شناسهٔ عددی برابر با شمارهٔ وضعیت آغازین خود دریافت می‌کند، و سوئیچ میان شرایط هیچ تفاوتی با سوئیچ میان وضعیت‌های DFA یک شرط منفرد ندارد. نیازی به یک switch اولیهٔ جداگانه برای شرایط وجود ندارد. (از آنجا که از همین رویکرد برای پیاده‌سازی وضعیت‌های قابل‌ذخیره استفاده می‌شود، در صورتی که هم از وضعیت‌های قابل‌ذخیره و هم از شرایط استفاده شود، دستورهای \fBYYGETCOND\fP/\fBYYSETCOND\fP مازاد خواهند بود). .sp برنامهٔ زیر از شرایط آغازین برای تجزیهٔ اعداد باینری، اوکتال، دسیمال و هگزادسیمال استفاده می‌کند. یک بلوک واحد وجود دارد که در آن هر مبنا شرط مختص به خود را دارد، و شرط اولیه به همهٔ آن‌ها متصل است. متغیر تعریف‌شده توسط کاربر با نام \fBcond\fP، شمارهٔ شرط فعلی را نگهداری می‌کند؛ این متغیر با شمارهٔ شرط اولیه که با بلوک \fBconditions\fP تولید شده مقداردهی اولیه می‌شود. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2v $INPUT \-o $OUTPUT \-ci /*!conditions:re2c*/ const u32_lim = u64(1) << 32 fn parse_u32(yyinput string) ?u32 { mut yycursor, mut yymarker := 0, 0 mut n := u64(0) mut yycond := YYCONDTYPE.yycinit adddgt := fn (num u64, base u64, digit u8) u64 { n := num * base + u64(digit) return if n >= u32_lim { u32_lim } else { n } } /*!re2c re2c:yyfill:enable = 0; <*> * { return none } \(aq0b\(aq / [01] :=> bin \(dq0\(dq :=> oct \(dq\(dq / [1\-9] :=> dec \(aq0x\(aq / [0\-9a\-fA\-F] :=> hex \(dq\ex00\(dq { return if n < u32_lim { u32(n) } else { none } } [01] { n = adddgt(n, 2, yyinput[yycursor\-1] \- 48); unsafe{ goto yyc_bin } } [0\-7] { n = adddgt(n, 8, yyinput[yycursor\-1] \- 48); unsafe{ goto yyc_oct } } [0\-9] { n = adddgt(n, 10, yyinput[yycursor\-1] \- 48); unsafe{ goto yyc_dec } } [0\-9] { n = adddgt(n, 16, yyinput[yycursor\-1] \- 48); unsafe{ goto yyc_hex } } [a\-f] { n = adddgt(n, 16, yyinput[yycursor\-1] \- 87); unsafe{ goto yyc_hex } } [A\-F] { n = adddgt(n, 16, yyinput[yycursor\-1] \- 55); unsafe{ goto yyc_hex } } */ } fn main() { test := fn (num ?u32, str string) { if n := parse_u32(str) { if m := num { if n != m { panic(\(dqwrong number\(dq) } } } else { if _ := num { panic(\(dqexpected none\(dq) } } } test(1234567890, \(dq1234567890\e0\(dq) test(13, \(dq0b1101\e0\(dq) test(0x7fe, \(dq0x007Fe\e0\(dq) test(0o644, \(dq0644\e0\(dq) test(none, \(dq9999999999\e0\(dq) test(none, \(dq123??\e0\(dq) } .ft P .fi .UNINDENT .UNINDENT.SS "وضعیت ذخیره‌پذیر (Storable state)" .sp با گزینهٔ \fB\-\-storable\-state\fP، ابزار re2v یک تحلیل‌گر لغوی (lexer) تولید می‌کند که می‌تواند وضعیت فعلی خود را ذخیره کند، به فراخواننده بازگردد، و بعداً عملیات را دقیقاً از همان‌جایی که متوقف شده بود از سر بگیرد. حالت پیش‌فرض عملکرد در re2v یک مدل «کِششی» (\(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 به عنوان بخشی از وضعیت ماندگار تحلیل‌گر لغوی. متغیر \fBstate\fP باید با مقدار \fB\-1\fP مقداردهی اولیه شود. .IP \(bu 2 دستور \fBYYFILL\fP باید به جای تلاش برای تأمین ورودی بیشتر، به برنامهٔ بیرونی بازگردد. کد بازگشتی باید نشان دهد که تحلیل‌گر لغوی به ورودی بیشتری نیاز دارد. .IP \(bu 2 برنامهٔ بیرونی باید موقعیت‌هایی را که تحلیل‌گر لغوی به ورودی بیشتری نیاز دارد تشخیص داده و واکنش مناسب نشان دهد. .IP \(bu 2 استفادهٔ اختیاری از بلوک \fBgetstate\fP برای تولید switch مربوط به \fBYYGETSTATE\fP به‌صورت مجزا از تحلیل‌گر لغوی اصلی. این ویژگی تنها برای زبان‌هایی کار می‌کند که دارای \fBgoto\fP هستند (نه در حالت \fB\-\-loop\-switch\fP). .IP \(bu 2 استفاده از \fBre2c:eof\fP و روش \fI\%sentinel with bounds checks\fP برای مدیریت انتهای ورودی. روش مبتنی بر فاصله‌گذاری (padding) ممکن است کار نکند، چرا که زمان الحاق padding نامشخص است: انتهای فعلی ورودی ممکن است انتهای نهایی ورودی نباشد، و الحاق زودهنگام padding ممکن است یک نشانهٔ لغوی حریصانه (greedy lexeme) را که بخشی از آن خوانده شده است قطع کند. افزون بر این، با توجه به منطق سطح‌بالای برنامه، دریافت ورودی بیشتر ممکن است به پردازش نشانهٔ لغوی در انتهای بافر وابسته باشد (که از پیش به دلیل شرط انتهای ورودی مسدود شده است). .UNINDENT .sp در اینجا نمونه‌ای از یک تحلیل‌گر لغوی مدل «رانشی» (\(dqpush\(dq) آورده شده است که خواندن بسته‌ها از یک سوکت را شبیه‌سازی می‌کند. تحلیل‌گر لغوی تا زمانی که با انتهای ورودی مواجه شود در حلقه اجرا می‌شود و به تابع فراخواننده بازمی‌گردد. تابع فراخواننده با «ارسال» بستهٔ بعدی، ورودی بیشتری را فراهم کرده و تحلیل لغوی را از سر می‌گیرد. این فرآیند زمانی متوقف می‌شود که همهٔ بسته‌ها ارسال شده باشند، یا خطایی رخ دهد. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2v \-f $INPUT \-o $OUTPUT import log import os // Use a small buffer to cover the case when a lexeme doesn\(aqt fit. // In real world use a larger buffer. const bufsize = 10 struct State { mut: file os.File yyinput []u8 yycursor int yymarker int yylimit int token int yystate int } enum Status { lex_end lex_ready lex_waiting lex_bad_packet lex_big_packet } fn fill(mut st &State) Status { shift := st.token used := st.yylimit \- st.token free := bufsize \- used // Error: no space. In real life can reallocate a larger buffer. if free < 1 { return .lex_big_packet } // Shift buffer contents (discard already processed data). copy(mut &st.yyinput, st.yyinput[shift..shift+used]) st.yycursor \-= shift st.yymarker \-= shift st.yylimit \-= shift st.token \-= shift // Fill free space at the end of buffer with new data. pos := st.file.tell() or { 0 } if n := st.file.read_bytes_into(u64(pos), mut st.yyinput[st.yylimit..bufsize]) { st.yylimit += n } st.yyinput[st.yylimit] = 0 // append sentinel symbol return .lex_ready } fn lex(mut yyrecord &State, mut recv &int) Status { mut yych := u8(0) /*!getstate:re2c*/ loop: yyrecord.token = yyrecord.yycursor /*!re2c re2c:api = record; re2c:eof = 0; re2c:YYFILL = \(dqreturn .lex_waiting\(dq; packet = [a\-z]+[;]; * { return .lex_bad_packet } $ { return .lex_end } packet { recv += 1; unsafe{ goto loop } } */ } fn test(expect Status, packets []string) { // Create a pipe (open the same file for reading and writing). fname := \(dqpipe\(dq mut fw := os.create(fname) or { panic(\(dqcannot create file\(dq) } mut fr := os.open(fname) or { panic(\(dqcannot open file\(dq) } // Initialize lexer state: \(gastate\(ga value is \-1, all offsets are at the end // of buffer. mut st := &State{ file: fr, // Sentinel at \(gayylimit\(ga offset is set to zero, which triggers YYFILL. yyinput: []u8{len: bufsize + 1}, yycursor: bufsize, yymarker: bufsize, yylimit: bufsize, token: bufsize, yystate: \-1, } // 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. mut status := Status.lex_ready mut send := 0 mut recv := 0 for { status = lex(mut &st, mut &recv) if status == .lex_end { break } else if status == .lex_waiting { if send < packets.len { log.debug(\(dqsending packet $send\(dq) fw.write_string(packets[send]) or { panic(\(dqcannot write to file\(dq) } fw.flush() send += 1 } status = fill(mut &st) log.debug(\(dqfilled buffer $st.yyinput, status $status\(dq) if status != .lex_ready { break } } else if status == .lex_bad_packet { break } } // Check results. if status != expect || (status == .lex_end && recv != send) { panic(\(dqexpected $expect with $send packet(s), got $status with $recv packet(s)\(dq) } // Cleanup: remove input file. fr.close() fw.close() os.rm(fname) or { panic(\(dqcannot remove file\(dq) } } fn main() { //log.set_level(.debug) test(.lex_end, []) test(.lex_end, [\(dqzero;\(dq, \(dqone;\(dq, \(dqtwo;\(dq, \(dqthree;\(dq, \(dqfour;\(dq]) test(.lex_bad_packet, [\(dq??;\(dq]) test(.lex_big_packet, [\(dqlooooooooooooong;\(dq]) } .ft P .fi .UNINDENT .UNINDENT.SS بلوک‌های با قابلیت استفاده مجدد (Reusable blocks) .sp بلوک‌های با قابلیت استفاده مجدد به فرم \fB/*!rules:re2c[:] ... */\fP یا \fB%{rules[:] ... %}\fP را می‌توان به هر تعداد بار دوباره استفاده کرد و با دیگر بلوک‌های re2v ترکیب نمود. بخش \fB\fP اختیاری است. یک بلوک rules می‌تواند در یک بلوک یا دستورالعمل \fBuse\fP به کار رود. کدِ مربوط به یک بلوک rules در هر نقطه از استفاده تولید می‌شود. .sp بلوک‌های use با \fB/*!use:re2c[:] ... */\fP یا \fB%{use[:] ... %}\fP\& تعریف می‌شوند. بخش \fB\fP اختیاری است: اگر مشخص نشده باشد، بلوک rules مرتبط، نزدیک‌ترین بلوک پیشین خواهد بود (خواه نام‌دار باشد یا بی‌نام). یک بلوک use می‌تواند تعاریف نام‌دار، پیکربندی‌ها و قواعد مخصوص به خود را اضافه کند. یک مورد کاربرد مهم برای بلوک‌های use، تحلیل‌گر لغوی (lexer) است که از چندین کدگذاری ورودی پشتیبانی می‌کند: همان بلوک rules چندین بار با پیکربندی‌های مختصِ کدگذاری مجدداً استفاده می‌شود (مثال زیر را ببینید). .sp دستورالعمل درون‌بلوکی \fB!use:;\fP می‌تواند از داخل یک بلوک re2v استفاده شود. این دستورالعمل، بلوک ارجاع‌داده‌شده‌ی \fB\fP را در بلوک فعلی ادغام می‌کند. اگر برخی از قواعد و پیکربندی‌های ادغام‌شده با موارد از پیش تعریف‌شده هم‌پوشانی داشته باشند، تداخل‌ها به شیوه معمول برطرف می‌شوند: نخستین قاعده اولویت دارد و آخرین پیکربندی بر موارد قبلی اعمال می‌شود. یک استثنا، قواعد ویژه \fB*\fP، \fB$\fP و (در حالت شرطی) \fB\fP هستند که برای آن‌ها تعریف محلی درون بلوک، بر هر تعریف موروثی اولویت دارد. دستورالعمل use به شما امکان می‌دهد بلوک‌های مختلف re2v را در یک بلوک با هم ترکیب کنید (مثال زیر را ببینید). .sp بلوک‌های نام‌دار و دستورالعمل درون‌بلوکی use در نگارش 2.2 از re2v اضافه شدند. از آن نگارش به بعد، بلوک‌های با قابلیت استفاده مجدد به صورت پیش‌فرض مجاز هستند (به گزینه خاصی نیاز نیست). پیش از نگارش 2.2، حالت استفاده مجدد با گزینه \fB\-r \-\-reusable\fP فعال می‌شد. پیش از نگارش 1.2، امکان ترکیب بلوک‌های با قابلیت استفاده مجدد با بلوک‌های عادی وجود نداشت. .SS مثالی از یک دستورالعمل \fB!use\fP (Example of a !use directive) .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2v $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. enum What { color fish dunno } /*!rules:re2c:colors * { panic(\(dqeh!\(dq) } \(dqred\(dq | \(dqsalmon\(dq | \(dqmagenta\(dq { return .color } */ /*!rules:re2c:fish * { panic(\(dqoh!\(dq) } \(dqhaddock\(dq | \(dqsalmon\(dq | \(dqeel\(dq { return .fish } */ fn lex(yyinput string) What { mut yycursor, mut yymarker := 0, 0 /*!re2c re2c:yyfill:enable = 0; !use:fish; !use:colors; * { return .dunno } // overrides inherited \(aq*\(aq rules */ } fn main() { 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 // re2v $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 0 } * { return 1 } */ fn lex_utf8(yyinput []u8) int { mut yycursor, mut yymarker := 0, 0 /*!use:re2c re2c:encoding:utf8 = 1; re2c:YYCTYPE = u8; // the default */ } fn lex_utf32(yyinput []u32) int { mut yycursor, mut yymarker := 0, 0 /*!use:re2c re2c:encoding:utf32 = 1; re2c:YYCTYPE = u32; */ } fn main() { s8 := [u8(0xe2), u8(0x88), u8(0x80), u8(0x78), u8(0x20), u8(0xe2), u8(0x88), u8(0x83), u8(0x79)] s32 := [u32(0x2200), u32(0x78), u32(0x20), u32(0x2203), u32(0x79)] assert lex_utf8(s8) == 0 assert lex_utf32(s32) == 0 } .ft P .fi .UNINDENT .UNINDENT .SS استخراج زیرتطابق (Submatch extraction) .sp ابزار re2v دو گزینه برای استخراج زیرتطابق دارد. .INDENT 0.0 .TP .B \fBTags\fP گزینهٔ نخست، استفاده از \fIبرچسب‌ها (tags)\fP مستقل به شکل \fB@stag\fP یا \fB#mtag\fP است، که در آن \fBstag\fP و \fBmtag\fP نام‌های اختیاری تعریف‌شده توسط کاربر هستند. برچسب‌ها با گزینهٔ \fB\-T \-\-tags\fP یا پیکربندی \fBre2c:tags = 1\fP فعال می‌شوند. از نظر معنایی، برچسب‌ها نشانگرهای موقعیت هستند: می‌توان آن‌ها را در هر کجای یک عبارت منظم درج کرد و به موقعیت مربوطه (یا چندین موقعیت) در رشتهٔ ورودی مقید می‌شوند. \fIS\-tagها\fP به آخرین موقعیت تطبیق‌یافته مقید می‌شوند، و \fIm\-tagها\fP به فهرستی از موقعیت‌ها مقید می‌گردند (ممکن است در زیرعبارت‌های تکرار استفاده شوند، جایی که یک موقعیت منفرد در عبارت منظم با چندین موقعیت در رشتهٔ ورودی مطابقت دارد). همهٔ برچسب‌ها باید توسط کاربر، به‌صورت دستی یا با کمک بلوک‌های \fBsvars\fP و \fBmvars\fP تعریف شوند. اگر بیش از یک روش برای تطبیق برچسب‌ها با ورودی وجود داشته باشد، ابهام با استفاده از راهبرد رفع ابهام حریصانهٔ چپ‌ترین (leftmost greedy) حل می‌شود. .TP .B \fBCaptures\fP گزینهٔ دوم استفاده از \fIگروه‌های گیرانداز (capturing groups)\fP\& است. آن‌ها با گزینهٔ \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، ابزار re2v متغیرهای \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\%Tagged Deterministic Finite Automata with Lookahead\fP\& ترجمه می‌شوند. ایدهٔ اصلی TDFA به حداقل رساندن بار اضافی (overhead) بر روی استخراج زیرتطابق است. در حالت حدی، اگر هیچ برچسب یا گیراندازی در یک عبارت منظم وجود نداشته باشد، TDFA صرفاً یک DFA معمولی است. اگر تعداد برچسب‌ها متوسط باشد، بار اضافی به سختی قابل توجه خواهد بود. اتوماتون TDFA تولیدشده از تعدادی \fIمتغیر برچسب\fP استفاده می‌کند که مستقیماً به برچسب‌ها نگاشت نمی‌شوند: یک متغیر واحد ممکن است برای برچسب‌های متفاوتی استفاده شود، و یک برچسب ممکن است برای نگهداری تمام مقادیر احتمالی خود به چندین متغیر نیاز داشته باشد. در نهایت ابهام برطرف می‌شود و تنها یک متغیر نهایی به ازای هر برچسب باقی می‌ماند. متغیرهای برچسب باید با استفاده از بلوک‌های \fBstags\fP یا \fBmtags\fP تعریف شوند. اگر وضعیت تحلیل‌گر لغوی (lexer state) ذخیره می‌شود، متغیرهای برچسب نیز باید بخشی از آن باشند. آن‌ها همچنین باید توسط \fBYYFILL\fP\& به‌روزرسانی شوند. .sp برچسب‌های S\-tag از عملیات‌های زیر پشتیبانی می‌کنند: .INDENT 0.0 .IP \(bu 2 ذخیرهٔ موقعیت ورودی در یک s\-tag: عبارت \fBt = YYCURSOR\fP با API اشاره‌گر C یا یک عملیات تعریف‌شده توسط کاربر \fBYYSTAGP(t)\fP با API عمومی .IP \(bu 2 ذخیرهٔ مقدار پیش‌فرض در یک s\-tag: مقدار \fBt = NULL\fP با API اشاره‌گر C یا یک عملیات تعریف‌شده توسط کاربر \fBYYSTAGN(t)\fP با API عمومی .IP \(bu 2 کپی کردن یک s\-tag در دیگری: \fBt1 = t2\fP .UNINDENT .sp برچسب‌های M\-tag از عملیات‌های زیر پشتیبانی می‌کنند: .INDENT 0.0 .IP \(bu 2 افزودن موقعیت ورودی به یک m\-tag: عملیات تعریف‌شده توسط کاربر \fBYYMTAGP(t)\fP با هر دو API پیش‌فرض و عمومی .IP \(bu 2 افزودن مقدار پیش‌فرض به یک m\-tag: عملیات تعریف‌شده توسط کاربر \fBYYMTAGN(t)\fP با هر دو API پیش‌فرض و عمومی .IP \(bu 2 کپی کردن یک m\-tag در دیگری: \fBt1 = t2\fP .UNINDENT .sp برچسب‌های S\-tag می‌توانند به‌صورت مقادیر اسکالر (اشاره‌گرها یا آفست‌ها) پیاده‌سازی شوند. برچسب‌های M\-tag به نمایشی پیچیده‌تر نیاز دارند، چرا که باید دنباله‌ای از مقادیر برچسب را ذخیره کنند. ساده‌ترین و ناکارآمدترین نمایش برای یک m\-tag، یک فهرست (آرایه، بردار) از مقادیر برچسب است؛ نمایشی کارآمدتر، ذخیرهٔ تمام m\-tagها در یک درخت پیشوندی (prefix\-tree) است که به‌صورت آرایه‌ای از گره‌های \fB(v, p)\fP نمایش داده می‌شود، که در آن \fBv\fP مقدار برچسب و \fBp\fP اشاره‌گری به گره والد است. .sp در اینجا یک نمونهٔ ساده از به‌کارگیری s\-tagها برای تجزیهٔ نگارش‌های معنایی متشکل از سه مؤلفهٔ عددی آورده شده است: major، minor و patch (مورد آخر اختیاری است). برای مشاهدهٔ مثالی پیچیده‌تر که از \fBYYFILL\fP\& استفاده می‌کند، بخش زیر را ببینید. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2v $INPUT \-o $OUTPUT struct SemVer { major int minor int patch int } fn s2n(s string) int { // convert pre\-parsed string to number mut n := 0 for c in s { n = n * 10 + int(c \- 48) } return n } fn parse(yyinput string) ?SemVer { mut yycursor, mut yymarker := 0, 0 // Final tag variables available in semantic action. /*!svars:re2c format = \(aqmut @@ := 0\en\(aq; */ // Intermediate tag variables used by the lexer (must be autogenerated). /*!stags:re2c format = \(aqmut @@ := \-1\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] { return SemVer{ major: s2n(yyinput[t1..t2]), minor: s2n(yyinput[t3..t4]), patch: if t5 == \-1 { 0 } else { s2n(yyinput[t5..yycursor \- 1]) } } } * { return none } */ } fn main() { test := fn (result ?SemVer, expect ?SemVer) { if r := result { if e := expect { if r != e { panic(\(dqexpected $e, got $r\(dq) } } } else { if _ := result { panic(\(dqexpected none\(dq) } } } test(parse(\(dq23.34\e0\(dq), SemVer{23, 34, 0}) test(parse(\(dq1.2.9999\e0\(dq), SemVer{1, 2, 9999}) test(parse(\(dq1.a\e0\(dq), none) } .ft P .fi .UNINDENT .UNINDENT.sp در اینجا مثال پیچیده‌تری از به‌کارگیری s\-tagها با \fBYYFILL\fP برای تجزیه فایلی با نسخه‌بندی‌های معنایی (semantic versions) جداشده با خط جدید ارائه شده است. متغیرهای برچسب، بخشی از وضعیت تحلیل‌گر لغوی (lexer) هستند و در \fBYYFILL\fP درست مانند سایر موقعیت‌های ورودی تنظیم می‌شوند. توجه داشته باشید که این کار برای s\-tagها الزامی است، زیرا مقادیر آن‌ها پس از جابه‌جایی محتویات بافر باطل می‌شوند. ممکن است در یک پیاده‌سازی سفارشی که متغیرهای برچسب به‌جای بافر، آفست‌ها را نسبت به ابتدای رشته ورودی ذخیره می‌کنند نیازی به این کار نباشد؛ مانند آنچه ممکن است برای m\-tagها صدق کند. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2v $INPUT \-o $OUTPUT import arrays import os import strings const bufsize = 4096 const tag_none = \-1 struct State { file os.File mut: yyinput []u8 yycursor int yymarker int yylimit int token int // 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\et@@ int\en\(dq; */ eof bool } struct SemVer { major int minor int patch int } fn s2n(s []u8) int { // convert pre\-parsed string to number mut n := 0 for c in s { n = n * 10 + int(c \- 48) } return n } fn fill(mut st &State) int { if st.eof { return \-1 } // unexpected EOF // Error: lexeme too long. In real life can reallocate a larger buffer. if st.token < 1 { return \-2 } // Shift buffer contents (discard everything up to the current token). copy(mut &st.yyinput, st.yyinput[st.token..st.yylimit]) st.yycursor \-= st.token st.yymarker \-= st.token st.yylimit \-= st.token // Tag variables need to be shifted like other input positions. The check // for \-1 is only needed if some tags are nested inside of alternative or // repetition, so that they can have \-1 value. /*!stags:re2c format = \(dq\etif st.@@ != \-1 { st.@@ \-= st.token }\en\(dq; */ st.token = 0 // Fill free space at the end of buffer with new data from file. pos := st.file.tell() or { 0 } if n := st.file.read_bytes_into(u64(pos), mut st.yyinput[st.yylimit..bufsize]) { st.yylimit += n } st.yyinput[st.yylimit] = 0 // append sentinel symbol // If read less than expected, this is the end of input. st.eof = st.yylimit < bufsize return 0 } fn parse(mut st &State) ?[]SemVer { // Final tag variables available in semantic action. /*!svars:re2c format = \(dqmut @@ := tag_none\en\(dq; */ mut vers := []SemVer{} loop: st.token = st.yycursor /*!re2c re2c:api = record; re2c:yyrecord = st; re2c:YYFILL = \(dqfill(mut st) == 0\(dq; re2c:tags = 1; re2c:eof = 0; num = [0\-9]+; num @t1 \(dq.\(dq @t2 num @t3 (\(dq.\(dq @t4 num)? [\en] { ver := SemVer { major: s2n(st.yyinput[st.token..t1]), minor: s2n(st.yyinput[t2..t3]), patch: if t4 == \-1 { 0 } else { s2n(st.yyinput[t4..st.yycursor \- 1]) } } vers = arrays.concat(vers, ver) unsafe { goto loop } } $ { return vers } * { return none } */ } fn main() { fname := \(dqinput\(dq content := \(dq1.22.333\en\(dq; // Prepare input file: a few times the size of the buffer, containing // strings with zeroes and escaped quotes. mut fw := os.create(fname)! fw.write_string(strings.repeat_string(content, bufsize))! fw.close() // Prepare lexer state: all offsets are at the end of buffer. mut fr := os.open(fname)! mut st := &State{ file: fr, // Sentinel at \(gayylimit\(ga offset is set to zero, which triggers YYFILL. yyinput: []u8{len: bufsize + 1}, yycursor: bufsize, yymarker: bufsize, yylimit: bufsize, token: bufsize, eof: false, } // Run the lexer. expect := []SemVer{len: bufsize, init: SemVer{1, 22, 333}} result := parse(mut &st) or { panic(\(dqparse failed\(dq) } if result != expect { panic(\(dqerror\(dq) } // Cleanup: remove input file. fr.close() os.rm(fname)! } .ft P .fi .UNINDENT .UNINDENT .sp در اینجا مثالی از به‌کارگیری گروه‌های ضبط (capturing groups) برای تجزیه نسخه‌بندی‌های معنایی آمده است. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2v $INPUT \-o $OUTPUT struct SemVer { major int minor int patch int } fn s2n(s string) int { // convert pre\-parsed string to number mut n := 0 for c in s { n = n * 10 + int(c \- 48) } return n } fn parse(yyinput string) ?SemVer { mut yycursor, mut yymarker := 0, 0 // Final tag variables available in semantic action. /*!svars:re2c format = \(aqmut @@ := 0\en\(aq; */ // Intermediate tag variables used by the lexer (must be autogenerated). /*!stags:re2c format = \(aqmut @@ := 0\en\(aq; */ /*!re2c re2c:yyfill:enable = 0; re2c:captvars = 1; num = [0\-9]+; (num) \(dq.\(dq (num) (\(dq.\(dq num)? [\ex00] { _ := yytl0; _ := yytr0 // some variables are unused return SemVer { major: s2n(yyinput[yytl1..yytr1]), minor: s2n(yyinput[yytl2..yytr2]), patch: if yytl3 == \-1 {0} else {s2n(yyinput[yytl3 + 1..yytr3])} } } * { return none } */ } fn main() { test := fn (result ?SemVer, expect ?SemVer) { if r := result { if e := expect { if r != e { panic(\(dqexpected $e, got $r\(dq) } } } else { if _ := result { panic(\(dqexpected none\(dq) } } } test(parse(\(dq23.34\e0\(dq), SemVer{23, 34, 0}) test(parse(\(dq1.2.9999\e0\(dq), SemVer{1, 2, 9999}) test(parse(\(dq1.a\e0\(dq), none) } .ft P .fi .UNINDENT .UNINDENT.sp در اینجا مثالی از به‌کارگیری m\-tagها برای تجزیهٔ یک نسخه با تعداد متغیری از مؤلفه‌ها آمده است. متغیرهای برچسب در یک trie ذخیره می‌شوند. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2v $INPUT \-o $OUTPUT import arrays const mtag_root = \-1 const tag_none = \-1 // 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). struct MtagElem { elem int pred int } type MtagTrie = []MtagElem // Append a single value to an m\-tag history. fn add_mtag(mut trie MtagTrie, mtag int, value int) int { trie = arrays.concat(trie, MtagElem{value, mtag}) return trie.len \- 1 } // Recursively unwind tag histories and collect version components. fn unwind(trie MtagTrie, x int, y int, str string) []int { // Reached the root of the m\-tag tree, stop recursion. if x == mtag_root && y == mtag_root { return [] } // Unwind history further. mut result := unwind(trie, trie[x].pred, trie[y].pred, str) // Get tag values. Tag histories must have equal length. if x == mtag_root || y == mtag_root { panic(\(dqtag histories have different length\(dq) } ex := trie[x].elem ey := trie[y].elem if ex != tag_none && ey != tag_none { // Both tags are valid string indices, extract component. result = arrays.concat(result, s2n(str[ex..ey])) } else if !(ex == tag_none && ey == tag_none) { panic(\(dqboth tags should be tag_none\(dq) } return result } fn s2n(s string) int { // convert pre\-parsed string to number mut n := 0 for c in s { n = n * 10 + int(c \- 48) } return n } fn parse(yyinput string) ?[]int { mut yycursor, mut yymarker := 0, 0 // mut trie := []MtagElem{} mut trie := MtagTrie{} // Final tag variables available in semantic action. /*!svars:re2c format = \(aqmut @@ := tag_none\en\(aq; */ /*!mvars:re2c format = \(dqmut @@ := mtag_root\en\(dq; */ // Intermediate tag variables used by the lexer (must be autogenerated). /*!stags:re2c format = \(aqmut @@ := tag_none\en\(aq; */ /*!mtags:re2c format = \(dqmut @@ := mtag_root\en\(dq; */ /*!re2c re2c:tags = 1; re2c:yyfill:enable = 0; re2c:YYMTAGP = \(dq@@ = add_mtag(mut trie, @@, yycursor)\(dq; re2c:YYMTAGN = \(dq@@ = add_mtag(mut trie, @@, tag_none)\(dq; num = [0\-9]+; @t1 num @t2 (\(dq.\(dq #t3 num #t4)* [\ex00] { mut ver := []int{} ver = arrays.concat(ver, s2n(yyinput[t1..t2])) ver = arrays.append(ver, unwind(trie, t3, t4, yyinput)) return ver } * { return none } */ } fn main() { test := fn (result ?[]int, expect ?[]int) { if r := result { if e := expect { if r != e { panic(\(dqexpected $e, got $r\(dq) } } } else { if _ := result { panic(\(dqexpected none\(dq) } } } test(parse(\(dq1\e0\(dq), [1]) test(parse(\(dq1.2.3.4.5.6.7\e0\(dq), [1, 2, 3, 4, 5, 6, 7]) test(parse(\(dq1.\e0\(dq), none) } .ft P .fi .UNINDENT .UNINDENT.SS پشتیبانی از کدگذاری (Encoding support) .sp درک تفاوت میان \fBنقطه‌کدها (code points)\fP و \fBواحدهای کد (code units)\fP\& ضروری است. نقطه‌کد یک شناسه عددی برای یک نماد است. واحد کد کوچک‌ترین واحد ذخیره‌سازی در متن کدگذاری‌شده است. یک نقطه‌کد منفرد ممکن است با یک یا چند واحد کد نشان داده شود. در کدگذاری با طول ثابت، تمام نقطه‌کدها با تعداد یکسانی از واحدهای کد نمایش داده می‌شوند. در کدگذاری با طول متغیر، ممکن است نقطه‌کدها با تعداد متفاوتی از واحدهای کد نشان داده شوند. توجه داشته باشید که قاعدهٔ «هر نویسه» \fB[^]\fP با هر نقطه‌کدی مطابقت دارد، اما لزوماً با هر واحد کدی تطبیق پیدا نمی‌کند (تنها راه تطبیق با هر واحد کد صرف‌نظر از نوع کدگذاری، قاعدهٔ پیش‌فرض \fB*\fP است). تحلیل‌گر لغوی تولیدشده با جریانی از واحدهای کد کار می‌کند: \fByych\fP یک واحد کد را ذخیره می‌کند و \fBYYCTYPE\fP نوع واحد کد است. از سوی دیگر، عبارت‌های منظم بر اساس نقطه‌کدها مشخص می‌شوند. هنگامی که re2v عبارت‌های منظم را به اتوماتا کامپایل می‌کند، نقطه‌کدها را به واحدهای کد ترجمه می‌نماید. این فرایند معمولاً یک نگاشت ساده نیست: در کدگذاری‌های با طول متغیر، یک محدوده نقطه‌کد ممکن است به یک گراف پیچیده از واحدهای کد ترجمه شود. کدگذاری‌های زیر پشتیبانی می‌شوند: .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 فایل‌های الحاقی \fBinclude/unicode_blocks.re\fP، \fBinclude/unicode_categories.re\fP و \fBinclude/unicode_properties.re\fP تعاریف re2v را برای بلوک‌ها، دسته‌بندی‌ها و ویژگی‌های شرح‌داده‌شده در استاندارد یونیکد فراهم می‌کنند. .sp گزینهٔ \fB\-\-input\-encoding\fP کدگذاری فایل مبدأ را مشخص می‌کند که می‌تواند برای فعال‌سازی لیترال‌های یونیکد در عبارت‌های منظم استفاده شود. به عنوان مثال \fB\-\-input\-encoding utf8\fP به re2v اعلام می‌کند که فایل منبع با کدگذاری UTF8 است (این با \fB\-\-utf8\fP که کدگذاری متن ورودی را تعیین می‌کند متفاوت است). گزینهٔ \fB\-\-encoding\-policy\fP نحوهٔ مدیریت جانشین‌های یونیکد (Unicode surrogates؛ نقطه‌کدها در محدودهٔ \fB[0xD800\-0xDFFF]\fP) را توسط re2v مشخص می‌کند. .sp در زیر مثالی از یک تحلیل‌گر لغوی برای شناسه‌های یونیکد کدگذاری‌شده با UTF8 آمده است. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2v $INPUT \-o $OUTPUT \-\-utf8 \-si /*!include:re2c \(dqunicode_categories.re\(dq */ fn lex(yyinput string) int { mut yycursor, mut yymarker := 0, 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 0 } * { return 1 } */ } fn main() { if lex(\(dq_Ыдентификатор\e0\(dq) != 0 { panic(\(dqerror\(dq) } } .ft P .fi .UNINDENT .UNINDENT.SS فایل‌های ضمیمه (Include files) .sp ابزار re2v به کاربر اجازه می‌دهد با استفاده از بلوکی به قالب \fB/*!include:re2c FILE */\fP یا \fB%{include FILE %}\fP، یا یک دستورالعمل درون‌بلوکی \fB!include FILE ;\fP، فایل‌های دیگر را ضمیمه کند؛ که در آن \fBFILE\fP مسیر فایل مورد نظر برای ضمیمه‌سازی است. re2v فایل‌های ضمیمه را در پوشهٔ فایلِ دربرگیرنده و همچنین در مسیرهای ضمیمه‌سازی که می‌توان با گزینهٔ \fB\-I\fP تعیین کرد، جستجو می‌کند. بلوک‌ها/دستورالعمل‌های include در re2v مانند \fB#include\fP در C/C++ کار می‌کنند: محتویات \fBFILE\fP عیناً در محل بلوک/دستورالعمل جای‌گذاری می‌شوند. فایل‌های ضمیمه می‌توانند شامل includeهای دیگری نیز باشند. از گزینهٔ \fB\-\-depfile\fP برای ردیابی وابستگی‌های ساختِ فایل خروجی به فایل‌های ضمیمه استفاده کنید. ابزار re2v تعدادی فایل ضمیمهٔ از پیش تعریف‌شده ارائه می‌دهد که در زیرپوشهٔ \fBinclude/\fP پروژه قرار دارند. این فایل‌ها حاوی تعاریفی هستند که ممکن است برای پروژه‌های دیگر نیز مفید باشند (مانند دسته‌بندی‌های یونیکد) و چیزی شبیه به یک کتابخانهٔ استاندارد برای re2v\& تشکیل می‌دهند. در ادامه نمونه‌ای از به‌کارگیری فایل‌های ضمیمه آورده شده است. .SS فایل ضمیمه ۱ (definitions.v) .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C enum Result { 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 // re2v $INPUT \-o $OUTPUT \-i /*!include:re2c \(dqdefinitions.v\(dq */ fn lex(yyinput string) Result { mut yycursor, mut yymarker := 0, 0 /*!re2c re2c:yyfill:enable = 0; * { return .fail } number { return .ok } !include \(dqextra_rules.re.inc\(dq; */ } fn main() { assert lex(\(dq123\e0\(dq) == .ok assert lex(\(dq123.4567\e0\(dq) == .ok } .ft P .fi .UNINDENT .UNINDENT.SS فایل‌های سرایند (Header files) .sp ابزار re2v این امکان را فراهم می‌کند که با استفاده از گزینهٔ \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 فایل سرایند تولید شود. بلوک نخست آغاز فایل سرایند و بلوک دوم پایان آن را مشخص می‌کند. تمام محتوای میان این بلوک‌ها توسط re2v پردازش شده و کد تولیدشده در فایلی که با گزینهٔ \fB\-\-header\fP یا پیکربندی \fBre2c:header\fP تعیین شده است (یا \fBstdout\fP اگر هیچ‌کدام از گزینه یا پیکربندی استفاده نشده باشد) نوشته می‌شود. ممکن است در مواردی که از re2v برای تولید تعاریفی استفاده می‌شود که باید از سایر واحدهای ترجمه (translation units) قابل مشاهده باشند، به فایل سرایندِ تولیدشده به‌صورت خودکار نیاز باشد. .sp در ادامه مثالی از تولید یک فایل سرایند آمده است که شامل تعریف وضعیت تحلیل‌گر لغوی (lexer state) به همراه متغیرهای برچسب (tag variables) است (تعداد متغیرها به گرامر منظم بستگی دارد و برای برنامه‌نویس نامشخص است). .SS فایل ورودی (Input file) .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2v $INPUT \-o $OUTPUT \-i \-\-header lexer/state.v module main import lexer // the package is generated by re2c /*!header:re2c:on*/ module lexer pub struct State { pub mut: yyinput string yycursor int /*!stags:re2c format=\(dq@@ int\en\(dq; */ } /*!header:re2c:off*/ fn lex(mut yyrecord &lexer.State) int { mut t := 0 /*!re2c re2c:header = \(dqlexer/state.v\(dq; re2c:api = record; re2c:yyfill:enable = 0; re2c:tags = 1; [a]* @t [b]* { return t } */ } fn main() { mut st := &lexer.State{yyinput:\(dqab\e0\(dq,} if lex(mut st) != 1 { panic(\(dqerror\(dq) } } .ft P .fi .UNINDENT .UNINDENT .SS فایل سرایند (Header file) .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Code generated by re2c, DO NOT EDIT. module lexer pub struct State { pub mut: yyinput string yycursor int yyt1 int } .ft P .fi .UNINDENT .UNINDENT.SS "برنامه‌های اسکلتی (Skeleton programs)" .sp با گزینهٔ \fB\-S, \-\-skeleton\fP، برنامهٔ re2v تمام کدهای غیر re2v را نادیده گرفته و یک برنامهٔ C خودکفا تولید می‌کند که می‌تواند در ادامه کامپایل و اجرا شود. این برنامه شامل کد تحلیل‌گر لغوی (lexer) و داده‌های ورودی است. به‌ازای هر DFA ساخته‌شده (بلوک یا شرط)، re2v یک لکسر مستقل و دو فایل تولید می‌کند: یک فایل \fB\&.input\fP با رشته‌های برگرفته از DFA و یک فایل \fB\&.keys\fP با نتایج تطابق مورد انتظار. برنامه هر لکسر را روی فایل \fB\&.input\fP متناظر اجرا کرده و نتایج را با موارد مورد انتظار مقایسه می‌کند. برنامه‌های اسکلتی به چند دلیل بسیار مفید هستند: .INDENT 0.0 .IP \(bu 2 آن‌ها می‌توانند درستی بهینه‌سازی‌های گوناگون re2v را بسنجند (داده‌ها در مراحل اولیهٔ فرایند، پیش از انجام هرگونه تبدیل DFA تولید می‌شوند). .IP \(bu 2 تولید مجموعه‌ای از داده‌های ورودی با پوشش مناسب می‌تواند هم برای آزمون و هم برای محک‌زنی (benchmarking) سودمند باشد. .IP \(bu 2 تولید برنامه‌های اجرایی خودکفا به فرد امکان می‌دهد تا به نمونه‌های آزمون کمینه‌شده دست یابد (چرا که کد اصلی ممکن است حجیم بوده یا وابستگی‌های زیادی داشته باشد). .UNINDENT .sp دشواریِ تولید داده‌های ورودی در این است که به‌جز در ساده‌ترین حالت‌ها، تعداد رشته‌های ورودیِ ممکن بیش از حد زیاد است (حتی اگر طول رشته محدود باشد). re2v این مشکل را با تولید رشته‌های کافی برای پوشش تقریباً تمام گذارهای DFA حل می‌کند. این ابزار از الگوریتم زیر استفاده می‌کند: ابتدا، اسکلتی از DFA را می‌سازد. برای کدگذاری‌هایی با اندازهٔ واحد کد ۱ بایتی (مانند ASCII، UTF\-8 و EBCDIC) اسکلت دقیقاً رونوشتی برابر اصل از DFA نخستین است. برای کدگذاری‌هایی با واحدهای کد چندبایتی، اسکلت رونوشتی از DFA با حذف برخی گذارها است: به این صورت که re2v برای هر بازهٔ پیوسته و مجزا که متناظر با یک گذار DFA است، حداکثر ۲۵۶ واحد کد را در نظر می‌گیرد. مقادیر انتخاب‌شده به‌طور یکنواخت توزیع می‌شوند و شامل مرزهای بازه نیز هستند. re2v به‌جای تلاش برای پوشش تمام مسیرهای ممکن در اسکلت (که کاری ناممکن است)، مسیرهای کافی برای پوشش تمام گذارهای اسکلت را تولید می‌کند تا پرش‌های شرطی متناظر در لکسر فعال شوند. پیاده‌سازی این الگوریتم به حدود ۱ گیگابایت گذار محدود است و میزان ثابتی از حافظه را مصرف می‌کند (re2v داده‌ها را به محض تولید در فایل می‌نویسد). .SS "بصری‌سازی و اشکال‌زدایی (Visualization and debug)" .sp با گزینهٔ \fB\-D, \-\-emit\-dot\fP، برنامهٔ re2v کدی تولید نمی‌کند؛ در عوض، 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 برنامهٔ re2v در ابتدا توسط 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. .