.\" 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 "RE2GO" 1 "" "" "" .SH "نام (NAME)" re2go \- تولید تحلیل‌گرهای واژگانی سریع برای Go .SH "خلاصه دستور (SYNOPSIS)" .sp re2go \fB[ OPTIONS ]\fP \fB[ WARNINGS ]\fP \fBINPUT\fP .sp ورودی می‌تواند یک فایل یا \fB\-\fP برای stdin باشد. .SH "مقدمه (INTRODUCTION)" .sp ابزار re2go به عنوان یک پیش‌پردازنده عمل می‌کند. این ابزار فایل ورودی را (که معمولاً برنامه‌ای به زبان Go است، اما می‌تواند هر چیز دیگری نیز باشد) خوانده و به دنبال بلوک‌های کدی می‌گردد که در نشانگرهای آغاز/پایان با ساختار ویژه محصور شده‌اند. متن‌های خارج از این بلوک‌ها عیناً در فایل خروجی کپی می‌شوند. محتویات این بلوک‌ها توسط re2go\& پردازش می‌شوند. این ابزار آن‌ها را به کدهایی به زبان Go ترجمه کرده و کد تولیدشده را به جای بلوک اصلی در خروجی قرار می‌دهد. .sp در اینجا مثالی از یک برنامه کوچک آورده شده است که بررسی می‌کند آیا رشته داده‌شده شامل یک عدد ده‌دهی است یا خیر: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C //go:generate re2go $INPUT \-o $OUTPUT \-i \-\-api simple package main func lex(yyinput string) { var yycursor int /*!re2c re2c:YYCTYPE = byte; re2c:yyfill:enable = 0; [1\-9][0\-9]* { return } * { panic(\(dqerror!\(dq) } */ } func main() { lex(\(dq1234\ex00\(dq) } .ft P .fi .UNINDENT .UNINDENT .sp در خروجی، re2go بلوک میانی را با کد تولیدشده جایگزین کرده است: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Code generated by re2go, DO NOT EDIT. //go:generate re2go $INPUT \-o $OUTPUT \-i \-\-api simple package main func lex(yyinput string) { var yycursor int { var yych byte yych = yyinput[yycursor] switch (yych) { case \(aq1\(aq,\(aq2\(aq,\(aq3\(aq,\(aq4\(aq,\(aq5\(aq,\(aq6\(aq,\(aq7\(aq,\(aq8\(aq,\(aq9\(aq: goto yy2 default: goto yy1 } yy1: yycursor += 1 { panic(\(dqerror!\(dq) } yy2: yycursor += 1 yych = yyinput[yycursor] switch (yych) { case \(aq0\(aq,\(aq1\(aq,\(aq2\(aq,\(aq3\(aq,\(aq4\(aq,\(aq5\(aq,\(aq6\(aq,\(aq7\(aq,\(aq8\(aq,\(aq9\(aq: goto yy2 default: goto yy3 } yy3: { return } } } func main() { lex(\(dq1234\ex00\(dq) } .ft P .fi .UNINDENT .UNINDENT.SH "مبانی (BASICS)" .sp یک برنامه re2go از دنباله‌ای از \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 مروری بر نحو re2go برای عبارت‌های باقاعده ارائه می‌دهد. پس از تعریف، \fBname\fP می‌تواند در سایر عبارت‌های باقاعده و قواعد استفاده شود. بازگشت در تعاریف نام‌گذاری‌شده مجاز نیست و هر نام باید پیش از استفاده تعریف شده باشد. یک بلوک تعاریف نام‌گذاری‌شده را از دامنه سراسری به ارث می‌برد. تعریف مجدد نامی که در دامنه فعلی وجود دارد خطا است. .TP .B \fBconfiguration = value ;\fP یک \fIپیکربندی\fP امکان تغییر رفتار re2go و سفارشی‌سازی کد تولیدشده را فراهم می‌کند. برای فهرست کاملی از پیکربندی‌های پشتیبانی‌شده توسط re2go بخش \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\&. قاعده پیش‌فرض همواره باید تعریف شود، بدون توجه به جایگاهش در بلوک دارای کمترین اولویت است و با هر واحد کد مطابقت می‌یابد (نه لزوماً یک نویسه معتبر، به بخش \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 شامل تعاریف، پیکربندی‌ها، قواعد و دستورالعمل‌ها است. re2go عبارت‌های باقاعده مرتبط با هر قاعده را به یک اتوماتون متناهی قطعی کامپایل می‌کند، آن را به شکل پرش‌های شرطی در زبان مقصد کدگذاری کرده و بلوک را با کد تولیدشده جایگزین می‌کند. نام‌ها و پیکربندی‌های تعریف‌شده در یک بلوک سراسری به دامنه سراسری اضافه شده و برای بلوک‌های بعدی قابل مشاهده می‌شوند. در آغاز برنامه دامنه سراسری با \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 re2go بلوک‌های قواعد نیازمند گزینه \fB\-r \-\-reusable\fP بودند. .TP .B \fB/*!use:re2c[:] ... */\fP or \fB%{use[:] ... %}\fP یک بلوک استفاده که به یک بلوک قواعد از پیش تعریف‌شده ارجاع می‌دهد. اگر نام مشخص شده باشد، re2go به دنبال بلوک قواعدی با این نام می‌گردد. در غیر این صورت از جدیدترین بلوک قواعد استفاده می‌شود (خواه نام‌گذاری‌شده یا بدون نام). یک بلوک use می‌تواند تعاریف، پیکربندی‌ها و قواعد خاص خود را اضافه کند که به موارد بلوک قواعد ارجاع‌شده افزوده می‌شوند. پیش از نسخه 2.2 re2go بلوک‌های 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 تولیدشده توسط re2go باز می‌شود. یک فهرست اختیاری از نام‌های بلوک مشخص می‌کند که هنگام محاسبه مجموعه متغیرهای برچسب کدام بلوک‌ها باید گنجانده شوند (اگر فهرست خالی باشد، همه بلوک‌ها گنجانده می‌شوند). دو پیکربندی اختیاری وجود دارد: \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) یا به‌طور ضمنی توسط re2go تولید شده باشد (با گزینه‌های \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 بعدی توسط re2go پردازش شده و در فایل سرآیند مشخص‌شده با گزینه \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 در اینجا فهرست کاملی از پیکربندی‌های پشتیبانی‌شده توسط re2go آمده است: .INDENT 0.0 .TP .B \fBre2c:api\fP, \fBre2c:input\fP مشابه گزینهٔ \fB\-\-api\fP\&. .TP .B \fBre2c:api:sigil\fP نشانگر (\(dqsigil\(dq) مورد استفاده برای جای‌نگه‌دارهای آرگومان در عملگرهای اولیهٔ API را مشخص می‌کند. مقدار پیش‌فرض \fB@@\fP است. یک جای‌نگه‌دار با نشانگر آغاز شده و به دنبال آن نام آرگومان در آکولاد می‌آید. برای مثال، اگر نشانگر روی \fB$\fP تنظیم شود، جای‌نگه‌دارها به شکل \fB${name}\fP خواهند بود. APIهای تک‌آرگومانی می‌توانند از نمادگذاری کوتاه بدون نام در آکولاد استفاده کنند. این گزینه می‌تواند با گزینه‌های مربوط به عملگرهای اولیهٔ منفرد API باطل و بازنویسی شود، مانند \fBre2c:YYFILL@len\fP برای \fBYYFILL\fP\&. .TP .B \fBre2c:api:style\fP سبک API را مشخص می‌کند. مقادیر ممکن عبارتند از \fBfunctions\fP (پیش‌فرض برای C) و \fBfree\-form\fP (پیش‌فرض برای Go و Rust). در سبک \fBfunctions\fP، عملگرهای اولیهٔ API به همراه فهرستی از آرگومان‌ها درون پرانتز پس از نام عملگر تولید می‌شوند. آرگومان‌ها تنها برای پارامترهای خودکار تولید‌شده (مانند تعداد نویسه‌های ارسال‌شده به \fBYYFILL\fP) ارائه می‌شوند، نه برای زمینهٔ عمومی تحلیل‌گر لغوی، بنابراین این عملگرها بیشتر شبیه ماکروها در C/C++ یا کلوژرها در Go و Rust عمل می‌کنند. در سبک free\-form، عملگرهای اولیهٔ API قالب ثابتی ندارند: آنها باید به عنوان رشته‌هایی حاوی قطعه‌کدهای آزاد با متغیرهای درون‌یابی‌شده به شکل \fB@@{var}\fP یا \fB@@\fP تعریف شوند (این‌ها متناظر با آرگومان‌ها در سبک تابع‌گونه هستند). این پیکربندی می‌تواند برای عملگرهای اولیهٔ API به صورت مجزا باطل و بازنویسی شود؛ برای نمونه، پیکربندی \fBre2c:YYFILL:naked\fP را برای \fBYYFILL\fP ببینید. .TP .B \fBre2c:bit\-vectors\fP, \fBre2c:flags:bit\-vectors\fP, \fBre2c:flags:b\fP مشابه گزینهٔ \fB\-\-bit\-vectors\fP، اما می‌تواند بر مبنای هر بلوک پیکربندی شود. .TP .B \fBre2c:captures\fP, \fBre2c:leftmost\-captures\fP مشابه گزینهٔ \fB\-\-leftmost\-captures\fP، اما می‌تواند بر مبنای هر بلوک پیکربندی شود. .TP .B \fBre2c:captvars\fP, \fBre2c:leftmost\-captvars\fP مشابه گزینهٔ \fB\-\-leftmost\-captvars\fP، اما می‌تواند بر مبنای هر بلوک پیکربندی شود. .TP .B \fBre2c:case\-insensitive\fP, \fBre2c:flags:case\-insensitive\fP مشابه گزینهٔ \fB\-\-case\-insensitive\fP، اما می‌تواند بر مبنای هر بلوک پیکربندی شود. .TP .B \fBre2c:case\-inverted\fP, \fBre2c:flags:case\-inverted\fP مشابه گزینهٔ \fB\-\-case\-inverted\fP، اما می‌تواند بر مبنای هر بلوک پیکربندی شود. .TP .B \fBre2c:case\-ranges\fP, \fBre2c:flags:case\-ranges\fP مشابه گزینهٔ \fB\-\-case\-ranges\fP، اما می‌تواند بر مبنای هر بلوک پیکربندی شود. .TP .B \fBre2c:computed\-gotos\fP, \fBre2c:flags:computed\-gotos\fP, \fBre2c:flags:g\fP مشابه گزینهٔ \fB\-\-computed\-gotos\fP، اما می‌تواند بر مبنای هر بلوک پیکربندی شود. .TP .B \fBre2c:computed\-gotos:relative\fP, \fBre2c:cgoto:relative\fP مشابه گزینهٔ \fB\-\-computed\-gotos\-relative\fP، اما می‌تواند بر مبنای هر بلوک پیکربندی شود. .TP .B \fBre2c:computed\-gotos:threshold\fP, \fBre2c:cgoto:threshold\fP در صورت استفاده از \fBgoto\fPی محاسبه‌شده، این پیکربندی آستانهٔ پیچیدگی‌ای را مشخص می‌کند که منجر به تولید جدول‌های پرش به جای دستورهای تو‌در‌توی \fBif\fP و نقشه‌های بیتی می‌شود. مقدار پیش‌فرض \fB9\fP است. .TP .B \fBre2c:cond:abort\fP اگر روی یک مقدار عددی صحیح و مثبت تنظیم شود، حالت پیش‌فرض در توزیع وضعیت تولید‌شده، اجرای برنامه را متوقف می‌کند. .TP .B \fBre2c:cond:goto\fP قطعه‌کد مورد استفاده برای قواعد میان‌بر خودکار تولید‌شدهٔ \fB:=>\fP در شرط‌ها را مشخص می‌کند. مقدار پیش‌فرض \fBgoto @@;\fP است. جای‌نگه‌دار \fB@@\fP با نام شرط جایگزین می‌شود (پیکربندی‌های \fBre2c:api:sigil\fP و \fBre2c:cond:goto@cond\fP را ببینید). .TP .B \fBre2c:cond:goto@cond\fP نشانگر مورد استفاده برای جایگزینی آرگومان در تعریف \fBre2c:cond:goto\fP را مشخص می‌کند. مقدار پیش‌فرض \fB@@\fP است. این گزینه پیکربندی عمومی‌تر \fBre2c:api:sigil\fP را باطل و بازنویسی می‌کند. .TP .B \fBre2c:cond:divider\fP جداکنندهٔ بلوک‌های شرطی را تعریف می‌کند. مقدار پیش‌فرض \fB/* *********************************** */\fP است. جای‌نگه‌دارها با نام شرط جایگزین می‌شوند (به \fBre2c:api;sigil\fP و \fBre2c:cond:divider@cond\fP مراجعه کنید). .TP .B \fBre2c:cond:divider@cond\fP نشانگر مورد استفاده برای جایگزینی آرگومان در تعریف \fBre2c:cond:divider\fP را مشخص می‌کند. مقدار پیش‌فرض \fB@@\fP است. این گزینه پیکربندی عمومی‌تر \fBre2c:api:sigil\fP را باطل و بازنویسی می‌کند. .TP .B \fBre2c:cond:prefix\fP, \fBre2c:condprefix\fP پیشوند مورد استفاده برای برچسب‌های شرط را مشخص می‌کند. مقدار پیش‌فرض \fByyc_\fP است. .TP .B \fBre2c:cond:enumprefix\fP, \fBre2c:condenumprefix\fP پیشوند مورد استفاده برای شناسه‌های شرط را مشخص می‌کند. مقدار پیش‌فرض \fByyc\fP است. .TP .B \fBre2c:debug\-output\fP, \fBre2c:flags:debug\-output\fP, \fBre2c:flags:d\fP مشابه گزینهٔ \fB\-\-debug\-output\fP، اما می‌تواند بر مبنای هر بلوک پیکربندی شود. .TP .B \fBre2c:empty\-class\fP, \fBre2c:flags:empty\-class\fP مشابه گزینهٔ \fB\-\-empty\-class\fP، اما می‌تواند بر مبنای هر بلوک پیکربندی شود. .TP .B \fBre2c:encoding:ebcdic\fP, \fBre2c:flags:ecb\fP, \fBre2c:flags:e\fP مشابه گزینهٔ \fB\-\-ebcdic\fP، اما می‌تواند بر مبنای هر بلوک پیکربندی شود. .TP .B \fBre2c:encoding:ucs2\fP, \fBre2c:flags:wide\-chars\fP, \fBre2c:flags:w\fP مشابه گزینهٔ \fB\-\-ucs2\fP، اما می‌تواند بر مبنای هر بلوک پیکربندی شود. .TP .B \fBre2c:encoding:utf8\fP, \fBre2c:flags:utf\-8\fP, \fBre2c:flags:8\fP مشابه گزینهٔ \fB\-\-utf8\fP، اما می‌تواند بر مبنای هر بلوک پیکربندی شود. .TP .B \fBre2c:encoding:utf16\fP, \fBre2c:flags:utf\-16\fP, \fBre2c:flags:x\fP مشابه گزینهٔ \fB\-\-utf16\fP، اما می‌تواند بر مبنای هر بلوک پیکربندی شود. .TP .B \fBre2c:encoding:utf32\fP, \fBre2c:flags:unicode\fP, \fBre2c:flags:u\fP مشابه گزینهٔ \fB\-\-utf32\fP، اما می‌تواند بر مبنای هر بلوک پیکربندی شود. .TP .B \fBre2c:encoding\-policy\fP, \fBre2c:flags:encoding\-policy\fP مشابه گزینهٔ \fB\-\-encoding\-policy\fP، اما می‌تواند بر مبنای هر بلوک پیکربندی شود. .TP .B \fBre2c:eof\fP نماد نگهبان مورد استفاده همراه با قاعدهٔ پایان ورودی \fB$\fP را مشخص می‌کند. مقدار پیش‌فرض \fB\-1\fP است (قاعدهٔ \fB$\fP استفاده نمی‌شود). مقادیر ممکن دیگر شامل تمام واحدهای کد معتبر هستند. تنها اعداد ده‌دهی شناسایی می‌شوند. .TP .B \fBre2c:header\fP, \fBre2c:flags:type\-header\fP, \fBre2c:flags:t\fP نام فایل سرایند تولیدشده را نسبت به دایرکتوری فایل خروجی مشخص می‌کند. مشابه گزینهٔ \fB\-\-header\fP، با این تفاوت که مسیر فایل نسبی است. .TP .B \fBre2c:indent:string\fP رشتهٔ مورد استفاده برای تورفتگی را مشخص می‌کند. پیش‌فرض یک نویسهٔ تب منفرد \fB\(dq\et\(dq\fP است. رشتهٔ تورفتگی باید تنها حاوی نویسه‌های فاصله‌ساز باشد. برای غیرفعال کردن کامل تورفتگی، این پیکربندی را روی یک رشتهٔ خالی تنظیم کنید. .TP .B \fBre2c:indent:top\fP حداقل میزان تورفتگی مورد استفاده را مشخص می‌کند. مقدار پیش‌فرض صفر است. مقدار باید یک عدد صحیح غیرمنفی باشد. .TP .B \fBre2c:invert\-captures\fP مشابه گزینهٔ \fB\-\-invert\-captures\fP، اما می‌تواند بر مبنای هر بلوک پیکربندی شود. .TP .B \fBre2c:label:prefix\fP, \fBre2c:labelprefix\fP پیشوند مورد استفاده برای برچسب‌های وضعیت DFA را مشخص می‌کند. مقدار پیش‌فرض \fByy\fP است. .TP .B \fBre2c:label:start\fP, \fBre2c:startlabel\fP تولید برچسب شروع بلوک را کنترل می‌کند. مقدار پیش‌فرض صفر است، به این معنی که برچسب شروع تنها در صورتی تولید می‌شود که استفاده شده باشد. یک مقدار عدد صحیح بزرگ‌تر از صفر، تولید برچسب شروع را حتی در صورت عدم استفاده توسط تحلیل‌گر لغوی اجباری می‌کند. یک مقدار رشته‌ای نیز تولید برچسب شروع را اجباری کرده و نام برچسب را به رشتهٔ مشخص‌شده تنظیم می‌کند. این پیکربندی تنها بر بلوک جاری اعمال می‌شود (برای بلوک بعدی به مقدار پیش‌فرض بازنشانی می‌شود). .TP .B \fBre2c:label:yyFillLabel\fP پیشوند برچسب‌های \fBYYFILL\fP مورد استفاده با \fBre2c:eof\fP و در حالت وضعیت قابل ذخیره‌سازی را مشخص می‌کند. .TP .B \fBre2c:label:yyloop\fP نام برچسب مشخص‌کنندهٔ شروع حلقهٔ تحلیل‌گر لغوی به همراه گزینهٔ \fB\-\-loop\-switch\fP را مشخص می‌کند. پیش‌فرض \fByyloop\fP است. .TP .B \fBre2c:label:yyNext\fP نام برچسب اختیاری‌ای را که پس از سوییچ \fBYYGETSTATE\fP در حالت وضعیت قابل ذخیره‌سازی می‌آید (فعال‌شده با \fBre2c:state:nextlabel\fP) مشخص می‌کند. پیش‌فرض \fByyNext\fP است. .TP .B \fBre2c:lookahead\fP, \fBre2c:flags:lookahead\fP منسوخ‌شده (گزینهٔ منسوخ‌شدهٔ \fB\-\-no\-lookahead\fP را ببینید). .TP .B \fBre2c:monadic\fP اگر روی مقداری غیر از صفر تنظیم شود، تحلیل‌گر لغوی تولیدشده از نشانه‌گذاری مونادیک استفاده خواهد کرد (این پیکربندی مخصوص Haskell است)..TP .B \fBre2c:nested\-ifs\fP, \fBre2c:flags:nested\-ifs\fP, \fBre2c:flags:s\fP همانند گزینهٔ \fB\-\-nested\-ifs\fP، با این تفاوت که می‌تواند به‌ازای هر بلوک پیکربندی شود. .TP .B \fBre2c:posix\-captures\fP, \fBre2c:flags:posix\-captures\fP, \fBre2c:flags:P\fP همانند گزینهٔ \fB\-\-posix\-captures\fP، با این تفاوت که می‌تواند به‌ازای هر بلوک پیکربندی شود. .TP .B \fBre2c:posix\-captvars\fP همانند گزینهٔ \fB\-\-posix\-captvars\fP، با این تفاوت که می‌تواند به‌ازای هر بلوک پیکربندی شود. .TP .B \fBre2c:tags\fP, \fBre2c:flags:tags\fP, \fBre2c:flags:T\fP همانند گزینهٔ \fB\-\-tags\fP، با این تفاوت که می‌تواند به‌ازای هر بلوک پیکربندی شود. .TP .B \fBre2c:tags:expression\fP عبارت مورد استفاده برای متغیرهای برچسب را مشخص می‌کند. به‌طور پیش‌فرض re2go عبارت‌هایی به فرم \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 است (در این حالت re2go فرض می‌کند که نماد نگهبان صفر است، که معمول‌ترین حالت محسوب می‌شود). تنها اعداد ده‌دهی شناسایی می‌شوند. .TP .B \fBre2c:state:abort\fP اگر روی یک مقدار عددی صحیح مثبت تنظیم شود، مورد پیش‌فرض (default case) در توزیع وضعیتِ تولیدشده اجرای برنامه را متوقف (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 بازنویسی می‌کند. مقدار صفر متناظر با سبک API قالب‌آزاد (free\-form) است. .TP .B \fBre2c:YYFN\fP پریمیتیو API با نام \fBYYFN\fP را تعریف می‌کند. .TP .B \fBre2c:YYINPUT\fP پریمیتیو API با نام \fBYYINPUT\fP را تعریف می‌کند. .TP .B \fBre2c:YYGETCOND\fP, \fBre2c:define:YYGETCONDITION\fP پریمیتیو API با نام \fBYYGETCOND\fP را تعریف می‌کند. .TP .B \fBre2c:YYGETCOND:naked\fP, \fBre2c:define:YYGETCONDITION:naked\fP پیکربندی عمومی‌تر \fBre2c:api:style\fP را برای \fBYYGETCOND\fP بازنویسی می‌کند. مقدار صفر متناظر با سبک API قالب‌آزاد (free\-form) است. .TP .B \fBre2c:YYGETSTATE\fP, \fBre2c:define:YYGETSTATE\fP پریمیتیو API با نام \fBYYGETSTATE\fP را تعریف می‌کند. .TP .B \fBre2c:YYGETSTATE:naked\fP, \fBre2c:define:YYGETSTATE:naked\fP پیکربندی عمومی‌تر \fBre2c:api:style\fP را برای \fBYYGETSTATE\fP بازنویسی می‌کند. مقدار صفر متناظر با سبک API قالب‌آزاد (free\-form) است. .TP .B \fBre2c:YYGETACCEPT\fP, \fBre2c:define:YYGETACCEPT\fP پریمیتیو API با نام \fBYYGETACCEPT\fP را تعریف می‌کند. .TP .B \fBre2c:YYLESSTHAN\fP, \fBre2c:define:YYLESSTHAN\fP پریمیتیو عمومی API با نام \fBYYLESSTHAN\fP را تعریف می‌کند. .TP .B \fBre2c:YYLIMIT\fP, \fBre2c:define:YYLIMIT\fP پریمیتیو API با نام \fBYYLIMIT\fP را تعریف می‌کند. .TP .B \fBre2c:YYMARKER\fP, \fBre2c:define:YYMARKER\fP پریمیتیو API با نام \fBYYMARKER\fP را تعریف می‌کند. .TP .B \fBre2c:YYMTAGN\fP, \fBre2c:define:YYMTAGN\fP پریمیتیو عمومی API با نام \fBYYMTAGN\fP را تعریف می‌کند. .TP .B \fBre2c:YYMTAGP\fP, \fBre2c:define:YYMTAGP\fP پریمیتیو عمومی API با نام \fBYYMTAGP\fP را تعریف می‌کند. .TP .B \fBre2c:YYPEEK\fP, \fBre2c:define:YYPEEK\fP پریمیتیو عمومی API با نام \fBYYPEEK\fP را تعریف می‌کند. .TP .B \fBre2c:YYRESTORE\fP, \fBre2c:define:YYRESTORE\fP پریمیتیو عمومی API با نام \fBYYRESTORE\fP را تعریف می‌کند. .TP .B \fBre2c:YYRESTORECTX\fP, \fBre2c:define:YYRESTORECTX\fP پریمیتیو عمومی API با نام \fBYYRESTORECTX\fP را تعریف می‌کند. .TP .B \fBre2c:YYRESTORETAG\fP, \fBre2c:define:YYRESTORETAG\fP پریمیتیو عمومی API با نام \fBYYRESTORETAG\fP را تعریف می‌کند. .TP .B \fBre2c:YYSETCOND\fP, \fBre2c:define:YYSETCONDITION\fP پریمیتیو API با نام \fBYYSETCOND\fP را تعریف می‌کند. .TP .B \fBre2c:YYSETCOND@cond\fP, \fBre2c:define:YYSETCONDITION@cond\fP نشانهٔ (sigil) مورد استفاده برای جایگزینی آرگومان را در تعریف \fBYYSETCOND\fP مشخص می‌کند. مقدار پیش‌فرض \fB@@\fP است. پیکربندی عمومی‌تر \fBre2c:api:sigil\fP را بازنویسی می‌کند. .TP .B \fBre2c:YYSETCOND:naked\fP, \fBre2c:define:YYSETCONDITION:naked\fP پیکربندی عمومی‌تر \fBre2c:api:style\fP را برای \fBYYSETCOND\fP بازنویسی می‌کند. مقدار صفر متناظر با سبک API قالب‌آزاد (free\-form) است. .TP .B \fBre2c:YYSETSTATE\fP, \fBre2c:define:YYSETSTATE\fP پریمیتیو API با نام \fBYYSETSTATE\fP را تعریف می‌کند. .TP .B \fBre2c:YYSETSTATE@state\fP, \fBre2c:define:YYSETSTATE@state\fP نشانهٔ (sigil) مورد استفاده برای جایگزینی آرگومان را در تعریف \fBYYSETSTATE\fP مشخص می‌کند. مقدار پیش‌فرض \fB@@\fP است. پیکربندی عمومی‌تر \fBre2c:api:sigil\fP را بازنویسی می‌کند. .TP .B \fBre2c:YYSETSTATE:naked\fP, \fBre2c:define:YYSETSTATE:naked\fP پیکربندی عمومی‌تر \fBre2c:api:style\fP را برای \fBYYSETSTATE\fP بازنویسی می‌کند. مقدار صفر متناظر با سبک API قالب‌آزاد (free\-form) است. .TP .B \fBre2c:YYSETACCEPT\fP, \fBre2c:define:YYSETACCEPT\fP پریمیتیو API با نام \fBYYSETACCEPT\fP را تعریف می‌کند. .TP .B \fBre2c:YYSKIP\fP, \fBre2c:define:YYSKIP\fP پریمیتیو عمومی API با نام \fBYYSKIP\fP را تعریف می‌کند. .TP .B \fBre2c:YYSHIFT\fP, \fBre2c:define:YYSHIFT\fP پریمیتیو عمومی API با نام \fBYYSHIFT\fP را تعریف می‌کند. .TP .B \fBre2c:YYCOPYMTAG\fP, \fBre2c:define:YYCOPYMTAG\fP پریمیتیو عمومی API با نام \fBYYCOPYMTAG\fP را تعریف می‌کند. .TP .B \fBre2c:YYCOPYSTAG\fP, \fBre2c:define:YYCOPYSTAG\fP پریمیتیو عمومی API با نام \fBYYCOPYSTAG\fP را تعریف می‌کند..TP .B \fBre2c:YYSHIFTMTAG\fP, \fBre2c:define:YYSHIFTMTAG\fP دستور پایه API عمومی \fBYYSHIFTMTAG\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYSHIFTSTAG\fP, \fBre2c:define:YYSHIFTSTAG\fP دستور پایه API عمومی \fBYYSHIFTSTAG\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYSTAGN\fP, \fBre2c:define:YYSTAGN\fP دستور پایه API عمومی \fBYYSTAGN\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYSTAGP\fP, \fBre2c:define:YYSTAGP\fP دستور پایه API عمومی \fBYYSTAGP\fP را تعریف می‌کند\&. .TP .B \fBre2c:yyaccept\fP, \fBre2c:variable:yyaccept\fP دستور پایه API با نام \fByyaccept\fP را تعریف می‌کند\&. .TP .B \fBre2c:yybm\fP, \fBre2c:variable:yybm\fP دستور پایه API با نام \fByybm\fP را تعریف می‌کند\&. .TP .B \fBre2c:yybm:hex\fP, \fBre2c:variable:yybm:hex\fP اگر روی مقداری غیر از صفر تنظیم شود، نگاشت‌های بیتی (bitmaps) برای گزینه \fB\-\-bit\-vectors\fP در قالب شانزده‌شانزدهی (هگزادسیمال) تولید می‌شوند. پیش‌فرض صفر است (نگاشت‌های بیتی در قالب ده‌دهی هستند). .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 اگر روی غیرصفر تنظیم شود، re2go هر بار که \fByych\fP خوانده می‌شود، به‌طور خودکار یک تبدیل به \fBYYCTYPE\fP تولید می‌کند. پیش‌فرض صفر است (بدون تبدیل). .TP .B \fBre2c:yych:literals\fP, \fBre2c:variable:yych:literals\fP قالب مقادیر ثابتی (literals) را مشخص می‌کند که \fByych\fP در برابر آن‌ها مطابقت داده می‌شود. مقادیر مجاز عبارتند از: \fBchar\fP (ثابت‌های نویسه‌ای درون علامت نقل‌قول تکی، نویسه‌های غیرقابل‌چاپ از توالی‌های گریز که با بک‌اسلش شروع می‌شوند استفاده می‌کنند)، \fBhex\fP (اعداد صحیح هگزادسیمال) و \fBchar_or_hex\fP (ترکیبی از هر دو، ثابت‌های نویسه‌ای برای نویسه‌های قابل‌چاپ و اعداد صحیح هگزادسیمال برای سایر موارد). .TP .B \fBre2c:yyctable\fP, \fBre2c:variable:yyctable\fP دستور پایه API با نام \fByyctable\fP را تعریف می‌کند\&. .TP .B \fBre2c:yynmatch\fP, \fBre2c:variable:yynmatch\fP دستور پایه API با نام \fByynmatch\fP را تعریف می‌کند\&. .TP .B \fBre2c:yypmatch\fP, \fBre2c:variable:yypmatch\fP دستور پایه API با نام \fByypmatch\fP را تعریف می‌کند\&. .TP .B \fBre2c:yytarget\fP, \fBre2c:variable:yytarget\fP دستور پایه API با نام \fByytarget\fP را تعریف می‌کند\&. .TP .B \fBre2c:yystable\fP, \fBre2c:variable:yystable\fP منسوخ شده است. .TP .B \fBre2c:yystate\fP, \fBre2c:variable:yystate\fP دستور پایه API با نام \fByystate\fP را تعریف می‌کند\&. .TP .B \fBre2c:yyfill\fP, \fBre2c:variable:yyfill\fP دستور پایه API با نام \fByyfill\fP را تعریف می‌کند\&. .TP .B \fBre2c:yyfill:check\fP اگر روی صفر تنظیم شود، از تولید بررسی پیش از \fBYYFILL\fP برای تعداد نویسه‌های ورودی جلوگیری می‌کند (تعریف \fBYYLESSTHAN\fP در API عمومی و مقایسه مبتنی بر \fBYYLIMIT\fP در API اشاره‌گرهای C). پیش‌فرض غیرصفر است (بررسی تولید می‌شود). .TP .B \fBre2c:yyfill:enable\fP اگر روی صفر تنظیم شود، از تولید \fBYYFILL\fP (همراه با بررسی آن) جلوگیری می‌کند. این مورد باید زمانی استفاده شود که کل ورودی در یک قطعه پیوسته از حافظه جا می‌گیرد (نیازی به بافر کردن نیست) و بررسی‌های پایان ورودی به بررسی‌های \fBYYFILL\fP وابسته نیستند (برای نمونه در صورتی که از یک نویسه نگهبان (sentinel) استفاده شده باشد). از هشدارها (گزینه \fB\-W\fP) و پیکربندی \fBre2c:sentinel\fP برای اطمینان از اینکه تحلیل‌گر لغوی تولیدشده نمی‌تواند فراتر از پایان ورودی را بخواند، استفاده کنید. پیش‌فرض غیرصفر است (\fBYYFILL\fP فعال است). .TP .B \fBre2c:yyfill:parameter\fP اگر روی صفر تنظیم شود، از تولید پارامتر ارسالی به \fBYYFILL\fP جلوگیری می‌کند\&. این پارامتر حداقل تعداد نویسه‌هایی است که باید تأمین شود. پیش‌فرض غیرصفر است (پارامتر تولید می‌شود). این پیکربندی می‌تواند توسط \fBre2c:YYFILL:naked\fP یا \fBre2c:api:style\fP بازنویسی شود\&. .TP .B \fBre2c:yyfn:sep\fP جداکننده مورد استفاده در عناصر \fBYYFN\fP را مشخص می‌کند (پیش‌فرض نقطه‌ویرگول است). .TP .B \fBre2c:yyfn:throw\fP استثناهای پرتاب‌شده توسط تابع \fBYYFN\fP را مشخص می‌کند (پیش‌فرض خالی است، که به معنی عدم وجود استثنا می‌باشد). .UNINDENT.SS "عبارت‌های منظم (Regular expressions)" .sp re2go از نحو زیر برای عبارت‌های منظم استفاده می‌کند: .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 فهرست کنش‌های از پیش تعریف‌شده که توسط re2go پشتیبانی می‌شوند در زیر آمده است: .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 در اینجا فهرست کاملی از دستورالعمل‌های پشتیبانی‌شده توسط re2go آورده شده است: .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 شناخته می‌شوند\&. این‌که کدام عناصر اولیه باید برای یک برنامهٔ خاص تعریف شوند به عوامل متعددی بستگی دارد، از جمله پیچیدگی عبارات منظم، نحوهٔ نمایش ورودی، بافرینگ و استفاده از قابلیت‌های گوناگون. تمام عناصر اولیهٔ ضروری باید توسط کاربر در قالب ماکروها، توابع، متغیرها یا هر شکل مناسب دیگری که کد تولیدشده را از نظر نحوی و معنایی درست می‌سازد، تعریف شوند. re2go تعاریف را بررسی نمی‌کند (و نمی‌تواند بررسی کند)، بنابراین اگر موردی جا افتاده باشد یا به نادرستی تعریف شده باشد، برنامهٔ تولیدشده ممکن است خطاهای زمان کامپایل یا زمان اجرا داشته باشد. این راهنما مثال‌هایی از تعاریف API را برای رایج‌ترین حالت‌ها ارائه می‌دهد. .sp برنامهٔ re2go دارای سه شیوهٔ API است که مجموعهٔ اصلی عناصر اولیهٔ مورد استفاده توسط یک برنامه را مشخص می‌کنند: .INDENT 0.0 .TP .B \fBSimple API\fP (\fIدر نسخهٔ 4.0 افزوده شد\fP) این یک API پایه‌ای است که می‌تواند با گزینهٔ \fB\-\-api simple\fP یا پیکربندی \fBre2c:api = simple\fP فعال شود. این رابط شامل عناصر اولیهٔ زیر است: \fBYYINPUT\fP (که باید به‌صورت دنباله‌ای از واحدهای کد، مانند یک رشته تعریف شود) و \fBYYCURSOR\fP، \fBYYMARKER\fP، \fBYYCTXMARKER\fP، \fBYYLIMIT\fP (که باید به‌صورت اندیس‌هایی در \fBYYINPUT\fP تعریف شوند). .nf .fi .sp .TP .B \fBRecord API\fP (\fIدر نسخهٔ 4.0 افزوده شد\fP) رابط Record API در مواردی کاربرد دارد که وضعیت تحلیل‌گر لغوی (lexer) باید در یک 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 و رابط پیش‌فرض برای backend زبان Go است. این رابط شامل عناصر اولیه برای عملیات عمومی است: \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\&. رابط Generic API از دو سبک پشتیبانی می‌کند که نحوهٔ تعریف عناصر اولیه را تعیین می‌کنند: .nf .fi .sp .INDENT 7.0 .TP .B \fBFree\-form\fP سبک آزاد (Free\-form) سبک پیش‌فرض است. این سبک همچنین می‌تواند با پیکربندی \fBre2c:api:style = free\-form\fP فعال شود\&. در این سبک، عناصر اولیهٔ رابط باید به‌صورت قطعه‌کدهای آزاد با متغیرهای الحاقی به فرم \fB@@{var}\fP یا در صورت وجود تنها یک متغیر، به شکل اختیاری \fB@@\fP تعریف شوند. مجموعهٔ متغیرها مختص به هر عنصر اولیه است. در اینجا نحوهٔ تعریف Generic API به سبک free\-form بر اساس متغیرهای صحیح \fBcursor\fP، \fBlimit\fP، \fBmarker\fP، \fBctxmarker\fP و یک رشته (یا byte slice) \fBdata\fP آورده شده است: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C /*!re2c re2c:YYPEEK = \(dqdata[cursor]\(dq; re2c:YYSKIP = \(dqcursor++\(dq; re2c:YYBACKUP = \(dqmarker = cursor\(dq; re2c:YYRESTORE = \(dqcursor = marker\(dq; re2c:YYBACKUPCTX = \(dqctxmarker = cursor\(dq; re2c:YYRESTORECTX = \(dqcursor = ctxmarker\(dq; re2c:YYRESTORETAG = \(dqcursor = ${tag}\(dq; re2c:YYLESSTHAN = \(dqlimit \- cursor < @@{len}\(dq; re2c:YYEND = \(dqlimit == cursor\(dq; re2c:YYSTAGP = \(dq@@{tag} = cursor\(dq; re2c:YYSTAGN = \(dq@@{tag} = \-1\(dq; re2c:YYSHIFT = \(dqcursor += @@{shift}\(dq; re2c:YYSHIFTSTAG = \(dq@@{tag} += @@{shift}\(dq; */ .ft P .fi .UNINDENT .UNINDENT .nf .fi .sp .TP .B \fBFunction\-like\fP سبک شبه‌تابع (Function\-like) با پیکربندی \fBre2c:api:style = functions\fP فعال می‌شود\&. در این سبک، عناصر اولیه باید به‌صورت closureهایی تعریف شوند که آرگومان‌های لازم را می‌پذیرند. در اینجا نحوهٔ تعریف Generic API به سبک function\-like بر اساس متغیرهای صحیح \fBcursor\fP، \fBlimit\fP، \fBmarker\fP، \fBctxmarker\fP و یک رشته (یا byte slice) \fBdata\fP آمده است: .INDENT 7.0 .INDENT 3.5 .sp .nf .ft C YYPEEK := func() byte { return data[cursor] } YYSKIP := func() { cursor++ } YYBACKUP := func() { marker = cursor } YYRESTORE := func() { cursor = marker } YYBACKUPCTX := func() { ctxmarker = cursor } YYRESTORECTX := func() { cursor = ctxmarker } YYLESSTHAN := func(n int) bool { return limit\-cursor < n } YYEND := func(n int) bool { return limit == cursor } YYSHIFT := func(n int) { cursor += n } .ft P .fi .UNINDENT .UNINDENT .UNINDENT .UNINDENT .sp در اینجا فهرست کاملی از عناصر اولیهٔ API که ممکن است توسط کد تولیدشده برای برقراری ارتباط با برنامهٔ بیرونی استفاده شوند آورده شده است. .INDENT 0.0 .TP .B \fBYYCTYPE\fP نوع نویسه‌های ورودی (واحدهای کد یا code units). برای کدگذاری‌های 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 یک عنصر اولیه عمومی 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 یک عنصر اولیه که پیش‌نمونه تابع را در مدل کد \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 یک عنصر اولیه عمومی API با یک متغیر \fBlen\fP\&. این مقدار باید به عنوان یک r\-value از نوع دودویی (boolean) تعریف شود که اگر و تنها اگر کمتر از \fBlen\fP نویسه ورودی باقی مانده باشد، برابر با \fBtrue\fP خواهد بود. .TP .B \fBYYEND\fP یک عنصر اولیه عمومی API بدون هیچ متغیری. این مقدار باید به عنوان یک r\-value از نوع بولی تعریف شود که اگر و تنها اگر به پایان \fIمنطقی\fP ورودی رسیده باشیم (به‌استثنای هرگونه پدینگ یا نمادهای نگهبان)، برابر با \fBtrue\fP خواهد بود. \fBYYEND\fP برای پیاده‌سازی نماد \fB$\fP در عبارات باقاعده به کار می‌رود. این عنصر با \fBYYLESSTHAN\fP تفاوت دارد، که برای اطمینان از نخواندن فراتر از انتهای بافر توسط تحلیل‌گر لغوی استفاده می‌شود. .TP .B \fBYYPEEK\fP یک عنصر اولیه عمومی API بدون هیچ متغیری. این عنصر باید به عنوان یک r\-value از نوع \fBYYCTYPE\fP تعریف شود که برابر با نویسه موجود در موقعیت ورودی جاری است. .TP .B \fBYYSKIP\fP یک عنصر اولیه عمومی API که باید موقعیت ورودی جاری را به اندازه یک واحد کد جلو ببرد. .TP .B \fBYYBACKUP\fP یک عنصر اولیه عمومی API که باید موقعیت ورودی جاری را ذخیره کند (تا بعداً با \fBYYRESTORE\fP بازیابی شود). .TP .B \fBYYRESTORE\fP یک عنصر اولیه عمومی API که باید موقعیت ورودی جاری را به مقدار ذخیره‌شده توسط \fBYYBACKUP\fP بازگرداند. .TP .B \fBYYBACKUPCTX\fP یک عنصر اولیه عمومی API که باید موقعیت ورودی جاری را به عنوان موقعیت بافت پس‌آیند ذخیره کند (تا بعداً با \fBYYRESTORECTX\fP بازیابی شود). .TP .B \fBYYRESTORECTX\fP یک عنصر اولیه عمومی API که باید موقعیت بافت پس‌آیند ذخیره‌شده با \fBYYBACKUPCTX\fP را بازیابی کند. .TP .B \fBYYRESTORETAG\fP یک عنصر اولیه عمومی API با یک متغیر \fBtag\fP که باید موقعیت بافت پس‌آیند را به مقدار \fBtag\fP بازگرداند. .TP .B \fBYYSTAGP\fP یک عنصر اولیه عمومی API با یک متغیر \fBtag\fP، که در آن \fBtag\fP می‌تواند یک اشاره‌گر یا یک افست در \fBYYINPUT\fP باشد (برای جزئیات به بخش استخراج تطابق‌های فرعی مراجعه کنید). \fBYYSTAGP\fP باید \fBtag\fP را روی موقعیت ورودی جاری تنظیم کند. .TP .B \fBYYSTAGN\fP یک عنصر اولیه عمومی API با یک متغیر \fBtag\fP، که در آن \fBtag\fP می‌تواند یک اشاره‌گر یا یک افست در \fBYYINPUT\fP باشد (برای جزئیات به بخش استخراج تطابق‌های فرعی مراجعه کنید). \fBYYSTAGN\fP باید \fBtag\fP را روی مقداری تنظیم کند که نشان‌دهنده موقعیت ورودی ناموجود باشد. .TP .B \fBYYMTAGP\fP یک عنصر اولیه عمومی API با یک متغیر \fBtag\fP\&. \fBYYMTAGP\fP باید موقعیت جاری را به تاریخچه تطابق فرعی \fBtag\fP ضمیمه کند (برای جزئیات به بخش استخراج تطابق‌های فرعی مراجعه کنید). .TP .B \fBYYMTAGN\fP یک عنصر اولیه عمومی API با یک متغیر \fBtag\fP\&. \fBYYMTAGN\fP باید مقداری را که نشان‌دهنده موقعیت ورودی ناموجود است به تاریخچه تطابق فرعی \fBtag\fP ضمیمه کند (برای جزئیات به بخش استخراج تطابق‌های فرعی مراجعه کنید). .TP .B \fBYYSHIFT\fP یک عنصر اولیه عمومی API با یک متغیر \fBshift\fP که باید موقعیت ورودی جاری را به اندازه \fBshift\fP نویسه جابه‌جا کند (مقدار جابه‌جایی ممکن است منفی باشد). .TP .B \fBYYCOPYSTAG\fP یک عنصر اولیه عمومی API با دو متغیر \fBlhs\fP و \fBrhs\fP که باید متغیر s\-tag سمت راست \fBrhs\fP را در متغیر s\-tag سمت چپ \fBlhs\fP کپی کند. برای بیشتر زبان‌ها این عنصر اولیه تعریفی پیش‌فرض دارد که \fBlhs\fP را به \fBrhs\fP انتساب می‌دهد. .TP .B \fBYYCOPYMTAG\fP یک عنصر اولیه عمومی API با دو متغیر \fBlhs\fP و \fBrhs\fP که باید متغیر m\-tag سمت راست \fBrhs\fP را در متغیر m\-tag سمت چپ \fBlhs\fP کپی کند. برای بیشتر زبان‌ها این عنصر اولیه تعریفی پیش‌فرض دارد که \fBlhs\fP را به \fBrhs\fP انتساب می‌دهد. .TP .B \fBYYSHIFTSTAG\fP یک عنصر اولیه عمومی API با دو متغیر \fBtag\fP و \fBshift\fP که باید \fBtag\fP را به اندازه \fBshift\fP واحد کد جابه‌جا کند (مقدار جابه‌جایی ممکن است منفی باشد). .TP .B \fBYYSHIFTMTAG\fP یک عنصر اولیه عمومی API با دو متغیر \fBtag\fP و \fBshift\fP که باید آخرین مقدار در تاریخچه \fBtag\fP را به اندازه \fBshift\fP واحد کد جابه‌جا کند (مقدار جابه‌جایی ممکن است منفی باشد). .TP .B \fBYYMAXNMATCH\fP یک ثابت از نوع عدد صحیح برابر با حداکثر تعداد گروه‌های تسخیرکننده POSIX در یک قاعده. این مقدار با یک بلوک \fBmaxnmatch\fP تولید می‌شود. .TP .B \fBYYCONDTYPE\fP نوع شمارش شرط (condition enum). می‌تواند با بلوک \fBconditions\fP یا گزینه \fB\-\-header\fP تولید شود. .TP .B \fBYYGETACCEPT\fP یک عنصر اولیه با یک متغیر \fBvar\fP که گزینش‌گر عددی قاعده پذیرفته‌شده را ذخیره می‌کند. برای بیشتر زبان‌ها این عنصر اولیه دارای تعریف پیش‌فرضی است که از \fBvar\fP می‌خواند. .TP .B \fBYYSETACCEPT\fP یک عنصر اولیه با دو متغیر: \fBvar\fP (یک l\-value که گزینش‌گر عددی قاعده پذیرفته‌شده را ذخیره می‌کند)، و \fBval\fP (مقدار گزینش‌گر). برای بیشتر زبان‌ها این عنصر اولیه دارای تعریفی پیش‌فرض است که \fBvar\fP را به \fBval\fP انتساب می‌دهد. .TP .B \fBYYGETCOND\fP یک r\-value از نوع \fBYYCONDTYPE\fP که برابر با شناسه شرط جاری است. .TP .B \fBYYSETCOND\fP یک عنصر اولیه با یک متغیر \fBcond\fP که باید شناسه شرط جاری را روی \fBcond\fP تنظیم کند. .TP .B \fBYYGETSTATE\fP یک r\-value از نوع عدد صحیح که برابر با وضعیت جاری تحلیل‌گر لغوی است. مقدار اولیه آن باید برابر با \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 فعال‌سازی استخراج زیرتطبیق با گروه‌های گیرانداز حریصانهٔ چپ‌ترین. نتیجه در آرایهٔ \fByybmatch\fP با ظرفیت \fB2 * YYMAXNMATCH\fP جمع‌آوری شده و \fByynmatch\fP به تعداد گروه‌ها برای قاعدهٔ منطبق تنظیم می‌شود. .TP .B \fB\-\-captvars\fP, \fB\-\-leftmost\-captvars\fP فعال‌سازی استخراج زیرتطبیق با گروه‌های گیرانداز حریصانهٔ چپ‌ترین. نتیجه در متغیرهای \fByytl\fP و \fByytr\fP برای \fBk\fP\-امین گروه گیرانداز ذخیره می‌شود. .TP .B \fB\-\-case\-insensitive\fP در نظر گرفتن رشته‌های درون گیومهٔ تکی و دوتایی به صورت غیرحساس به حروف بزرگ و کوچک. .TP .B \fB\-\-case\-inverted\fP معکوس کردن معنای رشته‌های درون گیومهٔ تکی و دوتایی: در نظر گرفتن رشته‌های درون گیومهٔ تکی به صورت حساس به حروف بزرگ و کوچک و رشته‌های درون گیومهٔ دوتایی به صورت غیرحساس به حروف بزرگ و کوچک. .TP .B \fB\-\-case\-ranges\fP ادغام caseهای متوالی در دستور switch به یک بازه با فرم \fBlow ... high\fP\&. این نحو یک افزونهٔ زبان C/C++ است که توسط کامپایلرهایی مانند GCC، Clang و Tcc پشتیبانی می‌شود. مزیت اصلی نسبت به استفاده از caseهای منفرد، کد تولیدشدهٔ کوچک‌تر و زمان تولید سریع‌تر است، هرچند برای برخی کامپایلرها مانند Tcc به اندازهٔ باینری کوچک‌تر نیز منجر می‌شود. .TP .B \fB\-\-computed\-gotos \-g\fP بهینه‌سازی پرش‌های شرطی با استفاده از افزونهٔ غیر استاندارد \(dqcomputed goto\(dq (که باید توسط کامپایلر پشتیبانی شود). re2go جداول پرش را تنها در موارد پیچیده با شاخه‌های شرطی فراوان تولید می‌کند. آستانهٔ پیچیدگی با پیکربندی \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: چندین لکسر مرتبط به هم درون یک بلوک. این گزینه جایگزینی برای مشخص کردن دستی بلوک‌های مختلف re2go متصل به هم با \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 می‌خواند. re2go فرض می‌کند که محدودهٔ نویسه 0 \-\- 0xFF و اندازهٔ نویسه ۱ بایت است. .TP .B \fB\-\-empty\-class \fP تعریف نحوهٔ برخورد re2go با کلاس‌های نویسهٔ خالی. با \fBmatch\-empty\fP (پیش‌فرض) کلاس خالی با ورودی خالی تطبیق می‌یابد (که غیرمنطقی است، اما با نسخه‌های پیشین سازگار است). با \fBmatch\-none\fP کلاس خالی همواره در تطبیق ناموفق می‌شود. با \fBerror\fP کلاس خالی خطای کامپایل ایجاد می‌کند. .TP .B \fB\-\-encoding\-policy \fP تعریف نحوهٔ برخورد re2go با جانشین‌های یونیکد (Unicode surrogates). با \fBfail\fP در صورت مواجهه با یک جانشین، re2go با خطا متوقف می‌شود. با \fBsubstitute\fP، re2go بدون هشدار جانشین‌ها را با نقطه کد خطای 0xFFFD جایگزین می‌کند. با \fBignore\fP (پیش‌فرض) re2go با جانشین‌ها مانند نقاط کد عادی برخورد می‌کند. استاندارد یونیکد می‌گوید که جانشین‌های مستقل نامعتبر هستند، اما کتابخانه‌ها و برنامه‌های دنیای واقعی به روش‌های مختلفی رفتار می‌کنند. .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 کاربرد دارد. re2go به دنبال \fBFILE\fP در دایرکتوری فایل والد و در مکان‌های include مشخص‌شده با گزینهٔ \fB\-I\fP می‌گردد. .TP .B \fB\-\-input \fP نام مستعار منسوخ‌شده برای \fB\-\-api\fP\&. گزینهٔ \fBdefault\fP با \fBsimple\fP مطابقت دارد (که البته برای بیشتر بک‌اندها پیش‌فرض است، اما نه برای همه). گزینهٔ \fBcustom\fP با \fBgeneric\fP مطابقت دارد. .TP .B \fB\-\-input\-encoding \fP مشخص کردن نحوهٔ تجزیه عبارت‌های منظم توسط re2go. با \fBascii\fP (پیش‌فرض) re2go ورودی را با کدگذاری ASCII پردازش می‌کند: هر دنباله‌ای از واحدهای کد، دنباله‌ای از نویسه‌های مستقل ۱ بایتی است. با \fButf8\fP، re2go ورودی را با کدگذاری 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 دستورالعمل‌های خط خروجی داده نشوند. این گزینه زمانی که کُد تولیدشده در یک سیستم کنترل نسخه نگه‌داری می‌شود مفید است (جهت جلوگیری از ایجاد 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 builds) ناامن است؛ در این حالت گزینهٔ \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 نادیده گرفتن کُد رابط تعریف‌شده توسط کاربر و تولید یک برنامهٔ اسکلتی (\(dqskeleton\(dq) خودکفا. علاوه بر این، تولید فایل‌های ورودی با رشته‌های مشتق‌شده از گرامر باقاعده و نتایج تطابق فشرده‌شده که برای اعتبارسنجی رفتار \(dqskeleton\(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 را می‌خواند. re2go فرض می‌کند که محدودهٔ نویسه 0 \-\- 0xFFFF و اندازهٔ نویسه ۲ بایت است. این گزینه مستلزم \fB\-\-nested\-ifs\fP است. .TP .B \fB\-\-utf8 \-\-utf\-8 \-8\fP تولید تحلیل‌گر لغوی که ورودی با کدگذاری UTF\-8 را می‌خواند. re2go فرض می‌کند که محدودهٔ نویسه 0 \-\- 0x10FFFF و اندازهٔ نویسه ۱ بایت است. .TP .B \fB\-\-utf16 \-\-utf\-16 \-x\fP تولید تحلیل‌گر لغوی که ورودی با کدگذاری UTF16 را می‌خواند. re2go فرض می‌کند که محدودهٔ نویسه 0 \-\- 0x10FFFF و اندازهٔ نویسه ۲ بایت است. این گزینه مستلزم \fB\-\-nested\-ifs\fP است. .TP .B \fB\-\-utf32 \-\-unicode \-u\fP تولید تحلیل‌گر لغوی که ورودی با کدگذاری UTF32 را می‌خواند. re2go فرض می‌کند که محدودهٔ نویسه 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 پس از تونل‌زنی (tunneling) (در قالب .dot). .TP .B \fB\-\-dump\-cfg\fP گزینهٔ اشکال‌زدایی: خروجی دادن گراف جریان کنترل متغیرهای برچسب (در قالب .dot). .TP .B \fB\-\-dump\-closure\-stats\fP گزینهٔ اشکال‌زدایی: خروجی دادن آمار تعداد وضعیت‌ها در بستار (closure). .TP .B \fB\-\-dump\-dfa\-det\fP گزینهٔ اشکال‌زدایی: خروجی دادن DFA بلافاصله پس از قطعی‌سازی (determinization) (در قالب .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 مورداستفاده توسط re2go\&. گزینهٔ \fBmoore\fP الگوریتم مور (Moore) است (که پیش‌فرض است). گزینهٔ \fBtable\fP الگوریتم \(dqپر کردن جدول\(dq است. هر دو الگوریتم باید به جز برچسب‌گذاری مجدد وضعیت‌ها، DFA یکسانی تولید کنند؛ پر کردن جدول ساده‌تر و بسیار کندتر بوده و به عنوان پیاده‌سازی مرجع عمل می‌کند. .TP .B \fB\-\-eager\-skip\fP گزینهٔ داخلی: پیش بردن موقعیت ورودی در تحلیل‌گر لغوی تولیدشده به صورت مشتاقانه (eager) \-\- بلافاصله پس از خواندن نماد ورودی. این گزینه رفتار پیش‌فرض را که در آن موقعیت ورودی به صورت تنبلانه (lazy) و پس از انتقال به وضعیت بعدی پیش برده می‌شود تغییر می‌دهد. .TP .B \fB\-\-no\-lookahead\fP گزینهٔ داخلی، منسوخ شده. قبلاً برای فعال‌سازی الگوریتم TDFA(0) به کار می‌رفت. بر خلاف TDFA(1)، الگوریتم TDFA(0) از پیش‌نگری یک‌نمادی استفاده نمی‌کند. این الگوریتم عملیات ثبات را به جای انتقال‌های خروجی روی انتقال‌های ورودی اعمال می‌کند. ارزیابی‌ها نشان دادند که الگوریتم TDFA(0) کارایی کمتری نسبت به TDFA(1) دارد. .TP .B \fB\-\-no\-optimize\-tags\fP گزینهٔ داخلی: جلوگیری از بهینه‌سازی متغیرهای برچسب (مفید برای اشکال‌زدایی). .TP .B \fB\-\-posix\-closure \fP گزینهٔ داخلی: مشخص کردن الگوریتم کوتاه‌ترین مسیر مورداستفاده برای ساخت بستار اپسیلون با معناشناسی رفع ابهام POSIX: گزینهٔ \fBgor1\fP (پیش‌فرض) بیانگر الگوریتم گلدبرگ\-رادزیک (Goldberg\-Radzik) است، و \fBgtop\fP بیانگر الگوریتم \(dqترتیب توپولوژیک سراسری\(dq است. .TP .B \fB\-\-posix\-prectable \fP گزینهٔ داخلی: مشخص کردن الگوریتم مورداستفاده برای محاسبهٔ جدول اولویت POSIX. الگوریتم \fBcomplex\fP جدول اولویت را در یک پیمایش از درخت تاریخچهٔ برچسب محاسبه می‌کند و دارای پیچیدگی درجه دو بر حسب تعداد وضعیت‌های TNFA است؛ این حالت پیش‌فرض است. الگوریتم \fBnaive\fP در بدترین حالت پیچیدگی مکعبی بر حسب تعداد وضعیت‌های TNFA دارد، اما بسیار ساده‌تر از \fBcomplex\fP است و ممکن است در موارد غیرپاتولوژیک کمی سریع‌تر باشد..TP .B \fB\-\-stadfa\fP گزینه داخلی، منسوخ‌شده. در گذشته برای فعال‌سازی الگوریتم staDFA استفاده می‌شد، که تفاوت آن با TDFA در این است که عملیات‌های ثبات به جای گذارها، در وضعیت‌ها قرار می‌گیرند. ارزیابی‌ها نشان دادند که الگوریتم staDFA کارایی کمتری نسبت به TDFA دارد. .TP .B \fB\-\-fixed\-tags \fP گزینه داخلی: مشخص می‌کند که آیا بهینه‌سازی برچسب ثابت (fixed\-tag) باید روی همهٔ برچسب‌ها (\fBall\fP)، هیچ‌کدام از آن‌ها (\fBnone\fP)، یا فقط برچسب‌های موجود در الحاق سطح بالا (\fBtoplevel\fP) اعمال شود یا خیر. مقدار پیش‌فرض \fBall\fP\& است. برچسب‌های \(dqثابت\(dq برچسب‌هایی هستند که در فاصلهٔ ثابتی از برچسب دیگری (به نام \(dqbase\(dq یا پایه) قرار دارند. در چنین مواردی فقط برچسب پایه نیاز به رهگیری دارد و مقدار برچسب ثابت می‌تواند از طریق مقدار برچسب پایه به‌علاوهٔ یک آفست ایستا محاسبه شود. برای برچسب‌هایی که تحت انشعاب یا تکرار هستند، بررسی این‌که آیا برچسب پایه مقدار عدم تطابق (no\-match) دارد نیز ضروری است (در این حالت برچسب ثابت نیز باید بدون در نظر گرفتن آفست، روی no\-match تنظیم شود). برای برچسب‌ها در الحاق سطح بالا این بررسی لازم نیست، زیرا آن‌ها همیشه مطابقت دارند. .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 هشدار در صورتی که یک عبارت منظم حاوی یک رده نویسه‌ای خالی باشد. تلاش برای تطبیق با یک رده نویسه‌ای خالی بی‌معنی است: این کار همیشه باید ناموفق باشد. با این حال، به دلایل سازگاری عقبرو، re2go رده‌های نویسه‌ای خالی را مجاز دانسته و با آن‌ها مانند رشته‌های خالی رفتار می‌کند. از گزینهٔ \fB\-\-empty\-class\fP برای تغییر رفتار پیش‌فرض استفاده کنید. .TP .B \fB\-Wmatch\-empty\-string\fP هشدار در صورتی که یک قاعده تهی‌پذیر باشد (با یک رشتهٔ خالی تطبیق یابد). اگر تحلیل‌گر لغوی در یک حلقه اجرا شود و تطبیق تهی ناخواسته باشد، ممکن است تحلیل‌گر لغوی به‌طور غیرمنتظره در یک حلقهٔ بی‌پایان متوقف شود (hang کند). .TP .B \fB\-Wswapped\-range\fP هشدار در صورتی که کران پایین یک بازه از کران بالای آن بزرگ‌تر باشد. رفتار پیش‌فرض این است که بدون هشدار جای کران‌های بازه با یکدیگر عوض شود. .TP .B \fB\-Wundefined\-control\-flow\fP هشدار در صورتی که برخی از رشته‌های ورودی باعث جریان کنترل تعریف‌نشده در تحلیل‌گر لغوی شوند (الگوهای دارای اشکال گزارش می‌شوند). این یک خطای خطرناک و رایج است. می‌توان آن را با افزودن قاعدهٔ پیش‌فرض \fB*\fP که کمترین اولویت را دارد، با هر واحد کد مطابقت دارد و همیشه یک واحد کد منفرد را مصرف می‌کند، به آسانی اصلاح کرد. .TP .B \fB\-Wunreachable\-rules\fP هشدار دربارهٔ قواعدی که توسط قواعد دیگر تحت‌الشعاع قرار گرفته‌اند (shadowed) و هرگز مطابقت نخواهند یافت. .TP .B \fB\-Wdeprecated\-eof_rule\fP هشدار دربارهٔ قواعد مستقل پایان ورودی \fB$\fP که با تغییرات آینده دچار شکست خواهند شد و نیاز به اصلاح دارند. در حال حاضر، این قواعد در زمان تداخل با قواعد دیگر اولویت دارند، اما پس از معرفی نماد تعمیم‌یافتهٔ پایان ورودی \fB$\fP، ترتیب اولویت تغییر خواهد کرد و این قواعد توسط قواعد دیگر تحت‌الشعاع قرار خواهند گرفت. .TP .B \fB\-Wuseless\-escape\fP هشدار در صورتی که یک نماد در جایی که نباید، گریز (escape) داده شود. به‌طور پیش‌فرض، re2go بدون هشدار چنین گریزهایی را نادیده می‌گیرد، اما این حالت می‌تواند نشان‌دهندهٔ یک غلط املایی یا خطا در توالی گریز باشد. .TP .B \fB\-Wnondeterministic\-tags\fP هشدار در صورتی که یک برچسب دارای درجهٔ \fBn\fP\-ام از عدم قطعیت باشد، جایی که \fBn\fP بزرگ‌تر از ۱ است. .TP .B \fB\-Wsentinel\-in\-midrule\fP هشدار در صورتی که نماد نگهبان در وسط یک قاعده رخ دهد \-\-\- این امر ممکن است باعث خواندن داده فراتر از انتهای بافر، از کار افتادن (crash) یا تخریب حافظه در تحلیل‌گر لغوی تولیدشده شود. این هشدار تنها در صورتی کاربرد دارد که از روش نماد نگهبان برای بررسی پایان ورودی استفاده شود. در صورت استفاده از پیکربندی \fBre2c:sentinel\fP، این وضعیت به یک خطا تبدیل خواهد شد. .TP .B \fB\-Wundefined\-syntax\-config\fP هشدار در صورتی که فایل نحو مشخص‌شده با گزینهٔ \fB\-\-syntax\fP فاقد تعاریف برخی از پیکربندی‌ها باشد. این ویژگی به نگهداری فایل‌های نحو تعریف‌شده توسط کاربر کمک می‌کند: اگر نسخهٔ جدیدی پیکربندی‌هایی را اضافه کند، فایل نحو قدیمی هشداری را صادر کرده و به کاربر اطلاع داده خواهد شد. اگر برخی از پیکربندی‌ها استفاده نمی‌شوند و نیازی به تعریف ندارند، باید به‌طور صریح روی \fB\fP\& تنظیم شوند. .UNINDENT.SS پرونده‌های نحو (Syntax files) .sp پشتیبانی از زبان‌های گوناگون در re2c بر پایه ایده \fIپرونده‌های نحو\fP (syntax files) بنا شده است\&. یک پرونده نحو، یک پرونده پیکربندی است که نحو زبان مقصد را تعریف می‌کند \-\- نه کل زبان، بلکه بخش کوچکی از آن را که توسط کد تولیدشده استفاده می‌شود. پرونده‌های نحو re2c را بسیار منعطف می‌سازند، اما نباید به عنوان جایگزینی برای پیکربندی‌های \fBre2c:\fP استفاده شوند: هدف آن‌ها تعریف نحو زبان مقصد است، نه سفارشی‌سازی یک تحلیل‌گر لغوی خاص. تمام زبان‌های پشتیبانی‌شده دارای پرونده‌های نحو پیش‌فرضی هستند که بخشی از بسته توزیع به شمار می‌روند (زیرپوشه \fBinclude/syntax\fP را ببینید)؛ آن‌ها همچنین در باینری re2go نیز گنجانده شده‌اند. کاربران می‌توانند یک پرونده نحو سفارشی ارائه دهند که چند پیکربندی را برای یکی از زبان‌های پشتیبانی‌شده بازنویسی می‌کند، یا می‌توانند همه پیکربندی‌ها را مجدداً تعریف نمایند (در این حالت گزینه \fB\-\-lang none\fP باید استفاده شود). پرونده‌های نحو شامل چهار گونه پیکربندی مختلف هستند: فهرست ویژگی‌ها، پیکربندی‌های زبان، پیکربندی‌های درجا (inplace) و قالب‌های کد. .sp \fBفهرست ویژگی‌ها (Feature lists)\fP .INDENT 0.0 .INDENT 3.5 چند پیکربندی فهرستی، ویژگی‌های گوناگون پشتیبانی‌شده توسط یک بک‌اند مشخص را تعریف می‌کنند تا در صورتی که کاربر تلاش کند یک ویژگی پشتیبانی‌نشده را فعال سازد، re2go بتواند خطای واضحی صادر کند: .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 چند پیکربندی بولی ویژگی‌هایی از زبان مقصد را توصیف می‌کنند که بر تجزیه‌کننده و تولیدکننده کد re2go اثر می‌گذارند: .INDENT 0.0 .TP .B \fBsemicolons\fP غیر صفر اگر زبان پس از گزاره‌ها از نقطه‌ویرگول (semicolon) استفاده می‌کند. .TP .B \fBbacktick_quoted_strings\fP غیر صفر اگر زبان دارای رشته‌های محصور در بک‌تیک (backtick) است. .TP .B \fBsingle_quoted_strings\fP غیر صفر اگر زبان دارای رشته‌های محصور در تک‌نقل‌قول (single quote) است. .TP .B \fBindentation_sensitive\fP غیر صفر اگر زبان به دندانه‌گذاری (indentation) حساس است. .TP .B \fBwrap_blocks_in_braces\fP غیر صفر اگر گزاره‌های مرکب باید در آکولاد محصور شوند. .UNINDENT .UNINDENT .UNINDENT .sp \fBپیکربندی‌های درجا (Inplace configurations)\fP .INDENT 0.0 .INDENT 3.5 پرونده‌های نحو مقادیر اولیه تمام پیکربندی‌های \fBre2c:\fP را تعیین می‌کنند، چرا که ممکن است برای زبان‌های مختلف متفاوت باشند. برای فهرست کاملی از تمام پیکربندی‌های درجا و معنای آن‌ها بخش پیکربندی‌ها را ببینید. .UNINDENT .UNINDENT .sp \fBقالب‌های کد (Code templates)\fP .INDENT 0.0 .INDENT 3.5 قالب‌های کد، نحو زبان مقصد را تعریف می‌کنند. آن‌ها در یک زبان ساده دامنه-خاص با دستور زبان رسمی زیر نوشته می‌شوند: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C code\-template :: name \(aq=\(aq code\-exprs \(aq;\(aq | CODE_TEMPLATE \(aq;\(aq | \(aq\(aq \(aq;\(aq code\-exprs :: | code\-exprs code\-expr code\-expr :: STRING | VARIABLE | optional | list optional :: \(aq(\(aq CONDITIONAL \(aq?\(aq code\-exprs \(aq)\(aq | \(aq(\(aq CONDITIONAL \(aq?\(aq code\-exprs \(aq:\(aq code\-exprs \(aq)\(aq list :: \(aq[\(aq VARIABLE \(aq:\(aq code\-exprs \(aq]\(aq | \(aq[\(aq VARIABLE \(aq{\(aq NUMBER \(aq}\(aq \(aq:\(aq code\-exprs \(aq]\(aq | \(aq[\(aq VARIABLE \(aq{\(aq NUMBER \(aq,\(aq NUMBER \(aq}\(aq \(aq:\(aq code\-exprs \(aq]\(aq .ft P .fi .UNINDENT .UNINDENT .sp یک قالب کد دنباله‌ای از رشته‌های لفظی، متغیرها، عنصرهای اختیاری و فهرست‌ها، یا ارجاعی به یک قالب کد دیگر، یا مقدار ویژه \fB\fP است\&. متغیرها جای‌نگه‌دارنده‌هایی هستند که در طول مرحله تولید کد جایگزین می‌شوند. متغیرهای فهرست خاص هستند: هنگام بسط دادن قالب‌های فهرست، re2go عبارت‌های سمت راست دو‌نقطه را چند بار تکرار می‌کند و هر بار رخدادهای متغیر فهرست را با مقداری مختص این تکرار جایگزین می‌سازد. فهرست‌ها دارای کران‌های اختیاری هستند (مقدارهای منفی از انتها شمرده می‌شوند، مثلاً \fB\-1\fP به معنای آخرین عنصر است). نام شرطی‌ها با یک نقطه آغاز می‌شود. هم شرطی‌ها و هم متغیرها می‌توانند محلی (مخصوص قالب کد داده‌شده) یا سراسری (مجاز در تمام قالب‌های کد) باشند. هنگامی که re2go یک پرونده نحو را می‌خواند، بررسی می‌کند که هر قالب کد تنها از متغیرها و شرطی‌هایی استفاده کند که در آن مجاز هستند. .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 در ادامه فهرستی از تمام قالب‌های کد پشتیبانی‌شده توسط re2go به همراه متغیرها و شرطی‌های محلی آن‌ها آورده شده است. توجه داشته باشید که یک تعریف خاص می‌تواند از متغیرها و شرطی‌های محلی استفاده کند، اما الزامی به آن ندارد. هر قالب کد استفاده‌نشده باید برابر با \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، با این تفاوت که در بالاترین سطح استفاده می‌شود. .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، با این تفاوت که در بالاترین سطح استفاده می‌شود. .TP .B \fBcode:array_elem\fP ارجاع به عنصری از یک آرایه (جدول). متغیرهای پشتیبانی‌شده: \fBarray\fP (نام آرایه) و \fBindex\fP (نمایه عنصر). .TP .B \fBcode:enum\fP تعریف یک شمارش یا enumeration (ممکن است با استفاده از یک سازهٔ زبانی ویژه برای شمارش‌ها تعریف شود، یا صرفاً به عنوان چند مقدار ثابت مستقل). متغیرهای پشتیبانی‌شده عبارتند از \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 نوع عدد صحیح علامت‌دار (signed integer). .TP .B \fBcode:type_uint\fP نوع عدد صحیح بدون علامت (unsigned integer). .TP .B \fBcode:type_yybm\fP نوع عناصر در جدول \fByybm\fP. .TP .B \fBcode:type_yytarget\fP نوع عناصر در جدول \fByytarget\fP. .TP .B \fBcode:type_yyctable\fP نوع عناصر در جدول \fByyctable\fP. .TP .B \fBcode:cmp_eq\fP عملگر «برابر» (\(dqequals\(dq). .TP .B \fBcode:cmp_ne\fP عملگر «نامساوی» (\(dqnot equals\(dq). .TP .B \fBcode:cmp_lt\fP عملگر «کوچک‌تر از» (\(dqless than\(dq). .TP .B \fBcode:cmp_gt\fP عملگر «بزرگ‌تر از» (\(dqgreater than\(dq). .TP .B \fBcode:cmp_le\fP عملگر «کوچک‌تر یا مساوی» (\(dqless or equal\(dq). .TP .B \fBcode:cmp_ge\fP عملگر «بزرگ‌تر یا مساوی» (\(dqgreater or equal\(dq). .TP .B \fBcode:if_then_else\fP دستور if\-then\-else با یک یا چند شاخه. متغیرهای پشتیبانی‌شده: \fBbranch\fP (متغیر فهرستی که به خودی خود کدی تولید نمی‌کند، اما عبارت فهرست را به تعداد شاخه‌ها بسط می‌دهد)، \fBcond\fP (شرط شاخه جاری) و \fBstmt\fP (متغیر فهرستی که به تمام دستورات در شاخه جاری بسط می‌یابد). شرط‌ها: \fB\&.cond\fP (اگر شاخه جاری دارای شرط باشد، درست است)، \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 گروهی از caseهای switch که به یک بلوک کد واحد نگاشت می‌شوند. متغیرهای پشتیبانی‌شده عبارتند از \fBcase\fP (متغیر فهرستی که به تمام caseهای موجود در این گروه بسط می‌یابد) و \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 حالت پیش‌فرض (default) در switch. .TP .B \fBcode:loop\fP حلقه‌ای که تا ابد اجرا می‌شود (مگر اینکه از درون بدنه حلقه متوقف شود). متغیرهای پشتیبانی‌شده: \fBlabel\fP (برچسب حلقه)، \fBstmt\fP (متغیر فهرستی که به تمام دستورات موجود در بدنه حلقه بسط می‌یابد). .TP .B \fBcode:continue\fP دستور continue. متغیرهای پشتیبانی‌شده: \fBlabel\fP (برچسبی که اجرای برنامه از آن ادامه می‌یابد). .TP .B \fBcode:goto\fP دستور goto. متغیرهای پشتیبانی‌شده: \fBlabel\fP (برچسب مقصد پرش). .TP .B \fBcode:cgoto\fP دستور \fBgoto\fP محاسباتی (computed \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 اثرانگشت (fingerprint) در بالای فایل خروجی تولیدشده. متغیرهای پشتیبانی‌شده: \fBver\fP (نسخهٔ re2go که برای تولید این فایل استفاده شده است) و \fBdate\fP (تاریخ تولید). .TP .B \fBcode:line_info\fP قالب دستورالعمل‌های خط (اگر روی \fB\fP تنظیم شود، هیچ دستورالعملی تولید نمی‌شود). متغیرهای پشتیبانی‌شده: \fBline\fP (شماره خط) و \fBfile\fP (نام فایل). .TP .B \fBcode:abort\fP عبارتی که اجرای برنامه را متوقف (abort) می‌کند. .TP .B \fBcode:yydebug\fP عبارت \fBYYDEBUG\fP، احتمالاً تخصیص‌یافته برای APIهای گوناگون. متغیرهای پشتیبانی‌شده: \fBYYDEBUG\fP، \fByyrecord\fP، \fByych\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBstate\fP (شماره وضعیت DFA). .TP .B \fBcode:yypeek\fP عبارت \fBYYPEEK\fP، احتمالاً تخصیص‌یافته برای APIهای گوناگون. متغیرهای پشتیبانی‌شده: \fBYYPEEK\fP، \fBYYCTYPE\fP، \fBYYINPUT\fP، \fBYYCURSOR\fP، \fByyrecord\fP، \fByych\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP). شروط: \fB\&.cast\fP (درست اگر \fBre2c:yych:conversion\fP روی مقداری غیر از صفر تنظیم شده باشد). .TP .B \fBcode:yyskip\fP عبارت \fBYYSKIP\fP، احتمالاً تخصیص‌یافته برای APIهای گوناگون. متغیرهای پشتیبانی‌شده: \fBYYSKIP\fP، \fBYYCURSOR\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP). .TP .B \fBcode:yybackup\fP عبارت \fBYYBACKUP\fP، احتمالاً تخصیص‌یافته برای APIهای گوناگون. متغیرهای پشتیبانی‌شده: \fBYYBACKUP\fP، \fBYYCURSOR\fP، \fBYYMARKER\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP). .TP .B \fBcode:yybackupctx\fP عبارت \fBYYBACKUPCTX\fP، احتمالاً تخصیص‌یافته برای APIهای گوناگون. متغیرهای پشتیبانی‌شده: \fBYYBACKUPCTX\fP، \fBYYCURSOR\fP، \fBYYCTXMARKER\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP). .TP .B \fBcode:yyskip_yypeek\fP عبارت ترکیبی \fBcode:yyskip\fP و \fBcode:yypeek\fP (به‌طور پیش‌فرض \fBcode:yyskip\fP و سپس \fBcode:yypeek\fP). .TP .B \fBcode:yypeek_yyskip\fP عبارت ترکیبی \fBcode:yypeek\fP و \fBcode:yyskip\fP (به‌طور پیش‌فرض \fBcode:yypeek\fP و سپس \fBcode:yyskip\fP). .TP .B \fBcode:yyskip_yybackup\fP عبارت ترکیبی \fBcode:yyskip\fP و \fBcode:yybackup\fP (به‌طور پیش‌فرض \fBcode:yyskip\fP و سپس \fBcode:yybackup\fP). .TP .B \fBcode:yybackup_yyskip\fP عبارت ترکیبی \fBcode:yybackup\fP و \fBcode:yyskip\fP (به‌طور پیش‌فرض \fBcode:yybackup\fP و سپس \fBcode:yyskip\fP). .TP .B \fBcode:yybackup_yypeek\fP عبارت ترکیبی \fBcode:yybackup\fP و \fBcode:yypeek\fP (به‌طور پیش‌فرض \fBcode:yybackup\fP و سپس \fBcode:yypeek\fP). .TP .B \fBcode:yyskip_yybackup_yypeek\fP عبارت ترکیبی \fBcode:yyskip\fP، \fBcode:yybackup\fP و \fBcode:yypeek\fP (به‌طور پیش‌فرض \(ga\(gacode:yyskip\(ga\(ga و سپس \fBcode:yybackup\fP و به دنبال آن \fBcode:yypeek\fP). .TP .B \fBcode:yybackup_yypeek_yyskip\fP عبارت ترکیبی \fBcode:yybackup\fP، \fBcode:yypeek\fP و \fBcode:yyskip\fP (به‌طور پیش‌فرض \(ga\(gacode:yybackup\(ga\(ga و سپس \fBcode:yypeek\fP و به دنبال آن \fBcode:yyskip\fP). .TP .B \fBcode:yyrestore\fP عبارت \fBYYRESTORE\fP، احتمالاً تخصیص‌یافته برای APIهای گوناگون. متغیرهای پشتیبانی‌شده: \fBYYRESTORE\fP، \fBYYCURSOR\fP، \fBYYMARKER\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP). .TP .B \fBcode:yyrestorectx\fP عبارت \fBYYRESTORECTX\fP، احتمالاً تخصیص‌یافته برای APIهای گوناگون. متغیرهای پشتیبانی‌شده: \fBYYRESTORECTX\fP، \fBYYCURSOR\fP، \fBYYCTXMARKER\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP). .TP .B \fBcode:yyrestoretag\fP عبارت \fBYYRESTORETAG\fP، احتمالاً تخصیص‌یافته برای APIهای گوناگون. متغیرهای پشتیبانی‌شده: \fBYYRESTORETAG\fP، \fBYYCURSOR\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBtag\fP (نام متغیر برچسب که برای بازیابی موقعیت استفاده می‌شود). .TP .B \fBcode:yyshift\fP عبارت \fBYYSHIFT\fP، احتمالاً تخصیص‌یافته برای APIهای گوناگون. متغیرهای پشتیبانی‌شده: \fBYYSHIFT\fP، \fBYYCURSOR\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBoffset\fP (تعداد واحدهای کد برای جابه‌جا کردن موقعیت فعلی). .TP .B \fBcode:yyshiftstag\fP عبارت \fBYYSHIFTSTAG\fP، احتمالاً تخصیص‌یافته برای APIهای گوناگون. متغیرهای پشتیبانی‌شده: \fBYYSHIFTSTAG\fP، \fByyrecord\fP، \fBnegative\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBtag\fP (متغیر برچسبی که باید جابه‌جا شود)، \fBoffset\fP (تعداد واحدهای کد برای جابه‌جایی). شروط: \fB\&.nested\fP (درست اگر این یک برچسب تودرتو باشد \-\- در این حالت مقدار آن ممکن است برابر با \fBre2c:tags:negative\fP باشد، که نباید جابه‌جا شود). .TP .B \fBcode:yyshiftmtag\fP عبارت \fBYYSHIFTMTAG\fP، احتمالاً تخصیص‌یافته برای APIهای گوناگون. متغیرهای پشتیبانی‌شده: \fBYYSHIFTMTAG\fP (نگاشت به پیکربندی متناظر \fBre2c:\fP)، \fBtag\fP (متغیر برچسبی که باید جابه‌جا شود)، \fBoffset\fP (تعداد واحدهای کد برای جابه‌جایی). .TP .B \fBcode:yystagp\fP عبارت \fBYYSTAGP\fP، احتمالاً تخصیص‌یافته برای APIهای گوناگون. متغیرهای پشتیبانی‌شده: \fBYYSTAGP\fP، \fBYYCURSOR\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBtag\fP (متغیر برچسبی که باید به‌روزرسانی شود). .TP .B \fBcode:yymtagp\fP عبارت \fBYYMTAGP\fP، احتمالاً تخصیص‌یافته برای APIهای گوناگون. متغیرهای پشتیبانی‌شده: \fBYYMTAGP\fP (نگاشت به پیکربندی متناظر \fBre2c:\fP)، \fBtag\fP (متغیر برچسبی که باید به‌روزرسانی شود). .TP .B \fBcode:yystagn\fP عبارت \fBYYSTAGN\fP، احتمالاً تخصیص‌یافته برای APIهای گوناگون. متغیرهای پشتیبانی‌شده: \fBYYSTAGN\fP، \fBnegative\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBtag\fP (متغیر برچسبی که باید به‌روزرسانی شود). .TP .B \fBcode:yymtagn\fP عبارت \fBYYMTAGN\fP، احتمالاً تخصیص‌یافته برای APIهای گوناگون. متغیرهای پشتیبانی‌شده: \fBYYMTAGN\fP (نگاشت به پیکربندی متناظر \fBre2c:\fP)، \fBtag\fP (متغیر برچسبی که باید به‌روزرسانی شود). .TP .B \fBcode:yycopystag\fP عبارت \fBYYCOPYSTAG\fP، احتمالاً تخصیص‌یافته برای APIهای گوناگون. متغیرهای پشتیبانی‌شده: \fBYYCOPYSTAG\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBlhs\fP، \fBrhs\fP (متغیرهای برچسب سمت چپ و راست در عملیات رونوشت). .TP .B \fBcode:yycopymtag\fP عبارت \fBYYCOPYMTAG\fP، احتمالاً تخصیص‌یافته برای APIهای گوناگون. متغیرهای پشتیبانی‌شده: \fBYYCOPYMTAG\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBlhs\fP، \fBrhs\fP (متغیرهای برچسب سمت چپ و راست در عملیات رونوشت). .TP .B \fBcode:yygetaccept\fP عبارت \fBYYGETACCEPT\fP، احتمالاً تخصیص‌یافته برای APIهای گوناگون. متغیرهای پشتیبانی‌شده: \fBYYGETACCEPT\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBvar\fP (نگاشت به پیکربندی \fBre2c:yyaccept\fP). .TP .B \fBcode:yysetaccept\fP عبارت \fBYYSETACCEPT\fP، احتمالاً تخصیص‌یافته برای APIهای گوناگون. متغیرهای پشتیبانی‌شده: \fBYYSETACCEPT\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBvar\fP (نگاشت به پیکربندی \fBre2c:yyaccept\fP) و \fBval\fP (مقدار عددی قاعدهٔ پذیرفته‌شده). .TP .B \fBcode:yygetcond\fP عبارت \fBYYGETCOND\fP، احتمالاً تخصیص‌یافته برای APIهای گوناگون. متغیرهای پشتیبانی‌شده: \fBYYGETCOND\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBvar\fP (نگاشت به پیکربندی \fBre2c:yycond\fP). .TP .B \fBcode:yysetcond\fP عبارت \fBYYSETCOND\fP، احتمالاً تخصیص‌یافته برای APIهای گوناگون. متغیرهای پشتیبانی‌شده: \fBYYSETCOND\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBvar\fP (نگاشت به پیکربندی \fBre2c:yycond\fP) و \fBval\fP (شناسهٔ عددی شرط). .TP .B \fBcode:yygetstate\fP عبارت \fBYYGETSTATE\fP، احتمالاً تخصیص‌یافته برای APIهای گوناگون. متغیرهای پشتیبانی‌شده: \fBYYGETSTATE\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBvar\fP (نگاشت به پیکربندی \fBre2c:yystate\fP). .TP .B \fBcode:yysetstate\fP عبارت \fBYYSETSTATE\fP، احتمالاً تخصیص‌یافته برای APIهای گوناگون. متغیرهای پشتیبانی‌شده: \fBYYSETSTATE\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBvar\fP (نگاشت به پیکربندی \fBre2c:yystate\fP) و \fBval\fP (شماره وضعیت). .TP .B \fBcode:yylessthan\fP عبارت \fBYYLESSTHAN\fP، احتمالاً تخصیص‌یافته برای APIهای گوناگون. متغیرهای پشتیبانی‌شده: \fBYYLESSTHAN\fP، \fBYYCURSOR\fP، \fBYYLIMIT\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBneed\fP (تعداد واحدهای کد برای بررسی در برابر آن). شرط: \fB\&.many\fP (درست اگر \fBneed\fP بیش از یک باشد)..TP .B \fBcode:yyend\fP عبارت \fBYYEND\fP، احتمالاً تخصیص‌یافته برای APIهای گوناگون. متغیرهای پشتیبانی‌شده: \fBYYEND\fP، \fBYYCURSOR\fP، \fBYYLIMIT\fP\&. .TP .B \fBcode:yybm_filter\fP شرطی که برای فیلتر کردن مقادیر \fByych\fP که تحت پوشش جدول \fByybm\fP نیستند استفاده می‌شود (همراه با گزینهٔ \fB\-\-bitmaps\fP به کار می‌رود). متغیر پشتیبانی‌شده: \fByych\fP (به پیکربندی \fBre2c:yych\fP نگاشت می‌شود). .TP .B \fBcode:yybm_match\fP قالب بررسی جدول \fByybm\fP (تولیدشده با گزینهٔ \fB\-\-bitmaps\fP). متغیرهای پشتیبانی‌شده: \fByybm\fP، \fByych\fP (به پیکربندی‌های متناظر \fBre2c:\fP نگاشت می‌شوند)، \fBoffset\fP (آفست در جدول \fByybm\fP که باید به \fByych\fP اضافه شود) و \fBmask\fP (ماسک بیتی که باید روی مدخل جدول اعمال شود تا مقدار بولی که باید بررسی شود بازیابی گردد). .TP .B \fBcode:yytarget_filter\fP شرطی که برای فیلتر کردن مقادیر \fByych\fP که تحت پوشش جدول \fByytarget\fP نیستند استفاده می‌شود (همراه با گزینهٔ \fB\-\-computed\-gotos\fP به کار می‌رود). متغیر پشتیبانی‌شده: \fByych\fP (به پیکربندی \fBre2c:yych\fP نگاشت می‌شود). .UNINDENT .sp در اینجا فهرستی از تمام متغیرهای سراسری که در فایل‌های نحو مجاز هستند آمده است: .INDENT 0.0 .TP .B \fBnl\fP یک خط جدید. .TP .B \fBindent\fP متغیری که هیچ کدی تولید نمی‌کند، اما اثر جانبیِ افزایش سطح تورفتگی را دارد. .TP .B \fBdedent\fP متغیری که هیچ کدی تولید نمی‌کند، اما اثر جانبیِ کاهش سطح تورفتگی را دارد. .TP .B \fBtopindent\fP رشتهٔ تورفتگی برای دستور فعلی. سطح تورفتگی توسط تولیدکنندهٔ کد پیگیری شده و به‌طور خودکار به‌روزرسانی می‌شود. .UNINDENT .sp در اینجا فهرستی از تمام شرط‌های سراسری که در فایل‌های نحو مجاز هستند آمده است: .INDENT 0.0 .TP .B \fB\&.api.simple\fP درست (True) اگر از API ساده استفاده شود (\fB\-\-api simple\fP یا \fBre2c:api = simple\fP). .TP .B \fB\&.api.generic\fP درست (True) اگر از API عمومی استفاده شود (\fB\-\-api generic\fP یا \fBre2c:api = generic\fP). .TP .B \fB\&.api.record\fP درست (True) اگر از API ثبتی استفاده شود (\fB\-\-api record\fP یا \fBre2c:api = record\fP). .TP .B \fB\&.api_style.functions\fP درست (True) اگر از سبک API تابع‌گونه استفاده شود (\fBre2c:api\-style = functions\fP). .TP .B \fB\&.api_style.freeform\fP درست (True) اگر از سبک API آزاد استفاده شود (\fBre2c:api\-style = free\-form\fP). .TP .B \fB\&.case_ranges\fP درست (True) اگر قابلیت محدوده‌های مورد فعال باشد (\fB\-\-case\-ranges\fP یا \fBre2c:case\-ranges = 1\fP). .TP .B \fB\&.cgoto.relative\fP درست (True) اگر شکل نسبی \fBgoto\fP محاسبه‌شده استفاده شود (\fB\-\-computed\-gotos\-relative\fP یا \fBre2c:cgoto:relative = 1\fP). .TP .B \fB\&.code_model.goto_label\fP درست (True) اگر مدل کد مبتنی بر goto/label استفاده شود (\fB\-\-goto\-label\fP). .TP .B \fB\&.code_model.loop_switch\fP درست (True) اگر مدل کد مبتنی بر loop/switch استفاده شود (\fB\-\-loop\-switch\fP). .TP .B \fB\&.code_model.recursive_functions\fP درست (True) اگر مدل کد مبتنی بر توابع بازگشتی استفاده شود (\fB\-\-recursive\-function\fP). .TP .B \fB\&.date\fP درست (True) اگر اثر انگشت تولیدشده باید شامل تاریخ تولید باشد. .TP .B \fB\&.loop_label\fP درست (True) اگر حلقه‌های تولیدشده توسط re2go باید دارای برچسب باشند (\fBre2c:label:yyloop\fP روی یک رشتهٔ غیرخالی تنظیم شده باشد). .TP .B \fB\&.monadic\fP درست (True) اگر کد تولیدشده باید مونادیک باشد (\fBre2c:monadic = 1\fP). این مورد فقط برای زبان‌های کاملاً تابعی مرتبط است. .TP .B \fB\&.start_conditions\fP درست (True) اگر شرایط شروع فعال باشند (\fB\-\-start\-conditions\fP). .TP .B \fB\&.storable_state\fP درست (True) اگر وضعیت قابل ذخیره‌سازی فعال باشد (\fB\-\-storable\-state\fP). .TP .B \fB\&.unsafe\fP درست (True) اگر re2go باید از بلوک‌های \(dqunsafe\(dq به‌منظور تولید کد سریع‌تر استفاده کند (\fB\-\-unsafe\fP، \fBre2c:unsafe = 1\fP). این تنها برای زبان‌هایی که ویژگی \(dqunsafe\(dq دارند مرتبط است. .TP .B \fB\&.version\fP درست (True) اگر اثر انگشت تولیدشده باید شامل نسخهٔ re2go باشد. .TP .B \fB\&.yyfill.enable\fP درست (True) اگر \fBYYFILL\fP فعال باشد (\fBre2c:yyfill:enable = 1\fP). .TP .B \fB\&.yyfn.throw\fP درست (True) اگر پیکربندی \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 دو شرط نخست، تحلیل‌گر را به روشی «طبیعی» پایان می‌دهند: تحلیل‌گر به وضعیتی بدون هیچ انتقال خروجی می‌رسد و تطبیق به‌طور خودکار متوقف می‌شود. شرط سوم، یعنی پایان ورودی، متفاوت است: این حالت ممکن است در هر وضعیتی رخ دهد و تحلیل‌گر باید بتواند آن را مدیریت کند. بررسی پایان ورودی، گردش کار عادی تحلیل‌گر را مختل کرده و شاخه‌های شرطی را به برنامهٔ تولیدشده اضافه می‌کند؛ بنابراین ضروری است که تعداد چنین بررسی‌هایی به حداقل برسد. re2go از چند روش گوناگون برای مدیریت پایان ورودی پشتیبانی می‌کند. این‌که از کدام روش استفاده شود به پیچیدگی عبارات باقاعده، نیاز به بافرسازی، ملاحظات کارایی و سایر عوامل بستگی دارد. در ادامه فهرستی از این روش‌ها آورده شده است: .INDENT 0.0 .IP \(bu 2 \fBدیده‌بان (Sentinel).\fP این روش نیاز به بررسی‌های پایان ورودی را به‌طور کامل از بین می‌برد. این روش ساده و کارآمد است، اما محدود به مواردی است که یک نویسهٔ «دیده‌بان» (sentinel) طبیعی وجود داشته باشد که هرگز نتواند در ورودی معتبر رخ دهد. این نویسه ممکن است همچنان در ورودی نامعتبر ظاهر شود، اما نباید توسط عبارات باقاعده مجاز دانسته شود، مگر شاید به‌عنوان آخرین نویسهٔ یک قاعده. دیده‌بان به انتهای ورودی افزوده می‌شود و به‌عنوان یک سیگنال توقف عمل می‌کند: هنگامی که تحلیل‌گر این نویسه را می‌خواند، یا یک خطای نحوی رخ داده یا پایان ورودی است. در هر دو حالت، تحلیل‌گر باید متوقف شود. از این روش در صورتی استفاده می‌شود که \fBYYFILL\fP با \fBre2c:yyfill:enable = 0;\fP غیرفعال شده باشد و \fBre2c:eof\fP مقدار پیش‌فرض \fB\-1\fP را داشته باشد. .nf .fi .sp .IP \(bu 2 \fBدیده‌بان با بررسی مرزها (Sentinel with bounds checks).\fP این روش عمومی است: امکان مدیریت هر ورودی را بدون هیچ محدودیتی بر عبارات باقاعده فراهم می‌کند. ایدهٔ کار کاهش تعداد بررسی‌های پایان ورودی از طریق انجام آن‌ها تنها روی نویسه‌های خاصی است. مشابه روش «دیده‌بان»، یکی از نویسه‌ها به‌عنوان «دیده‌بان» انتخاب شده و به انتهای ورودی افزوده می‌شود. با این حال، هیچ محدودیتی در مورد محل قرارگیری دیده‌بان وجود ندارد (در واقع هر نویسه‌ای می‌تواند به‌عنوان دیده‌بان انتخاب شود). هنگامی که تحلیل‌گر این نویسه را می‌خواند، علاوه بر آن بررسی مرز را نیز انجام می‌دهد. اگر موقعیت فعلی در محدوده باشد، تحلیل‌گر تطبیق را از سر می‌گیرد و با دیده‌بان مانند یک نویسهٔ عادی رفتار می‌کند. در غیر این صورت \fBYYFILL\fP را فراخوانی می‌کند (مگر این‌که غیرفعال شده باشد). اگر ورودی بیشتری ارائه شود، تحلیل‌گر آخرین نویسه را مجدداً تطبیق داده و چنان ادامه می‌دهد که گویی دیده‌بان در آنجا نبوده است. در غیر این صورت، این باید پایان واقعی ورودی باشد و تحلیل‌گر متوقف می‌شود. از این روش زمانی استفاده می‌شود که \fBre2c:eof\fP مقداری نامنفی داشته باشد (باید روی مقدار عددی دیده‌بان تنظیم شود). استفاده از \fBYYFILL\fP اختیاری است. .nf .fi .sp .IP \(bu 2 \fBبررسی مرزها با پدگذاری (Bounds checks with padding).\fP این روش عمومی است و ممکن است از روش «دیده‌بان با بررسی مرزها» سریع‌تر باشد، اما پیچیده‌تر نیز هست. ایدهٔ کار این است که وضعیت‌های DFA به مؤلفه‌های قویاً همبند (SCCها) افراز شوند و برای هر SCC یک بررسی منفرد برای تعداد نویسهٔ کافی تولید شود تا طولانی‌ترین مسیر بدون حلقه در این SCC را پوشش دهد. این کار تعداد بررسی‌ها را کاهش می‌دهد، اما مشکلی در رابطه با واژک‌های کوتاه در انتهای ورودی ایجاد می‌کند، زیرا بررسی نیازمند نویسه‌های کافی برای پوشش دادن طولانی‌ترین واژک است. این مشکل می‌تواند با پدگذاری ورودی با چند نویسهٔ ساختگی که پسوند واژک معتبری را تشکیل نمی‌دهند (به‌طوری که تحلیل‌گر نتواند آن‌ها را مطابقت دهد) برطرف شود. طول پدگذاری باید \fBYYMAXFILL\fP باشد که با یک بلوک \fBmax\fP تولید می‌شود. اگر ورودی کافی نباشد، تحلیل‌گر \fBYYFILL\fP را فراخوانی می‌کند که باید حداقل تعداد نویسهٔ مورد نیاز را تأمین کند یا بازگشتی نداشته باشد. این روش در صورتی استفاده می‌شود که \fBYYFILL\fP فعال باشد و \fBre2c:eof\fP مقدار \fB\-1\fP داشته باشد (این پیکربندی پیش‌فرض است). .nf .fi .sp .IP \(bu 2 \fBبررسی‌های سفارشی (Custom checks).\fP رابط Generic API امکان بازتعریف (override) عملیات پایه‌ای مانند خواندن یک نویسه را فراهم می‌کند، که این امر گنجاندن بررسی‌های پایان ورودی را به‌عنوان بخشی از آن‌ها ممکن می‌سازد. این رویکرد مستعد خطا است و باید با احتیاط استفاده شود. برای استفاده از روش سفارشی، Generic 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 //go:generate re2go $INPUT \-o $OUTPUT \-\-api simple package main // Expect a null\-terminated string. func lex(yyinput string) int { yycursor := 0 count := 0 for { /*!re2c re2c:yyfill:enable = 0; re2c:YYCTYPE = byte; * { return \-1 } [\ex00] { return count } [a\-z]+ { count += 1; continue } [ ]+ { continue } */ } } func main() { assert_eq := func(x, y int) { if x != y { panic(\(dqerror\(dq) } } assert_eq(lex(\(dq\e000\(dq), 0) assert_eq(lex(\(dqone two three\e000\(dq), 3) assert_eq(lex(\(dqf0ur\e000\(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 را مدیریت می‌کند محدود است. بررسی‌های مرز در generic 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 //go:generate re2go $INPUT \-o $OUTPUT \-\-api simple package main // Expects a null\-terminated string. func lex(yyinput string) int { var yycursor, yymarker int yylimit := len(yyinput) \- 1 // lim points at the terminating null count := 0 for { /*!re2c re2c:YYCTYPE = byte; re2c:yyfill:enable = 0; re2c:eof = 0; str = [\(aq] ([^\(aq\e\e] | [\e\e][^])* [\(aq]; * { return \-1 } $ { return count } str { count += 1; continue } [ ]+ { continue } */ } } func main() { assert_eq := func(x, y int) { if x != y { panic(\(dqerror\(dq) } } assert_eq(lex(\(dq\e000\(dq), 0) assert_eq(lex(\(dq\(aqqu\e000tes\(aq \(aqare\(aq \(aqfine: \e\e\(aq\(aq \e000\(dq), 3) assert_eq(lex(\(dq\(aqunterminated\e\e\(aq\e000\(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 در ابتدای لایه‌گذاری است یا خیر، در غیر این صورت یک خطای نحوی است). بررسی‌های محدوده تنها در وضعیت‌هایی تولید می‌شوند که توسط مؤلفه‌های قویاً همبندِ اتوماتون زیربنایی تعیین شده باشند. بررسی‌ها با رابط عمومی (generic API) به صورت \fB(YYLIMIT \- YYCURSOR) < n\fP یا \fBYYLESSTHAN(n)\fP هستند، که در آن \fBn\fP حداقل تعداد نویسه‌های مورد نیاز برای پیشروی تحلیل‌گر واژگانی است (این همچنین بدان معناست که بررسی محدودهٔ بعدی حداکثر تا \fBn\fP نویسهٔ دیگر رخ خواهد داد). اگر شرط بررسی برقرار باشد، تحلیل‌گر واژگانی به پایان ورودی رسیده است و \fBYYFILL(n)\fP را فراخوانی می‌کند که باید یا حداقل \fBn\fP نویسه ورودی را فراهم کند یا بازگشتی نداشته باشد. در این مثال \fBYYFILL\fP همواره با شکست مواجه می‌شود و تحلیل‌گر واژگانی را با یک خطا پایان می‌دهد (که مشکلی نیست زیرا کل ورودی در یک بافر جا می‌شود). برای مثالی که بافر ورودی را با \fBYYFILL\fP دوباره پر می‌کند، بخش \fI\%YYFILL with padding\fP را ببینید\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C //go:generate re2go $INPUT \-o $OUTPUT \-\-api simple package main import \(dqstrings\(dq /*!max:re2c*/ // Expects YYMAXFILL\-padded string. func lex(str string) int { // Pad string with YYMAXFILL zeroes at the end. yyinput := str + strings.Repeat(\(dq\e000\(dq, int(YYMAXFILL)) yycursor := 0 yylimit := len(yyinput) count := 0 for { /*!re2c re2c:YYCTYPE = byte; 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 == len(str) { return count } else { return \-1 } } str { count += 1; continue } [ ]+ { continue } * { return \-1 } */ } } func main() { assert_eq := func(x, y int) { if x != y { panic(\(dqerror\(dq) } } assert_eq(lex(\(dq\(dq), 0) assert_eq(lex(\(dq\(aqqu\e000tes\(aq \(aqare\(aq \(aqfine: \e\e\(aq\(aq \(dq), 3) assert_eq(lex(\(dq\(aqunterminated\e\e\(aq\(dq), \-1) assert_eq(lex(\(dq\(aqunexpected \e000 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 //go:generate re2go $INPUT \-o $OUTPUT package main // Returns \(dqfake\(dq terminating null if cursor has reached limit. func peek(str string, cur int) byte { if cur >= len(str) { return 0 // fake null } else { return str[cur] } } // Expects a string without terminating null. func lex(str string) int { var cur int count := 0 for { /*!re2c re2c:yyfill:enable = 0; re2c:YYCTYPE = byte; re2c:YYPEEK = \(dqpeek(str, cur)\(dq; re2c:YYSKIP = \(dqcur += 1\(dq; * { return \-1 } [\ex00] { return count } [a\-z]+ { count += 1; continue } [ ]+ { continue } */ } } func main() { assert_eq := func(x, y int) { if x != y { panic(\(dqerror\(dq) } } assert_eq(lex(\(dq\(dq), 0) assert_eq(lex(\(dqone two three\(dq), 3) assert_eq(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 مربوط به re2go ضمنی است، چرا که برای عملکرد عادی لکسر نیازی به آن نیست و می‌تواند توسط کاربر تعریف و به‌روزرسانی شود) .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) با فاصله‌گذاری (padding) است. همچنین توجه داشته باشید که اگر گزینهٔ \fB\-f \-\-storable\-state\fP به کار رود، \fBYYFILL\fP دارای معناشناسی متفاوتی خواهد بود (که در بخش وضعیت قابل ذخیره‌سازی توضیح داده شده است). .SS "YYFILL با نشانگر پایان (YYFILL with sentinel)" .sp اگر از قاعدهٔ EOF استفاده شود، \fBYYFILL\fP یک دستور اولیهٔ تابع‌مانند است که هیچ آرگومانی نمی‌پذیرد و مقداری بازمی‌گرداند که در مقایسه با صفر بررسی می‌شود. فراخوانی \fBYYFILL\fP با شرط \fBYYLIMIT <= YYCURSOR\fP در API اشاره‌گر C و \fBYYLESSTHAN()\fP در 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 //go:generate re2go $INPUT \-o $OUTPUT package main import ( \(dqos\(dq \(dqstrings\(dq ) const BUFSIZE uint = 4096 type Input struct { file *os.File yyinput []byte yycursor uint yymarker uint yylimit uint token uint eof bool } func fill(in *Input) int { if in.eof { return \-1 } // unexpected EOF // Error: lexeme too long. In real life can reallocate a larger buffer. if in.token < 1 { return \-2 } // Shift buffer contents (discard everything up to the current token). copy(in.yyinput[0:], in.yyinput[in.token:in.yylimit]) in.yycursor \-= in.token in.yymarker \-= in.token in.yylimit \-= in.token in.token = 0 // Fill free space at the end of buffer with new data from file. n, _ := in.file.Read(in.yyinput[in.yylimit:BUFSIZE]) in.yylimit += uint(n) in.yyinput[in.yylimit] = 0 // If read less than expected, this is the end of input. in.eof = in.yylimit < BUFSIZE return 0 } func lex(yyrecord *Input) int { count := 0 for { yyrecord.token = yyrecord.yycursor /*!re2c re2c:api = record; re2c:eof = 0; re2c:YYCTYPE = byte; re2c:YYFILL = \(dqfill(yyrecord) == 0\(dq; str = [\(aq] ([^\(aq\e\e] | [\e\e][^])* [\(aq]; * { return \-1 } $ { return count } str { count += 1; continue } [ ]+ { continue } */ } } func main() () { fname := \(dqinput\(dq content := \(dq\(aqqu\e000tes\(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. f, _ := os.Create(fname) f.WriteString(strings.Repeat(content, int(BUFSIZE))) f.Seek(0, 0) count := 3 * int(BUFSIZE) // number of quoted strings written to file // Prepare lexer state: all offsets are at the end of buffer. in := &Input{ file: f, // Sentinel at \(gayylimit\(ga offset is set to zero, which triggers YYFILL. yyinput: make([]byte, BUFSIZE+1), yycursor: BUFSIZE, yymarker: BUFSIZE, yylimit: BUFSIZE, token: BUFSIZE, eof: false, } // Run the lexer. if lex(in) != count { panic(\(dqerror\(dq); } // Cleanup: remove input file. f.Close(); os.Remove(fname); } .ft P .fi .UNINDENT .UNINDENT.SS YYFILL با پدینگ (padding) .sp در حالت پیش‌فرض (زمانی که از قاعده EOF استفاده نمی‌شود)، \fBYYFILL\fP یک دستور اولیه شبه‌تابع است که یک آرگومان می‌پذیرد و هیچ مقداری برنمی‌گرداند. فراخوانی \fBYYFILL\fP با شرط \fB(YYLIMIT \- YYCURSOR) < n\fP در API اشاره‌گر C و \fBYYLESSTHAN(n)\fP در API عمومی (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 //go:generate re2go $INPUT \-o $OUTPUT package main import ( \(dqos\(dq \(dqstrings\(dq ) /*!max:re2c*/ const BUFSIZE uint = 4096 type Input struct { file *os.File yyinput []byte yycursor uint yylimit uint token uint eof bool } func fill(in *Input, need uint) int { if in.eof { return \-1 } // unexpected EOF // Error: lexeme too long. In real life can reallocate a larger buffer. if in.token < need { return \-2 } // Shift buffer contents (discard everything up to the current token). copy(in.yyinput[0:], in.yyinput[in.token:in.yylimit]) in.yycursor \-= in.token in.yylimit \-= in.token in.token = 0 // Fill free space at the end of buffer with new data from file. n, _ := in.file.Read(in.yyinput[in.yylimit:BUFSIZE]) in.yylimit += uint(n) // If read less than expected, this is end of input => add zero padding // so that the lexer can access characters at the end of buffer. if in.yylimit < BUFSIZE { in.eof = true for i := uint(0); i < YYMAXFILL; i += 1 { in.yyinput[in.yylimit+i] = 0 } in.yylimit += YYMAXFILL } return 0 } func lex(yyrecord *Input) int { count := 0 for { yyrecord.token = yyrecord.yycursor /*!re2c re2c:api = record; re2c:YYCTYPE = byte; re2c:YYFILL = \(dqif r := fill(yyrecord, @@); r != 0 { return r }\(dq; str = [\(aq] ([^\(aq\e\e] | [\e\e][^])* [\(aq]; [\ex00] { // Check that it is the sentinel, not some unexpected null. if yyrecord.token == yyrecord.yylimit \- YYMAXFILL { return count } else { return \-1 } } str { count += 1; continue } [ ]+ { continue } * { return \-1 } */ } } func main() () { fname := \(dqinput\(dq content := \(dq\(aqqu\e000tes\(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. f, _ := os.Create(fname) f.WriteString(strings.Repeat(content, int(BUFSIZE))) f.Seek(0, 0) count := 3 * int(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. in := &Input{ file: f, yyinput: make([]byte, BUFSIZE+YYMAXFILL), yycursor: BUFSIZE, yylimit: BUFSIZE, token: BUFSIZE, eof: false, } // Run the lexer. if lex(in) != count { panic(\(dqerror\(dq); } // Cleanup: remove input file. f.Close(); os.Remove(fname); } .ft P .fi .UNINDENT .UNINDENT.SH "ویژگی‌ها (FEATURES)" .SS "بلوک‌های چندگانه (Multiple blocks)" .sp گاهی اوقات لازم است چندین تحلیل‌گر لغوی (lexer) مرتبط با یکدیگر داشته باشیم (برای مثال، زمانی که یک ماشین حالت سطح‌بالا وجود دارد که بین حالت‌های تحلیل‌گر لغوی جابه‌جا می‌شود). این ساختار را می‌توان با استفاده از چندین بلوک متصل re2go پیاده‌سازی کرد. گزینه دیگر، استفاده از \fI\%start conditions\fP\& است. .sp پیاده‌سازی ارتباط بین بلوک‌ها به زبان مقصد بستگی دارد. در زبان‌هایی که دستور \fBgoto\fP دارند (مانند C/C++ و Go)، می‌توان تمام بلوک‌ها را در یک تابع قرار داد، به‌گونه‌ای که پیش از هر کدام یک برچسب بیاید. انتقال از یک بلوک به بلوک دیگر، یک \fBgoto\fP ساده است. در زبان‌هایی که فاقد \fBgoto\fP هستند (مانند Rust)، استفاده از یک حلقه همراه با switch روی متغیر حالت ضروری است؛ مشابه حلقه/switch مربوط به \fByystate\fP که توسط re2go تولید می‌شود، یا در غیر این صورت، قرار دادن هر بلوک درون یک تابع و استفاده از فراخوانی توابع. .sp مثال زیر از چندین بلوک برای تجزیه اعداد دودویی (binary)، هشت‌هشتی (octal)، ده‌دهی (decimal) و شانزده‌شانزدهی (hexadecimal) استفاده می‌کند. هر مبنا بلوک اختصاصی خود را دارد. بلوک اولیه مبنا را تشخیص داده و پردازش را به بلوک‌های دیگر هدایت می‌کند. پیکربندی‌های مشترک در یک بلوک جداگانه در ابتدای برنامه تعریف شده‌اند؛ این پیکربندی‌ها توسط سایر بلوک‌ها به ارث برده می‌شوند. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C //go:generate re2go $INPUT \-o $OUTPUT \-i \-\-api simple package main import \(dqerrors\(dq const u32Limit uint64 = 1<<32 var ( eSyntax = errors.New(\(dqsyntax error\(dq) eOverflow = errors.New(\(dqoverflow error\(dq) ) func parse_u32(yyinput string) (uint32, error) { var yycursor, yymarker int result := uint64(0) add := func(base uint64, offset byte) { result = result * base + uint64(yyinput[yycursor\-1] \- offset) if result >= u32Limit { result = u32Limit } } /*!re2c re2c:yyfill:enable = 0; re2c:YYCTYPE = byte; end = \(dq\ex00\(dq; \(aq0b\(aq / [01] { goto bin } \(dq0\(dq { goto oct } \(dq\(dq / [1\-9] { goto dec } \(aq0x\(aq / [0\-9a\-fA\-F] { goto hex } * { goto err } */ bin: /*!re2c end { goto end } [01] { add(2, \(aq0\(aq); goto bin } * { goto err } */ oct: /*!re2c end { goto end } [0\-7] { add(8, \(aq0\(aq); goto oct } * { goto err } */ dec: /*!re2c end { goto end } [0\-9] { add(10, \(aq0\(aq); goto dec } * { goto err } */ hex: /*!re2c end { goto end } [0\-9] { add(16, \(aq0\(aq); goto hex } [a\-f] { add(16, \(aqa\(aq\-10); goto hex } [A\-F] { add(16, \(aqA\(aq\-10); goto hex } * { goto err } */ end: if result < u32Limit { return uint32(result), nil } else { return 0, eOverflow } err: return 0, eSyntax } func main() { test := func(num uint32, str string, err error) { if n, e := parse_u32(str); !(n == num && e == err) { panic(\(dqerror\(dq) } } test(1234567890, \(dq1234567890\e000\(dq, nil) test(13, \(dq0b1101\e000\(dq, nil) test(0x7fe, \(dq0x007Fe\e000\(dq, nil) test(0644, \(dq0644\e000\(dq, nil) test(0, \(dq9999999999\e000\(dq, eOverflow) test(0, \(dq123??\e000\(dq, eSyntax) } .ft P .fi .UNINDENT .UNINDENT.SS شرایط شروع (Start conditions) .sp شرایط شروع با گزینهٔ \fB\-\-start\-conditions\fP فعال می‌شوند. این سازوکار راهکاری برای کدگذاری چندین خودکارهٔ (automata) مرتبط با یکدیگر درون یک بلوک re2go ارائه می‌دهد. .sp هر شرط متناظر با یک خودکارهٔ واحد است و دارای یک نام منحصربه‌فردِ تعیین‌شده توسط کاربر و یک شمارهٔ داخلی یکتا تعریف‌شده توسط re2go\& می‌باشد. این شماره‌ها برای جابه‌جایی میان شرایط استفاده می‌شوند: کد تولیدشده از توابع اولیهٔ \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 کدی که re2go برای شرایط تولید می‌کند بستگی به این دارد که re2go از رویکرد goto/label یا رویکرد loop/switch برای کدگذاری خودکاره‌ها استفاده کند. .sp در زبان‌هایی که دارای دستور \fBgoto\fP هستند (مانند C/C++ و Go)، شرایط به‌طور طبیعی به‌صورت بلوک‌هایی از کد با پیشوند برچسب‌هایی به شکل \fByyc_\fP پیاده‌سازی می‌شوند، که در آن \fBcond\fP نام یک شرط است (پیشوند برچسب را می‌توان با \fBre2c:cond:prefix\fP تغییر داد). گذارها میان شرایط با استفاده از \fBgoto\fP و برچسب‌های شرایط پیاده‌سازی می‌شوند. پیش از همهٔ شرایط، re2go یک switch اولیه روی \fBYYGETSTATE\fP تولید می‌کند که به وضعیت شروعِ شرطِ کنونی می‌پرد. قواعد میان‌بُر \fB:=>\fP این switch اولیه را دور می‌زنند و مستقیماً به شرط مشخص‌شده می‌پرند (می‌توان از \fBre2c:cond:goto\fP برای تغییر رفتار پیش‌فرض استفاده کرد). قواعد دارای کنش‌های معنایی به‌طور خودکار به شرط بعدی نمی‌پرند؛ این کار باید توسط کد کنشِ تعریف‌شده توسط کاربر انجام گیرد. .sp در زبان‌هایی که فاقد \fBgoto\fP هستند (مانند Rust)، re2go از متغیر \fByystate\fP برای ذخیرهٔ شمارهٔ شرایط استفادهٔ مجدد می‌کند. هر شرط یک شناسهٔ عددی برابر با شمارهٔ وضعیت آغازین خود دریافت می‌کند، و یک switch میان شرایط، هیچ تفاوتی با یک switch میان وضعیت‌های DFA درون یک شرط منفرد ندارد. نیازی به یک switch اولیهٔ مجزا برای شرایط نیست. (از آنجا که همین رویکرد برای پیاده‌سازی وضعیت‌های ذخیره‌پذیر استفاده می‌شود، در صورتی که هم از وضعیت‌های ذخیره‌پذیر و هم از شرایط استفاده شود، \fBYYGETCOND\fP/\fBYYSETCOND\fP زائد خواهند بود). .sp برنامهٔ زیر از شرایط شروع برای تجزیهٔ اعداد دودویی، هشت‌هشتی، ده‌دهی و شانزده‌شانزدهی استفاده می‌کند. یک بلوک واحد وجود دارد که در آن هر مبنا شرط مخصوص به خود را دارد، و شرط آغازین به همهٔ آن‌ها متصل است. متغیر تعریف‌شده توسط کاربر \fBcond\fP شمارهٔ شرط کنونی را ذخیره می‌کند؛ این متغیر با شمارهٔ شرط اولیه‌ای که با بلوک \fBconditions\fP تولید شده است مقداردهی اولیه می‌شود. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C //go:generate re2go \-c $INPUT \-o $OUTPUT \-i \-\-api simple package main import \(dqerrors\(dq var ( eSyntax = errors.New(\(dqsyntax error\(dq) eOverflow = errors.New(\(dqoverflow error\(dq) ) /*!conditions:re2c*/ const u32Limit uint64 = 1<<32 func parse_u32(yyinput string) (uint32, error) { var yycursor, yymarker int result := uint64(0) yycond := yycinit add := func(base uint64, offset byte) { result = result * base + uint64(yyinput[yycursor\-1] \- offset) if result >= u32Limit { result = u32Limit } } /*!re2c re2c:yyfill:enable = 0; re2c:YYCTYPE = byte; re2c:YYGETCOND = \(dqcond\(dq; re2c:YYSETCOND = \(dqcond = @@\(dq; <*> * { return 0, eSyntax } \(aq0b\(aq / [01] :=> bin \(dq0\(dq :=> oct \(dq\(dq / [1\-9] :=> dec \(aq0x\(aq / [0\-9a\-fA\-F] :=> hex \(dq\ex00\(dq { if result < u32Limit { return uint32(result), nil } else { return 0, eOverflow } } [01] { add(2, \(aq0\(aq); goto yyc_bin } [0\-7] { add(8, \(aq0\(aq); goto yyc_oct } [0\-9] { add(10, \(aq0\(aq); goto yyc_dec } [0\-9] { add(16, \(aq0\(aq); goto yyc_hex } [a\-f] { add(16, \(aqa\(aq\-10); goto yyc_hex } [A\-F] { add(16, \(aqA\(aq\-10); goto yyc_hex } */ } func main() { test := func(num uint32, str string, err error) { if n, e := parse_u32(str); !(n == num && e == err) { panic(\(dqerror\(dq) } } test(1234567890, \(dq1234567890\e000\(dq, nil) test(13, \(dq0b1101\e000\(dq, nil) test(0x7fe, \(dq0x007Fe\e000\(dq, nil) test(0644, \(dq0644\e000\(dq, nil) test(0, \(dq9999999999\e000\(dq, eOverflow) test(0, \(dq123??\e000\(dq, eSyntax) } .ft P .fi .UNINDENT .UNINDENT.SS وضعیت قابل ذخیره‌سازی (Storable state) .sp با گزینهٔ \fB\-\-storable\-state\fP، ابزار re2go یک تحلیل‌گر لغوی تولید می‌کند که می‌تواند وضعیت فعلی خود را ذخیره کرده، به فراخواننده بازگردد، و بعداً عملیات را دقیقاً از همان‌جایی که رها کرده بود از سر بگیرد. حالت پیش‌فرض عملکرد در re2go مدل «کشش» (\(dqpull\(dq) است که در آن تحلیل‌گر لغوی هر زمان که نیاز داشته باشد، ورودی بیشتری را «می‌کشد» (\(dqpulls\(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 برای تولید ساختار سوییچ \fBYYGETSTATE\fP به‌صورت جدا از تحلیل‌گر لغوی اصلی. این ویژگی تنها برای زبان‌هایی کار می‌کند که دارای \fBgoto\fP هستند (نه در حالت \fB\-\-loop\-switch\fP). .IP \(bu 2 استفاده از \fBre2c:eof\fP و روش \fI\%sentinel with bounds checks\fP برای مدیریت انتهای ورودی. روش مبتنی بر لایه‌گذاری (padding) ممکن است کار نکند زیرا مشخص نیست چه زمانی باید لایه‌گذاری را اضافه کرد: انتهای فعلی ورودی ممکن است انتهای نهایی ورودی نباشد، و اضافه کردن زودهنگام لایه‌گذاری ممکن است یک لکسم طمع‌کارانه (greedy lexeme) را که بخشی از آن خوانده شده قطع کند. علاوه بر این، به دلیل منطق سطح‌بالای برنامه، دریافت ورودی بیشتر ممکن است به پردازش لکسم در انتهای بافر وابسته باشد (که از قبل به دلیل شرط پایان ورودی مسدود شده است). .UNINDENT .sp در اینجا مثالی از یک تحلیل‌گر لغوی با مدل «رانش» (\(dqpush\(dq) آورده شده است که خواندن بسته‌ها از یک سوکت را شبیه‌سازی می‌کند. تحلیل‌گر لغوی تا زمانی که با انتهای ورودی مواجه شود حلقه می‌زند و به تابع فراخواننده بازمی‌گردد. تابع فراخواننده با «ارسال» (\(dqsending\(dq) بستهٔ بعدی، ورودی بیشتری فراهم کرده و تحلیل لغوی را از سر می‌گیرد. این فرآیند زمانی که تمام بسته‌ها ارسال شده باشند، یا زمانی که خطایی رخ دهد، متوقف می‌شود. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C //go:generate re2go \-f $INPUT \-o $OUTPUT package main import ( \(dqfmt\(dq \(dqos\(dq ) // Use a small buffer to cover the case when a lexeme doesn\(aqt fit. // In real world use a larger buffer. const BUFSIZE int = 10 type State struct { file *os.File yyinput []byte yycursor int yymarker int yylimit int token int yystate int } const ( lexEnd = iota lexReady lexWaitingForInput lexPacketBroken lexPacketTooBig ) func fill(st *State) int { 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 lexPacketTooBig } // Shift buffer contents (discard already processed data). copy(st.yyinput[0:], 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. n, _ := st.file.Read(st.yyinput[st.yylimit:BUFSIZE]) st.yylimit += n st.yyinput[st.yylimit] = 0 // append sentinel symbol return lexReady } func lex(yyrecord *State, recv *int) int { var yych byte /*!getstate:re2c*/ loop: yyrecord.token = yyrecord.yycursor /*!re2c re2c:api = record; re2c:eof = 0; re2c:YYFILL = \(dqreturn lexWaitingForInput\(dq; packet = [a\-z]+[;]; * { return lexPacketBroken } $ { return lexEnd } packet { *recv = *recv + 1; goto loop } */ } func test(expect int, packets []string) { // Create a pipe (open the same file for reading and writing). fname := \(dqpipe\(dq fw, _ := os.Create(fname) fr, _ := os.Open(fname) // Initialize lexer state: \(gastate\(ga value is \-1, all offsets are at the end // of buffer. st := &State{ file: fr, // Sentinel at \(gayylimit\(ga offset is set to zero, which triggers YYFILL. yyinput: make([]byte, 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. var status int send := 0 recv := 0 for { status = lex(st, &recv) if status == lexEnd { break } else if status == lexWaitingForInput { if send < len(packets) { fw.WriteString(packets[send]) send += 1 } status = fill(st) if status != lexReady { break } } else if status == lexPacketBroken { break } } // Check results. if status != expect || (status == lexEnd && recv != send) { panic(fmt.Sprintf(\(dqgot %d, want %d\(dq, status, expect)) } // Cleanup: remove input file. fr.Close() fw.Close() os.Remove(fname) } func main() { test(lexEnd, []string{}) test(lexEnd, []string{\(dqzero;\(dq, \(dqone;\(dq, \(dqtwo;\(dq, \(dqthree;\(dq, \(dqfour;\(dq}) test(lexPacketBroken, []string{\(dq??;\(dq}) test(lexPacketTooBig, []string{\(dqlooooooooooooong;\(dq}) } .ft P .fi .UNINDENT .UNINDENT.SS بلوک‌های قابل استفاده مجدد (Reusable blocks) .sp بلوک‌های قابل استفاده مجدد در قالب \fB/*!rules:re2c[:] ... */\fP یا \fB%{rules[:] ... %}\fP می‌توانند به هر تعداد بار دوباره استفاده شده و با دیگر بلوک‌های re2go ترکیب شوند. مقدار \fB\fP اختیاری است. یک بلوک rules می‌تواند در یک بلوک یا رهنمود \fBuse\fP به کار رود. کد مربوط به یک بلوک rules در هر نقطه‌ای از استفاده تولید می‌شود. .sp بلوک‌های use با \fB/*!use:re2c[:] ... */\fP یا \fB%{use[:] ... %}\fP\& تعریف می‌شوند. شناسهٔ \fB\fP اختیاری است: در صورتی که مشخص نشود، بلوک rules مرتبط، جدیدترین بلوک موجود خواهد بود (چه نام‌دار باشد و چه بی‌نام). یک بلوک use می‌تواند تعاریف نام‌دار، پیکربندی‌ها و قواعد مختص به خود را اضافه کند. یک کاربرد مهم برای بلوک‌های use، تحلیل‌گر لغوی (lexer) با پشتیبانی از چندین کدگذاری ورودی است: همان بلوک rules چندین بار با پیکربندی‌های خاص هر کدگذاری بازاستفاده می‌شود (مثال زیر را ببینید). .sp رهنمود use درون‌بلوکی \fB!use:;\fP می‌تواند از داخل یک بلوک re2go استفاده شود. این رهنمود بلوک ارجاع‌یافتهٔ \fB\fP را با بلوک فعلی ادغام می‌کند. اگر برخی از قواعد و پیکربندی‌های ادغام‌شده با موارد تعریف‌شدهٔ پیشین هم‌پوشانی داشته باشند، تداخل‌ها به شیوهٔ معمول حل‌وفصل می‌شوند: نخستین قاعده اولویت دارد، و آخرین پیکربندی بر موارد پیش از خود جایگزین می‌شود. یک استثنا، قواعد ویژهٔ \fB*\fP، \fB$\fP و (در حالت شرط/condition) \fB\fP هستند که برای آن‌ها تعریف محلیِ بلوک بر هر تعریف به ارث‌رسیده‌ای ارجحیت دارد. رهنمود use به کاربر اجازه می‌دهد بلوک‌های گوناگون re2go را با یکدیگر در یک بلوک ترکیب کند (مثال زیر را ببینید). .sp بلوک‌های نام‌دار و رهنمود use درون‌بلوکی در نسخهٔ 2.2 از re2go افزوده شدند. از آن نسخه به بعد، بلوک‌های قابل استفاده مجدد به‌طور پیش‌فرض مجاز هستند (نیازی به گزینهٔ خاصی نیست). پیش از نسخهٔ 2.2، حالت استفادهٔ مجدد با گزینهٔ \fB\-r \-\-reusable\fP فعال می‌شد. پیش از نسخهٔ 1.2، بلوک‌های قابل استفاده مجدد نمی‌توانستند با بلوک‌های معمولی ترکیب شوند. .SS مثالی از رهنمود \fB!use\fP .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C //go:generate re2go $INPUT \-o $OUTPUT \-\-api simple package main // 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. const ( Color = iota 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 } */ func lex(yyinput string) int { var yycursor, yymarker int /*!re2c re2c:yyfill:enable = 0; re2c:YYCTYPE = byte; !use:fish; !use:colors; * { return Dunno } // overrides inherited \(aq*\(aq rules */ } func main() { assert_eq := func(x, y int) { if x != y { panic(\(dqerror\(dq) } } assert_eq(lex(\(dqsalmon\(dq), Fish); assert_eq(lex(\(dqwhat?\(dq), Dunno); } .ft P .fi .UNINDENT .UNINDENT.SS مثالی از یک بلوک \fB/*!use:re2c ... */\fP .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C //go:generate re2go $INPUT \-o $OUTPUT \-\-input\-encoding utf8 \-\-api simple package main // 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; } */ func lexUTF8(yyinput []uint8) int { var yycursor, yymarker int /*!use:re2c re2c:encoding:utf8 = 1; re2c:YYCTYPE = uint8; */ } func lexUTF32(yyinput []uint32) int { var yycursor, yymarker int /*!use:re2c re2c:encoding:utf32 = 1; re2c:YYCTYPE = uint32; */ } func main() { assert_eq := func(x, y int) { if x != y { panic(\(dqerror\(dq) } } assert_eq(lexUTF8([]uint8{0xe2, 0x88, 0x80, 0x78, 0x20, 0xe2, 0x88, 0x83, 0x79}), 0) assert_eq(lexUTF32([]uint32{0x2200, 0x78, 0x20, 0x2203, 0x79}), 0) } .ft P .fi .UNINDENT .UNINDENT .SS استخراج زیرتطبیق (Submatch extraction) .sp ابزار re2go دو گزینه برای استخراج زیرتطبیق دارد. .INDENT 0.0 .TP .B \fBTags\fP گزینهٔ نخست استفاده از \fItag\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، ابزار re2go متغیرهای \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 ترجمه می‌شوند. ایدهٔ اصلی TDFA به حداقل رساندن بار اضافی (overhead) در استخراج زیرتطبیق است. در حالت حدی، اگر هیچ برچسب یا گیراندازی‌ای در یک عبارت منظم وجود نداشته باشد، TDFA تنها یک DFA معمولی است. اگر تعداد برچسب‌ها معتدل باشد، بار اضافی به سختی قابل توجه خواهد بود. ماشین TDFA تولیدشده از تعدادی \fIمتغیر برچسب (tag variables)\fP استفاده می‌کند که مستقیماً به برچسب‌ها نگاشت نمی‌شوند: یک متغیر منفرد ممکن است برای برچسب‌های متفاوتی استفاده شود، و یک برچسب ممکن است برای نگهداری تمام مقادیر احتمالی خود به چندین متغیر نیاز داشته باشد. سرانجام ابهام حل می‌شود، و تنها یک متغیر نهایی به ازای هر برچسب باقی می‌ماند. متغیرهای برچسب باید با استفاده از بلوک‌های \fBstags\fP یا \fBmtags\fP تعریف شوند. اگر وضعیت لکسر ذخیره می‌شود، متغیرهای برچسب باید بخشی از آن باشند. آن‌ها همچنین باید توسط \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ها برای تجزیهٔ نگارش‌های معنایی (semantic versions) متشکل از سه مؤلفهٔ عددی آمده است: major، minor، patch (مورد آخر اختیاری است). برای یک مثال پیچیده‌تر که از \fBYYFILL\fP استفاده می‌کند به بخش‌های زیر مراجعه کنید. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C //go:generate re2go $INPUT \-o $OUTPUT \-\-api simple package main import \(dqreflect\(dq type SemVer struct { major, minor, patch int } func s2n(s string) int { // convert pre\-parsed string to a number n := 0 for _, c := range s { n = n*10 + int(c\-\(aq0\(aq) } return n } func parse(yyinput string) *SemVer { var yycursor, yymarker int // Final tag variables available in semantic action. /*!svars:re2c format = \(aqvar @@ int;\(aq; */ // Intermediate tag variables used by the lexer (must be autogenerated). /*!stags:re2c format = \(aqvar @@ int;\(aq; */ /*!re2c re2c:yyfill:enable = 0; re2c:YYCTYPE = byte; re2c:tags = 1; num = [0\-9]+; @t1 num @t2 \(dq.\(dq @t3 num @t4 (\(dq.\(dq @t5 num)? [\ex00] { major := s2n(yyinput[t1:t2]) minor := s2n(yyinput[t3:t4]) patch := 0 if t5 != \-1 { patch = s2n(yyinput[t5:yycursor\-1]) } return &SemVer{major, minor, patch} } * { return nil } */ } func main() { assert_eq := func(x, y *SemVer) { if !reflect.DeepEqual(x, y) { panic(\(dqerror\(dq) } } assert_eq(parse(\(dq23.34\e000\(dq), &SemVer{23, 34, 0}) assert_eq(parse(\(dq1.2.9999\e000\(dq), &SemVer{1, 2, 9999}) assert_eq(parse(\(dq1.a\e000\(dq), nil) } .ft P .fi .UNINDENT .UNINDENT.sp در اینجا نمونه پیچیده‌تری از استفاده از s\-tagها به همراه \fBYYFILL\fP برای تجزیه فایلی با نسخه‌بندی‌های معناییِ جداشده با خط جدید آورده شده است. متغیرهای برچسب بخشی از وضعیت تحلیل‌گر لغوی (lexer) هستند و مانند سایر موقعیت‌های ورودی در \fBYYFILL\fP تنظیم می‌شوند. توجه داشته باشید که این امر برای s\-tagها ضروری است زیرا مقادیر آن‌ها پس از جابه‌جایی محتویات بافر باطل می‌شوند. این کار ممکن است در پیاده‌سازی‌های سفارشی که در آن‌ها متغیرهای برچسب به‌جای بافر، آفست‌ها را نسبت به ابتدای رشته ورودی ذخیره می‌کنند لازم نباشد، که احتمالاً در مورد m\-tagها چنین است. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C //go:generate re2go $INPUT \-o $OUTPUT \-\-tags package main import ( \(dqos\(dq \(dqreflect\(dq \(dqstrings\(dq ) const BUFSIZE int = 4095 type Input struct { file *os.File yyinput []byte 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 } type SemVer struct { major, minor, patch int } func s2n(s []byte) int { // convert pre\-parsed string to a number n := 0 for _, c := range s { n = n*10 + int(c\-\(aq0\(aq) } return n } func fill(in *Input) int { if in.eof { return \-1 } // unexpected EOF // Error: lexeme too long. In real life can reallocate a larger buffer. if in.token < 1 { return \-2 } // Shift buffer contents (discard everything up to the current token). copy(in.yyinput[0:], in.yyinput[in.token:in.yylimit]) in.yycursor \-= in.token in.yymarker \-= in.token in.yylimit \-= in.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 in.@@ != \-1 { in.@@ \-= in.token }\en\(dq; */ in.token = 0 // Fill free space at the end of buffer with new data from file. n, _ := in.file.Read(in.yyinput[in.yylimit:BUFSIZE]) in.yylimit += n in.yyinput[in.yylimit] = 0 // If read less than expected, this is the end of input. in.eof = in.yylimit < BUFSIZE return 0 } func parse(in *Input) []SemVer { // Final tag variables available in semantic action. /*!svars:re2c format = \(dqvar @@ int;\(dq; */ vers := make([]SemVer, 0) for { in.token = in.yycursor /*!re2c re2c:api = record; re2c:eof = 0; re2c:yyrecord = in; re2c:YYCTYPE = byte; re2c:YYFILL = \(dqfill(in) == 0\(dq; num = [0\-9]+; num @t1 \(dq.\(dq @t2 num @t3 (\(dq.\(dq @t4 num)? [\en] { major := s2n(in.yyinput[in.token:t1]) minor := s2n(in.yyinput[t2:t3]) patch := 0 if t4 != \-1 { patch = s2n(in.yyinput[t4:in.yycursor\-1]) } vers = append(vers, SemVer{major, minor, patch}) continue } $ { return vers } * { return nil } */ } } func main() () { fname := \(dqinput\(dq content := \(dq1.22.333\en\(dq; expect := make([]SemVer, 0, BUFSIZE) for i := 0; i < BUFSIZE; i += 1 { expect = append(expect, SemVer{1, 22, 333}) } // Prepare input file (make sure it exceeds buffer size). f, _ := os.Create(fname) f.WriteString(strings.Repeat(content, BUFSIZE)) f.Seek(0, 0) // Initialize lexer state: all offsets are at the end of buffer. in := &Input{ file: f, // Sentinel at \(gayylimit\(ga offset is set to zero, which triggers YYFILL. yyinput: make([]byte, BUFSIZE+1), yycursor: BUFSIZE, yymarker: BUFSIZE, yylimit: BUFSIZE, token: BUFSIZE, eof: false, } // Run the lexer and check results. if !reflect.DeepEqual(parse(in), expect) { panic(\(dqerror\(dq); } // Cleanup: remove input file. f.Close(); os.Remove(fname); } .ft P .fi .UNINDENT .UNINDENT .sp در اینجا نمونه‌ای از استفاده از گروه‌های ضبط (capturing groups) برای تجزیه نسخه‌بندی‌های معنایی آورده شده است. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C //go:generate re2go $INPUT \-o $OUTPUT \-\-api simple package main import \(dqreflect\(dq type SemVer struct { major, minor, patch int } func s2n(s string) int { // convert pre\-parsed string to a number n := 0 for _, c := range s { n = n*10 + int(c\-\(aq0\(aq) } return n } func parse(yyinput string) *SemVer { var yycursor, yymarker int // Final tag variables used in semantic action. /*!svars:re2c format = \(aqvar @@ int;\(aq; */ // Intermediate tag variables used by the lexer (must be autogenerated). /*!stags:re2c format = \(aqvar @@ int;\(aq; */ /*!re2c re2c:yyfill:enable = 0; re2c:YYCTYPE = byte; re2c:captvars = 1; num = [0\-9]+; (num) \(dq.\(dq (num) (\(dq.\(dq num)? [\ex00] { _ = yytl0; _ = yytr0; // some variables are unused major := s2n(yyinput[yytl1:yytr1]) minor := s2n(yyinput[yytl2:yytr2]) patch := 0 if yytl3 != \-1 { patch = s2n(yyinput[yytl3+1:yytr3]) } return &SemVer{major, minor, patch} } * { return nil } */ } func main() { assert_eq := func(x, y *SemVer) { if !reflect.DeepEqual(x, y) { panic(\(dqerror\(dq) } } assert_eq(parse(\(dq23.34\e000\(dq), &SemVer{23, 34, 0}) assert_eq(parse(\(dq1.2.9999\e000\(dq), &SemVer{1, 2, 9999}) assert_eq(parse(\(dq1.a\e000\(dq), nil) } .ft P .fi .UNINDENT .UNINDENT.sp در اینجا مثالی از به‌کارگیری m\-tagها برای تجزیهٔ نسخه‌ای با تعداد متغیری از مؤلفه‌ها آورده شده است. متغیرهای برچسب در یک trie ذخیره می‌شوند. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C //go:generate re2go $INPUT \-o $OUTPUT \-\-api simple package main import \(dqreflect\(dq const ( mtagRoot int = \-1 tagNone int = \-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). type mtagElem struct { elem int pred int } type mtagTrie = []mtagElem type Ver = []int // unbounded number of version components func s2n(s string) int { // convert pre\-parsed string to a number n := 0 for _, c := range s { n = n*10 + int(c\-\(aq0\(aq) } return n } // Append a single value to an m\-tag history. func add_mtag(trie *mtagTrie, mtag int, value int) int { *trie = append(*trie, mtagElem{value, mtag}) return len(*trie) \- 1 } // Recursively unwind tag histories and collect version components. func unwind(trie mtagTrie, x int, y int, str string) Ver { // Reached the root of the m\-tag tree, stop recursion. if x == mtagRoot && y == mtagRoot { return []int{} } // Unwind history further. ver := unwind(trie, trie[x].pred, trie[y].pred, str) // Get tag values. Tag histories must have equal length. if x == mtagRoot || y == mtagRoot { panic(\(dqtag histories have different length\(dq) } ex := trie[x].elem ey := trie[y].elem if ex != tagNone && ey != tagNone { // Both tags are valid string indices, extract component. ver = append(ver, s2n(str[ex:ey])) } else if !(ex == tagNone && ey == tagNone) { panic(\(dqboth tags should be tagNone\(dq) } return ver } func parse(yyinput string) []int { var yycursor, yymarker int trie := make([]mtagElem, 0) // Final tag variables available in semantic action. /*!svars:re2c format = \(aqvar @@ int;\(aq; */ /*!mvars:re2c format = \(dqvar @@ int;\(dq; */ // Intermediate tag variables used by the lexer (must be autogenerated). /*!stags:re2c format = \(aqvar @@ int\(aq; separator = \(dq\en\et\(dq; */ /*!mtags:re2c format = \(dq\et@@ := mtagRoot\en\(dq; */ /*!re2c re2c:tags = 1; re2c:yyfill:enable = 0; re2c:YYCTYPE = byte; re2c:YYMTAGP = \(dq@@ = add_mtag(&trie, @@, yycursor)\(dq; re2c:YYMTAGN = \(dq@@ = add_mtag(&trie, @@, tagNone)\(dq; num = [0\-9]+; @t1 num @t2 (\(dq.\(dq #t3 num #t4)* [\ex00] { ver := make([]int, 0) ver = append(ver, s2n(yyinput[t1:t2])) ver = append(ver, unwind(trie, t3, t4, yyinput)...) return ver } * { return nil } */ } func main() { assert_eq := func(x, y []int) { if !reflect.DeepEqual(x, y) { panic(\(dqerror\(dq) } } assert_eq(parse(\(dq1\e000\(dq), []int{1}) assert_eq(parse(\(dq1.2.3.4.5.6.7\e000\(dq), []int{1, 2, 3, 4, 5, 6, 7}) assert_eq(parse(\(dq1.\e000\(dq), nil) } .ft P .fi .UNINDENT .UNINDENT.SS پشتیبانی از کدگذاری (Encoding support) .sp درک تفاوت میان \fBنقطه‌کدها (code points)\fP و \fBواحدهای کد (code units)\fP ضروری است\&. نقطه‌کد یک شناسهٔ عددی برای یک نماد است. واحد کد کوچک‌ترین واحد ذخیره‌سازی در متن کدگذاری‌شده است. یک نقطه‌کد واحد ممکن است با یک یا چند واحد کد نمایش داده شود. در یک کدگذاری با طول ثابت (fixed\-length)، همهٔ نقطه‌کدها با تعداد یکسانی از واحدهای کد نمایش داده می‌شوند. در یک کدگذاری با طول متغیر (variable\-length)، نقطه‌کدها ممکن است با تعداد متفاوتی از واحدهای کد نمایش داده شوند. توجه داشته باشید که قاعدهٔ «هر چیزی» \(dqany\(dq \fB[^]\fP با هر نقطه‌کدی مطابقت می‌یابد، اما لزوماً با هر واحد کدی مطابقت ندارد (تنها روش برای تطبیق با هر واحد کد بدون توجه به نوع کدگذاری، قاعدهٔ پیش‌فرض \fB*\fP است). تحلیل‌گر لغوی تولیدشده با جریانی از واحدهای کد کار می‌کند: \fByych\fP یک واحد کد را ذخیره می‌کند و \fBYYCTYPE\fP نوع واحد کد است. از سوی دیگر، عبارات منظم بر حسب نقطه‌کدها مشخص می‌شوند. هنگامی که re2go عبارات منظم را به اتوماتا کامپایل می‌کند، نقطه‌کدها را به واحدهای کد ترجمه می‌نماید. این عموماً یک نگاشت ساده نیست: در کدگذاری‌های با طول متغیر، یک بازه از نقطه‌کد ممکن است به گراف پیچیده‌ای از واحدهای کد ترجمه شود. کدگذاری‌های زیر پشتیبانی می‌شوند: .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 تعاریف re2go را برای بلوک‌ها، دسته‌ها و ویژگی‌های توصیف‌شده در استاندارد یونیکد (Unicode) فراهم می‌کنند. .sp گزینهٔ \fB\-\-input\-encoding\fP کدگذاری فایل مبدا را مشخص می‌کند، که می‌تواند برای فعال کردن لیترال‌های یونیکد در عبارات منظم استفاده شود. برای نمونه \fB\-\-input\-encoding utf8\fP به re2go اعلام می‌کند که فایل مبدا در قالب UTF8 است (با \fB\-\-utf8\fP که کدگذاری متن ورودی را مشخص می‌کند متفاوت است). گزینهٔ \fB\-\-encoding\-policy\fP نحوهٔ مدیریت جانشین‌های یونیکد (نقطه‌کدهای موجود در بازهٔ \fB[0xD800\-0xDFFF]\fP) را توسط re2go مشخص می‌کند. .sp در زیر یک مثال از تحلیل‌گر لغوی برای شناسه‌های یونیکد کدگذاری‌شده با UTF8 آمده است. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C //go:generate re2go $INPUT \-o $OUTPUT \-8si \-\-api simple package main /*!include:re2c \(dqunicode_categories.re\(dq */ func lex(yyinput string) int { var yycursor, yymarker int /*!re2c re2c:yyfill:enable = 0; re2c:YYCTYPE = byte; // 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 } */ } func main() { if lex(\(dq_Ыдентификатор\e000\(dq) != 0 { panic(\(dqerror\(dq) } } .ft P .fi .UNINDENT .UNINDENT.SS فایل‌های Include (Include files) .sp re2go به شما امکان می‌دهد با استفاده از بلوکی به شکل \fB/*!include:re2c FILE */\fP یا \fB%{include FILE %}\fP، یا یک دستورالعمل درون‌بلوکیِ \fB!include FILE ;\fP، فایل‌های دیگر را ضمیمه کنید که در آن \fBFILE\fP مسیر فایلی است که باید ضمیمه شود. re2go به دنبال فایل‌های include در دایرکتوریِ فایلِ فراخواننده و مکان‌های include می‌گردد که می‌توان آن‌ها را با گزینهٔ \fB\-I\fP مشخص کرد. بلوک‌ها/دستورالعمل‌های include در re2go همانند \fB#include\fP در C/C++ عمل می‌کنند: محتویات \fBFILE\fP عیناً در محل بلوک/دستورالعمل کپی می‌شوند. فایل‌های include ممکن است خود دارای includeهای بیشتری باشند. از گزینهٔ \fB\-\-depfile\fP برای ردیابی وابستگی‌های ساخت فایل خروجی به فایل‌های include استفاده کنید. re2go برخی فایل‌های include از پیش تعریف‌شده را فراهم می‌کند که در زیردایرکتوری \fBinclude/\fP پروژه یافت می‌شوند. این فایل‌ها حاوی تعاریفی هستند که ممکن است برای پروژه‌های دیگر مفید باشند (مانند دسته‌بندی‌های Unicode) و چیزی شبیه به یک کتابخانه استاندارد برای re2go\& تشکیل می‌دهند. در ادامه مثالی از استفاده از فایل‌های include آمده است. .SS فایل Include شماره ۱ (definitions.go) .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C const ( ResultOk = iota ResultFail ) /*!re2c number = [1\-9][0\-9]*; */ .ft P .fi .UNINDENT .UNINDENT .SS فایل Include شماره ۲ (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 ResultOk } .ft P .fi .UNINDENT .UNINDENT .SS فایل ورودی (Input file) .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C //go:generate re2go $INPUT \-o $OUTPUT \-i \-\-api simple package main /*!include:re2c \(dqdefinitions.go\(dq */ func lex(yyinput string) int { var yycursor, yymarker int /*!re2c re2c:YYCTYPE = byte; re2c:yyfill:enable = 0; * { return ResultFail } number { return ResultOk } !include \(dqextra_rules.re.inc\(dq; */ } func main() { assert_eq := func(x, y int) { if x != y { panic(\(dqerror\(dq) } } assert_eq(lex(\(dq123\e000\(dq), ResultOk) assert_eq(lex(\(dq123.4567\e000\(dq), ResultOk) } .ft P .fi .UNINDENT .UNINDENT.SS فایل‌های سرآیند (Header files) .sp ابزار re2go به شما امکان می‌دهد تا با استفاده از گزینهٔ \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 یک فایل سرآیند تولید کنید\&. بلوک اول آغاز فایل سرآیند و بلوک دوم پایان آن را مشخص می‌کند. تمام محتوای بین این بلوک‌ها توسط re2go پردازش می‌شود و کد تولیدشده در فایلی که با گزینهٔ \fB\-\-header\fP یا پیکربندی \fBre2c:header\fP مشخص شده نوشته خواهد شد (یا در \fBstdout\fP اگر نه از گزینه و نه از پیکربندی استفاده نشده باشد). فایل سرآیند تولیدشدهٔ خودکار ممکن است در مواردی نیاز باشد که از re2go برای تولید تعاریفی استفاده می‌شود که باید از سایر واحدهای ترجمه (translation units) قابل مشاهده باشند. .sp در اینجا مثالی از تولید یک فایل سرآیند آورده شده است که شامل تعریف وضعیت تحلیل‌گر لغوی (lexer state) با متغیرهای برچسب است (تعداد متغیرها به گرامر باقاعده بستگی دارد و برای برنامه‌نویس مشخص نیست). .SS فایل ورودی (Input file) .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C //go:generate re2go $INPUT \-o $OUTPUT \-i \-\-header lexer/state.go package main import \(dq./lexer\(dq // the package is generated by re2c /*!header:re2c:on*/ package lexer type State struct { Data string Cur /*!stags:re2c format=\(dq, @@\(dq; */ int } /*!header:re2c:off*/ func lex(yyrecord *lexer.State) int { var t int /*!re2c re2c:header = \(dqlexer/state.go\(dq; re2c:api = record; re2c:YYCTYPE = byte; re2c:YYINPUT = \(dqyyrecord.Data\(dq; re2c:YYCURSOR = \(dqyyrecord.Cur\(dq; re2c:yyfill:enable = 0; re2c:tags = 1; re2c:tags:prefix = \(dqTag\(dq; [a]* @t [b]* { return t } */ } func main() { st := &lexer.State{Data:\(dqab\ex00\(dq,} if lex(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. package lexer type State struct { Data string Cur, Mar, Tag1 int } .ft P .fi .UNINDENT .UNINDENT.SS "برنامه‌های اسکلت (Skeleton programs)" .sp با گزینهٔ \fB\-S, \-\-skeleton\fP، برنامهٔ re2go تمام کدهای غیر re2go را نادیده گرفته و یک برنامهٔ C خودکفا تولید می‌کند که می‌تواند در ادامه کامپایل و اجرا شود. این برنامه شامل کد تحلیل‌گر لغوی و داده‌های ورودی است. برای هر DFA ساخته‌شده (بلاک یا شرط)، re2go یک تحلیل‌گر لغوی مستقل و دو فایل تولید می‌کند: یک فایل \fB\&.input\fP شامل رشته‌های مشتق‌شده از DFA و یک فایل \fB\&.keys\fP با نتایج تطابق مورد انتظار. برنامه هر تحلیل‌گر لغوی را روی فایل \fB\&.input\fP متناظر اجرا کرده و نتایج را با موارد مورد انتظار مقایسه می‌کند. برنامه‌های اسکلت به دلایل متعددی بسیار مفید هستند: .INDENT 0.0 .IP \(bu 2 آن‌ها می‌توانند صحت بهینه‌سازی‌های گوناگون re2go را بررسی کنند (داده‌ها در مراحل اولیهٔ فرآیند و پیش از اعمال هرگونه تبدیل روی DFA تولید می‌شوند). .IP \(bu 2 تولید مجموعه‌ای از داده‌های ورودی با پوشش مناسب می‌تواند برای هر دو مقصود آزمون و محک‌زنی (benchmarking) مفید باشد. .IP \(bu 2 تولید برنامه‌های اجرایی خودکفا امکان دسترسی به نمونه‌های آزمون کمینه‌شده (minimized) را فراهم می‌آورد (ممکن است کد اصلی بزرگ باشد یا وابستگی‌های زیادی داشته باشد). .UNINDENT .sp دشواری تولید داده‌های ورودی در این است که به‌جز در ساده‌ترین حالت‌ها، تعداد رشته‌های ورودی ممکن بسیار زیاد است (حتی اگر طول رشته محدود باشد). re2go این مشکل را با تولید رشته‌های کافی برای پوشش تقریباً تمام گذارهای DFA حل می‌کند. این ابزار از الگوریتم زیر استفاده می‌کند: ابتدا یک اسکلت از DFA می‌سازد. برای کدگذاری‌هایی با اندازه واحد کد ۱ بایتی (مانند ASCII، UTF\-8 و EBCDIC)، اسکلت دقیقاً یک رونوشت از DFA اصلی است. برای کدگذاری‌هایی با واحدهای کد چندبایتی، اسکلت رونوشتی از DFA با حذف برخی گذارها است: بدین صورت که re2go حداکثر ۲۵۶ واحد کد را برای هر بازهٔ پیوسته و مجزا که متناظر با یک گذار DFA است در نظر می‌گیرد. مقادیر انتخاب‌شده به‌صورت یکنواخت توزیع شده و شامل کران‌های بازه نیز هستند. re2go به جای تلاش برای پوشش تمام مسیرهای ممکن در اسکلت (که نشدنی است)، مسیرهای کافی برای پوشش همهٔ گذارهای اسکلت را تولید می‌کند و بدین ترتیب پرش‌های شرطی متناظر را در تحلیل‌گر لغوی فعال می‌سازد. پیاده‌سازی این الگوریتم به حدود ۱ گیگابایت گذار محدود شده و مقدار ثابتی حافظه مصرف می‌کند (re2go داده‌ها را به محض تولید در فایل می‌نویسد). .SS "مصورسازی و اشکال‌زدایی (Visualization and debug)" .sp با گزینهٔ \fB\-D, \-\-emit\-dot\fP، برنامهٔ re2go کدی تولید نمی‌کند؛ در عوض، DFA تولیدشده را در قالب DOT ذخیره می‌کند. می‌توان با استفاده از 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 برنامهٔ re2go در ابتدا توسط 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. .