.\" 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 "RE2JAVA" 1 "" "" "" .SH "نام (NAME)" re2java \- تولید تحلیل‌گرهای لغوی سریع برای Java .SH "خلاصه دستور (SYNOPSIS)" .sp re2java \fB[ OPTIONS ]\fP \fB[ WARNINGS ]\fP \fBINPUT\fP .sp ورودی می‌تواند یک فایل یا \fB\-\fP برای stdin باشد. .SH "مقدمه (INTRODUCTION)" .sp ابزار re2java به‌عنوان یک پیش‌پردازنده عمل می‌کند. این ابزار فایل ورودی (که معمولاً برنامه‌ای در Java است، اما می‌تواند هر چیز دیگری باشد) را خوانده و به دنبال بلوک‌هایی از کد می‌گردد که در نشانگرهای آغاز/پایان با قالبی خاص محصور شده‌اند. متن‌های خارج از این بلوک‌ها عیناً به فایل خروجی منتقل می‌شوند. محتویات این بلوک‌ها توسط re2java پردازش می‌شوند\&. این ابزار آن‌ها را به کد Java ترجمه کرده و کد تولیدشده را به جای آن بلوک در خروجی قرار می‌دهد. .sp در اینجا مثالی از یک برنامه کوچک آورده شده است که بررسی می‌کند آیا یک رشته داده‌شده شامل یک عدد ده‌دهی است یا خیر: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2java $INPUT \-o $OUTPUT class Main { static boolean lex(String yyinput) { int yycursor = 0; /*!re2c re2c:YYCTYPE = \(dqchar\(dq; re2c:YYPEEK = \(dqyyinput.charAt(yycursor)\(dq; re2c:yyfill:enable = 0; [1\-9][0\-9]* { return true; } * { return false; } */ } public static void main(String []args) { assert lex(\(dq1234\e0\(dq); } }; .ft P .fi .UNINDENT .UNINDENT .sp در خروجی، re2java بلوک میانی را با کد تولیدشده جایگزین کرده است: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Generated by re2java // re2java $INPUT \-o $OUTPUT class Main { static boolean lex(String yyinput) { int yycursor = 0; { char yych = 0; int yystate = 0; yyl: while (true) { switch (yystate) { case 0: yych = yyinput.charAt(yycursor); yycursor += 1; switch (yych) { case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: yystate = 2; continue yyl; default: yystate = 1; continue yyl; } case 1: { return false; } case 2: yych = yyinput.charAt(yycursor); switch (yych) { case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: yycursor += 1; yystate = 2; continue yyl; default: yystate = 3; continue yyl; } case 3: { return true; } default: throw new IllegalStateException(\(dqinternal lexer error\(dq); } } } } public static void main(String []args) { assert lex(\(dq1234\e0\(dq); } }; .ft P .fi .UNINDENT .UNINDENT.SH "مبانی (BASICS)" .sp یک برنامهٔ re2java از دنباله‌ای از \fIبلوک‌ها\fP (blocks) تشکیل شده است که با کدهای زبان مقصد درآمیخته شده‌اند. یک بلوک می‌تواند شامل \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\%عبارت‌های منظم\fP مروری کلی بر نحو re2java برای عبارت‌های منظم ارائه می‌دهد. پس از تعریف، \fBname\fP می‌تواند در سایر عبارت‌های منظم و در قواعد استفاده شود. بازگشت (توابع بازگشتی) در تعاریف نام‌گذاری‌شده مجاز نیست و هر نام باید پیش از استفاده تعریف شده باشد. یک بلوک، تعاریف نام‌گذاری‌شده را از حوزهٔ سراسری (global scope) به ارث می‌برد. بازتعریف نامی که در حوزهٔ فعلی وجود دارد یک خطا محسوب می‌شود. .TP .B \fBconfiguration = value ;\fP یک \fIپیکربندی\fP امکان تغییر رفتار re2java و سفارشی‌سازی کد تولیدشده را فراهم می‌کند. برای مشاهدهٔ فهرست کامل پیکربندی‌های پشتیبانی‌شده توسط re2java به بخش \fI\%پیکربندی‌ها\fP مراجعه کنید. بسته به هر پیکربندی مشخص، \fBvalue\fP می‌تواند یک کلیدواژه، یک عدد صحیح غیرمنفی یا یک رشتهٔ تک‌خطی باشد که اگر شامل نویسه‌های غیر حرفی\-عددی باشد باید در کوتیشن تکی یا جفتی قرار گیرد. یک بلوک، پیکربندی‌ها را از حوزهٔ سراسری به ارث می‌برد و می‌تواند آن‌ها را بازتعریف کرده یا موارد جدیدی اضافه کند. پیکربندی‌های تعریف‌شده درون یک بلوک بر کل بلوک تأثیر می‌گذارند، حتی اگر در انتهای آن قرار گرفته باشند. .TP .B \fBregular\-expression code\fP یک \fIقاعده\fP، عبارت منظم \fBregular\-expression\fP را به کنش معنایی آن (یک بلوک کد درون آکولاد، یا یک بلوک کد که با \fB:=\fP شروع شده و به یک خط جدید به همراه هر نویسهٔ غیرفاصله‌ای ختم می‌شود) مقید می‌سازد. اگر \fBregular\-expression\fP مطابقت داشته باشد، \fBcode\fP مربوطه اجرا می‌شود. اگر چند قاعده مطابقت داشته باشند، طولانی‌ترین تطابق اولویت دارد. اگر چند قاعده با یک رشتهٔ یکسان تطابق داشته باشند، قاعده‌ای که زودتر آمده اولویت دارد. دو قاعدهٔ خاص وجود دارد: قاعدهٔ پیش‌فرض \fB*\fP و قاعدهٔ پایان ورودی \fB$\fP\&. قاعدهٔ پیش‌فرض همواره باید تعریف شود؛ این قاعده صرف‌نظر از جایگاهش در بلوک، کمترین اولویت را دارد و با هر واحد کد (code unit) تطابق می‌یابد (نه لزوماً یک نویسهٔ معتبر، بخش \fI\%پشتیبانی از کدگذاری\fP را ببینید). اگر روش متناظر برای \fI\%مدیریت پایان ورودی\fP استفاده شده باشد، قاعدهٔ پایان ورودی باید تعریف شود. با وجود \fI\%شرایط شروع\fP، قواعد نحو پیچیده‌تری خواهند داشت. .TP .B \fB!action code\fP یک \fIکنش\fP، یک بلوک کدِ تعریف‌شده توسط کاربر (\fBcode\fP) را به یک مکان خاص در ماشین حالت متناهی تولیدشده مقید می‌سازد (همانند کنش‌های معنایی که کد را به وضعیت‌های نهایی مقید می‌کنند). برای فهرست کامل کنش‌های از پیش تعریف‌شده بخش \fI\%کنش‌ها\fP را ببینید. .TP .B \fB!directive ;\fP یک \fIدستورالعمل\fP یکی از دستورهای خاصِ از پیش تعریف‌شده است. هر دستورالعمل هدف منحصربه‌فردی دارد. برای جزئیات به بخش \fI\%دستورالعمل‌ها\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 شامل تعاریف، پیکربندی‌ها، قواعد و دستورالعمل‌ها است. re2java عبارت‌های منظم مربوط به هر قاعده را در قالب یک اتوماتای متناهی معین (DFA) کامپایل می‌کند، آن را به شکل پرش‌های شرطی در زبان مقصد کدگذاری کرده و بلوک را با کد تولیدشده جایگزین می‌کند. نام‌ها و پیکربندی‌های تعریف‌شده در یک بلوک سراسری به حوزهٔ سراسری افزوده شده و برای بلوک‌های بعدی قابل مشاهده می‌شوند. در آغاز برنامه، حوزهٔ سراسری با \fI\%گزینه‌های\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\%بلوک‌های قابل استفاده مجدد\fP). پیش از نسخهٔ 2.2 نرم‌افزار re2java، بلوک‌های قواعد نیازمند گزینهٔ \fB\-r \-\-reusable\fP بودند. .TP .B \fB/*!use:re2c[:] ... */\fP or \fB%{use[:] ... %}\fP یک بلوک use که به یک بلوک قواعد قبلاً تعریف‌شده ارجاع می‌دهد. اگر نام مشخص شده باشد، re2java به دنبال بلوک قواعدی با این نام می‌گردد. در غیر این صورت، نزدیک‌ترین بلوک قواعد قبلی استفاده می‌شود (چه نام‌گذاری‌شده باشد چه بدون نام). یک بلوک use می‌تواند تعاریف، پیکربندی‌ها و قواعد خاص خود را اضافه کند که به موارد موجود در بلوک قواعد مرجع افزوده می‌شوند. پیش از نسخهٔ 2.2 نرم‌افزار re2java، بلوک‌های 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 تولیدشده توسط re2java بسط می‌یابد\&. یک فهرست اختیاری از نام‌های بلوک مشخص می‌کند که هنگام محاسبهٔ مجموعهٔ متغیرهای برچسب، کدام بلوک‌ها باید لحاظ شوند (اگر فهرست خالی باشد، تمام بلوک‌ها لحاظ می‌شوند). دو پیکربندی اختیاری وجود دارد: \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) یا به‌طور ضمنی توسط re2java تولید شده باشد (با گزینه‌های \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 بلوکی که ارسال شرطی (conditional dispatch) بر روی وضعیت تحلیل‌گر لغوی را تولید می‌کند (به گزینهٔ \fB\-\-storable\-state\fP نیاز دارد). یک فهرست اختیاری از نام‌های بلوک تعیین می‌کند که کدام بلوک‌ها باید در ارسال وضعیت گنجانده شوند. گذار پیش‌فرض به برچسب آغازین اولین بلوک در فهرست می‌رود. اگر فهرست خالی باشد، تمام بلوک‌ها لحاظ می‌شوند و گذار پیش‌فرض به اولین بلوک دارای برچسب آغازین در فایل می‌رود. این نوع بلوک با گزینهٔ \fB\-\-loop\-switch\fP ناسازگار است، چرا که نیازمند گذارهای میان‌بلوکی است که بدون دستور \fBgoto\fP یا فراخوانی توابع پشتیبانی نمی‌شوند. .TP .B \fB/*!conditions:re2c[:[:...]] ... */\fP, \fB/*!types:re2c... */\fP or \fB%{conditions[:[:...]] ... %}\fP, \fB%{types... %}\fP بلوکی که شمارش وضعیت‌ها/شرایط (condition enumeration) را تولید می‌کند (نیازمند گزینهٔ \fB\-\-conditions\fP است). یک فهرست اختیاری از نام‌های بلوک مشخص می‌کند که کدام بلوک‌ها هنگام محاسبهٔ مجموعهٔ شرایط باید لحاظ شوند (اگر فهرست خالی باشد، تمام بلوک‌ها لحاظ می‌شوند). به‌طور پیش‌فرض، کد تولیدشده یک نوع شمارشی \fBYYCONDTYPE\fP است\&. این مقدار با پیکربندی‌های اختیاری \fBformat\fP و \fBseparator\fP قابل سفارشی‌سازی است\&. پیکربندی \fBformat\fP یک رشتهٔ الگو را مشخص می‌کند که در آن \fB@@{cond}\fP (یا به اختصار \fB@@\fP) با نام هر شرط، و \fB@@{num}\fP با اندیس عددی آن شرط جایگزین می‌شود. پیکربندی \fBseparator\fP قطعه کدی را تعیین می‌کند که برای پیوند دادن بخش‌های \fBformat\fP تولیدشده برای شرایط مختلف به کار می‌رود. .TP .B \fB/*!include:re2c */\fP or \fB%{include %}\fP این بلوک امکان درج \fB\fP را فراهم می‌کند که باید یک مسیر فایل درون علامت نقل‌قول جفتی (گیومه) باشد. محتویات فایل دقیقاً به جای بلوک جایگزین می‌شود، درست مانند نحوهٔ کارکرد \fB#include\fP در C/C++. این بلوک می‌تواند به همراه گزینهٔ \fB\-\-depfile\fP برای تولید وابستگی‌های سامانهٔ ساخت بر روی فایل‌های درج‌شده استفاده شود. .TP .B \fB/*!header:re2c:on*/\fP or \fB%{header:on %}\fP این بلوک نشانگر آغاز فایل سرآیند است. هر چیزی پس از آن و تا بلوک بعدی \fBheader:off\fP توسط re2java پردازش شده و در فایل سرآیند مشخص‌شده با گزینهٔ \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 در اینجا فهرست کاملی از پیکربندی‌های پشتیبانی‌شده توسط re2java آورده شده است: .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++ یا بستارها (closures) در 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 اگر روی یک مقدار عددی صحیح و مثبت تنظیم شود، حالت پیش‌فرض (default case) در توزیع شرایط تولیدشده، اجرای برنامه را لغو (abort) می‌کند. .TP .B \fBre2c:cond:goto\fP قطعه کدی را مشخص می‌کند که برای قواعد میانبر خودکار تولیدشدهٔ \fB:=>\fP در شرایط استفاده می‌شود. پیش‌فرض \fBgoto @@;\fP است\&. جای‌نگه‌دار \fB@@\fP با نام شرط جایگزین می‌شود (پیکربندی‌های \fBre2c:api:sigil\fP و \fBre2c:cond:goto@cond\fP را ببینید)\&. .TP .B \fBre2c:cond:goto@cond\fP نشانگر مورد استفاده برای جایگزینی آرگومان را در تعریف \fBre2c:cond:goto\fP مشخص می‌کند. مقدار پیش‌فرض \fB@@\fP است\&. بر پیکربندی عمومی‌تر \fBre2c:api:sigil\fP اولویت دارد. .TP .B \fBre2c:cond:divider\fP جداکنندهٔ بلوک‌های شرط را مشخص می‌کند. مقدار پیش‌فرض \fB/* *********************************** */\fP است\&. جای‌نگه‌دارها با نام شرط جایگزین می‌شوند (\fBre2c:api;sigil\fP و \fBre2c:cond:divider@cond\fP را ببینید)\&. .TP .B \fBre2c:cond:divider@cond\fP نشانگر مورد استفاده برای جایگزینی آرگومان در تعریف \fBre2c:cond:divider\fP را مشخص می‌کند. مقدار پیش‌فرض \fB@@\fP است\&. بر پیکربندی عمومی‌تر \fBre2c:api:sigil\fP اولویت دارد. .TP .B \fBre2c:cond:prefix\fP, \fBre2c:condprefix\fP پیشوند مورد استفاده برای برچسب‌های شرط را مشخص می‌کند. پیش‌فرض \fByyc_\fP است\&. .TP .B \fBre2c:cond:enumprefix\fP, \fBre2c:condenumprefix\fP پیشوند مورد استفاده برای شناسه‌های شرط را مشخص می‌کند. پیش‌فرض \fByyc\fP است\&. .TP .B \fBre2c:debug\-output\fP, \fBre2c:flags:debug\-output\fP, \fBre2c:flags:d\fP مشابه گزینهٔ \fB\-\-debug\-output\fP، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:empty\-class\fP, \fBre2c:flags:empty\-class\fP مشابه گزینهٔ \fB\-\-empty\-class\fP، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:encoding:ebcdic\fP, \fBre2c:flags:ecb\fP, \fBre2c:flags:e\fP مشابه گزینهٔ \fB\-\-ebcdic\fP، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:encoding:ucs2\fP, \fBre2c:flags:wide\-chars\fP, \fBre2c:flags:w\fP مشابه گزینهٔ \fB\-\-ucs2\fP، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:encoding:utf8\fP, \fBre2c:flags:utf\-8\fP, \fBre2c:flags:8\fP مشابه گزینهٔ \fB\-\-utf8\fP، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:encoding:utf16\fP, \fBre2c:flags:utf\-16\fP, \fBre2c:flags:x\fP مشابه گزینهٔ \fB\-\-utf16\fP، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:encoding:utf32\fP, \fBre2c:flags:unicode\fP, \fBre2c:flags:u\fP مشابه گزینهٔ \fB\-\-utf32\fP، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:encoding\-policy\fP, \fBre2c:flags:encoding\-policy\fP مشابه گزینهٔ \fB\-\-encoding\-policy\fP، اما می‌تواند بر پایهٔ هر بلوک پیکربندی شود. .TP .B \fBre2c:eof\fP نماد نشانگر پایان (sentinel) مورد استفاده همراه با قاعدهٔ پایان ورودی \fB$\fP را مشخص می‌کند. مقدار پیش‌فرض \fB\-1\fP است (قاعدهٔ \fB$\fP استفاده نمی‌شود). مقادیر ممکن دیگر شامل تمام واحدهای کد معتبر هستند. تنها اعداد در مبنای ۱۰ (ده‌دهی) شناسایی می‌شوند. .TP .B \fBre2c:header\fP, \fBre2c:flags:type\-header\fP, \fBre2c:flags:t\fP نام فایل سرآیند تولیدشده را نسبت به دایرکتوری فایل خروجی مشخص می‌کند. مشابه گزینهٔ \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 نام برچسب اختیاری را که پس از switch دستور \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 عبارت مورد استفاده برای متغیرهای تگ را مشخص می‌کند. به‌طور پیش‌فرض re2java عباراتی به شکل \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 تنظیم نشده باشد). این پیکربندی بر تولید کد تأثیری ندارد: هدف آن بررسی این است که نماد نگهبان در میانهٔ یک قاعده (rule) مجاز نباشد و اطمینان حاصل شود که تحلیل‌گر لغوی فراتر از انتهای بافر را نخواهد خواند. مقدار پیش‌فرض \fI\-1\(ga\fP است (در این حالت re2java فرض می‌کند که نگهبان صفر است، که رایج‌ترین حالت می‌باشد). فقط اعداد ده‌دهی شناسایی می‌شوند. .TP .B \fBre2c:state:abort\fP اگر روی یک مقدار عددی صحیح مثبت تنظیم شود، مورد (case) پیش‌فرض در توزیع وضعیت (state dispatch) تولیدشده، اجرای برنامه را متوقف (abort) می‌کند و یک مورد صریح \fB\-1\fP شامل انتقال به ابتدای بلوک خواهد بود. .TP .B \fBre2c:state:nextlabel\fP کنترل می‌کند که آیا پس از ساختار چندشاخهٔ (switch) \fBYYGETSTATE\fP یک برچسب \fByyNext\fP بیاید یا خیر (مقدار پیش‌فرض صفر است که متناظر با عدم وجود برچسب می‌باشد). به عنوان روش جایگزین می‌توان از \fBre2c:label:start\fP برای تولید یک برچسب شروع مشخص، یا یک بلوک صریح \fBgetstate\fP برای تولید ساختار switch مربوط به \fBYYGETSTATE\fP به‌طور جداگانه از بلوک تحلیل‌گر لغوی استفاده کرد. .TP .B \fBre2c:unsafe\fP, \fBre2c:flags:unsafe\fP مشابه گزینهٔ \fB\-\-no\-unsafe\fP، اما می‌تواند بر مبنای هر بلوک پیکربندی شود. اگر روی صفر تنظیم شود، از تولید پوشش‌های \fBunsafe\fP در اطراف \fBYYPEEK\fP جلوگیری می‌کند\&. مقدار پیش‌فرض غیرصفر است (پوشش‌ها تولید می‌شوند). این پیکربندی مختص به Rust است. .TP .B \fBre2c:YYBACKUP\fP, \fBre2c:define:YYBACKUP\fP پریمیتیو عمومی API \fBYYBACKUP\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYBACKUPCTX\fP, \fBre2c:define:YYBACKUPCTX\fP پریمیتیو عمومی API \fBYYBACKUPCTX\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYCONDTYPE\fP, \fBre2c:define:YYCONDTYPE\fP پریمیتیو API \fBYYCONDTYPE\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYCTYPE\fP, \fBre2c:define:YYCTYPE\fP پریمیتیو API \fBYYCTYPE\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYCTXMARKER\fP, \fBre2c:define:YYCTXMARKER\fP پریمیتیو API \fBYYCTXMARKER\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYCURSOR\fP, \fBre2c:define:YYCURSOR\fP پریمیتیو API \fBYYCURSOR\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYDEBUG\fP, \fBre2c:define:YYDEBUG\fP پریمیتیو API \fBYYDEBUG\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYFILL\fP, \fBre2c:define:YYFILL\fP پریمیتیو API \fBYYFILL\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYFILL@len\fP, \fBre2c:define:YYFILL@len\fP علامت نشانه (sigil) مورد استفاده برای جایگزینی آرگومان در تعریف \fBYYFILL\fP را مشخص می‌کند. مقدار پیش‌فرض \fB@@\fP است\&. پیکربندی عمومی‌تر \fBre2c:api:sigil\fP را بازنویسی می‌کند. .TP .B \fBre2c:YYFILL:naked\fP, \fBre2c:define:YYFILL:naked\fP پیکربندی عمومی‌تر \fBre2c:api:style\fP را برای \fBYYFILL\fP بازنویسی می‌کند\&. مقدار صفر متناظر با سبک آزاد (free-form) در API است. .TP .B \fBre2c:YYFN\fP پریمیتیو API \fBYYFN\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYINPUT\fP پریمیتیو API \fBYYINPUT\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYGETCOND\fP, \fBre2c:define:YYGETCONDITION\fP پریمیتیو API \fBYYGETCOND\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYGETCOND:naked\fP, \fBre2c:define:YYGETCONDITION:naked\fP پیکربندی عمومی‌تر \fBre2c:api:style\fP را برای \fBYYGETCOND\fP بازنویسی می‌کند\&. مقدار صفر متناظر با سبک آزاد (free-form) در API است. .TP .B \fBre2c:YYGETSTATE\fP, \fBre2c:define:YYGETSTATE\fP پریمیتیو API \fBYYGETSTATE\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYGETSTATE:naked\fP, \fBre2c:define:YYGETSTATE:naked\fP پیکربندی عمومی‌تر \fBre2c:api:style\fP را برای \fBYYGETSTATE\fP بازنویسی می‌کند\&. مقدار صفر متناظر با سبک آزاد (free-form) در API است. .TP .B \fBre2c:YYGETACCEPT\fP, \fBre2c:define:YYGETACCEPT\fP پریمیتیو API \fBYYGETACCEPT\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYLESSTHAN\fP, \fBre2c:define:YYLESSTHAN\fP پریمیتیو عمومی API \fBYYLESSTHAN\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYLIMIT\fP, \fBre2c:define:YYLIMIT\fP پریمیتیو API \fBYYLIMIT\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYMARKER\fP, \fBre2c:define:YYMARKER\fP پریمیتیو API \fBYYMARKER\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYMTAGN\fP, \fBre2c:define:YYMTAGN\fP پریمیتیو عمومی API \fBYYMTAGN\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYMTAGP\fP, \fBre2c:define:YYMTAGP\fP پریمیتیو عمومی API \fBYYMTAGP\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYPEEK\fP, \fBre2c:define:YYPEEK\fP پریمیتیو عمومی API \fBYYPEEK\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYRESTORE\fP, \fBre2c:define:YYRESTORE\fP پریمیتیو عمومی API \fBYYRESTORE\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYRESTORECTX\fP, \fBre2c:define:YYRESTORECTX\fP پریمیتیو عمومی API \fBYYRESTORECTX\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYRESTORETAG\fP, \fBre2c:define:YYRESTORETAG\fP پریمیتیو عمومی API \fBYYRESTORETAG\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYSETCOND\fP, \fBre2c:define:YYSETCONDITION\fP پریمیتیو API \fBYYSETCOND\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYSETCOND@cond\fP, \fBre2c:define:YYSETCONDITION@cond\fP علامت نشانه (sigil) مورد استفاده برای جایگزینی آرگومان در تعریف \fBYYSETCOND\fP را مشخص می‌کند. مقدار پیش‌فرض \fB@@\fP است\&. پیکربندی عمومی‌تر \fBre2c:api:sigil\fP را بازنویسی می‌کند. .TP .B \fBre2c:YYSETCOND:naked\fP, \fBre2c:define:YYSETCONDITION:naked\fP پیکربندی عمومی‌تر \fBre2c:api:style\fP را برای \fBYYSETCOND\fP بازنویسی می‌کند\&. مقدار صفر متناظر با سبک آزاد (free-form) در API است. .TP .B \fBre2c:YYSETSTATE\fP, \fBre2c:define:YYSETSTATE\fP پریمیتیو API \fBYYSETSTATE\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYSETSTATE@state\fP, \fBre2c:define:YYSETSTATE@state\fP علامت نشانه (sigil) مورد استفاده برای جایگزینی آرگومان در تعریف \fBYYSETSTATE\fP را مشخص می‌کند. مقدار پیش‌فرض \fB@@\fP است\&. پیکربندی عمومی‌تر \fBre2c:api:sigil\fP را بازنویسی می‌کند. .TP .B \fBre2c:YYSETSTATE:naked\fP, \fBre2c:define:YYSETSTATE:naked\fP پیکربندی عمومی‌تر \fBre2c:api:style\fP را برای \fBYYSETSTATE\fP بازنویسی می‌کند\&. مقدار صفر متناظر با سبک آزاد (free-form) در API است. .TP .B \fBre2c:YYSETACCEPT\fP, \fBre2c:define:YYSETACCEPT\fP پریمیتیو API \fBYYSETACCEPT\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYSKIP\fP, \fBre2c:define:YYSKIP\fP پریمیتیو عمومی API \fBYYSKIP\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYSHIFT\fP, \fBre2c:define:YYSHIFT\fP پریمیتیو عمومی API \fBYYSHIFT\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYCOPYMTAG\fP, \fBre2c:define:YYCOPYMTAG\fP پریمیتیو عمومی API \fBYYCOPYMTAG\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYCOPYSTAG\fP, \fBre2c:define:YYCOPYSTAG\fP پریمیتیو عمومی API \fBYYCOPYSTAG\fP را تعریف می‌کند\&..TP .B \fBre2c:YYSHIFTMTAG\fP, \fBre2c:define:YYSHIFTMTAG\fP پریمیتیو عمومی 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 اگر روی غیرصفر تنظیم شود، نگاشت‌های بیتی برای گزینهٔ \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 اگر روی غیرصفر تنظیم شود، re2java با هر بار خوانده شدن \fByych\fP به‌طور خودکار تبدیل به \fBYYCTYPE\fP را تولید می‌کند. پیش‌فرض صفر است (بدون تبدیل). .TP .B \fBre2c:yych:literals\fP, \fBre2c:variable:yych:literals\fP شکل لیترال‌هایی را که \fByych\fP با آن‌ها تطبیق داده می‌شود مشخص می‌کند. مقادیر ممکن عبارتند از: \fBchar\fP (لیترال‌های نویسه‌ای درون گیومهٔ تکی، نویسه‌های غیرقابل‌چاپ از دنباله‌های گریز که با بک‌اسلش شروع می‌شوند استفاده می‌کنند)، \fBhex\fP (اعداد صحیح هگزادسیمال) و \fBchar_or_hex\fP (ترکیبی از هر دو، لیترال‌های نویسه‌ای برای نویسه‌های قابل‌چاپ و اعداد صحیح هگزادسیمال برای بقیه). .TP .B \fBre2c:yyctable\fP, \fBre2c:variable:yyctable\fP پریمیتیو API یعنی \fByyctable\fP را تعریف می‌کند\&. .TP .B \fBre2c:yynmatch\fP, \fBre2c:variable:yynmatch\fP پریمیتیو API یعنی \fByynmatch\fP را تعریف می‌کند\&. .TP .B \fBre2c:yypmatch\fP, \fBre2c:variable:yypmatch\fP پریمیتیو API یعنی \fByypmatch\fP را تعریف می‌کند\&. .TP .B \fBre2c:yytarget\fP, \fBre2c:variable:yytarget\fP پریمیتیو API یعنی \fByytarget\fP را تعریف می‌کند\&. .TP .B \fBre2c:yystable\fP, \fBre2c:variable:yystable\fP منسوخ شده است. .TP .B \fBre2c:yystate\fP, \fBre2c:variable:yystate\fP پریمیتیو API یعنی \fByystate\fP را تعریف می‌کند\&. .TP .B \fBre2c:yyfill\fP, \fBre2c:variable:yyfill\fP پریمیتیو API یعنی \fByyfill\fP را تعریف می‌کند\&. .TP .B \fBre2c:yyfill:check\fP اگر روی صفر تنظیم شود، از تولید بررسی پیش از \fBYYFILL\fP برای تعداد نویسه‌های ورودی (تعریف \fBYYLESSTHAN\fP در generic API و مقایسهٔ مبتنی بر \fBYYLIMIT\fP در C pointer API) جلوگیری می‌کند. مقدار پیش‌فرض غیرصفر است (بررسی را تولید می‌کند). .TP .B \fBre2c:yyfill:enable\fP اگر روی صفر تنظیم شود، از تولید \fBYYFILL\fP (همراه با بررسی آن) جلوگیری می‌کند. این پیکربندی باید زمانی استفاده شود که کل ورودی در یک بخش پیوسته از حافظه جا می‌گیرد (نیازی به بافرسازی نیست) و بررسی‌های پایان ورودی به بررسی‌های \fBYYFILL\fP وابسته نیستند (مثلاً در صورتی که از یک نویسهٔ دیده‌بان استفاده شود). برای اطمینان از اینکه لکسر تولیدشده نمی‌تواند فراتر از پایان ورودی را بخواند، از هشدارها (گزینهٔ \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 ابزار re2java از نحو زیر برای عبارات باقاعده استفاده می‌کند: .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؛ از پرانتزها برای تغییر اولویت استفاده می‌شود. اگر استخراج زیرتطابق (submatch extraction) فعال باشد، \fB(R)\fP بسته به گزینهٔ \fB\-\-invert\-captures\fP یک گروه ضبط‌کننده یا غیرضبط‌کننده خواهد بود. .TP .B \fB(!R)\fP اگر استخراج زیرتطابق فعال باشد، \fB(!R)\fP بسته به گزینهٔ \fB\-\-invert\-captures\fP یک گروه غیرضبط‌کننده یا ضبط‌کننده خواهد بود. .TP .B \fBR S\fP الحاق: \fBR\fP و سپس \fBS\fP\&. .TP .B \fBR | S\fP جایگزین: \fBR\fP یا \fBS\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 در اینجا فهرستی از کنش‌های از پیش تعریف‌شده که توسط re2java پشتیبانی می‌شوند آمده است: .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 در اینجا فهرست کاملی از دستورالعمل‌های پشتیبانی‌شده توسط re2java آمده است: .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\& شناخته می‌شوند. اینکه چه پریمیتیوهایی باید برای یک برنامه خاص تعریف شوند به عوامل متعددی بستگی دارد، از جمله پیچیدگی عبارات باقاعده، نحوه نمایش ورودی، بافرینگ و استفاده از قابلیت‌های گوناگون. تمام پریمیتیوهای ضروری باید توسط کاربر در قالب ماکروها، توابع، متغیرها یا هر شکل مناسب دیگری تعریف شوند که کد تولیدشده را از نظر نحوی و معنایی صحیح سازد. ابزار re2java تعاریف را بررسی نمی‌کند (و نمی‌تواند بررسی کند)، بنابراین اگر چیزی جا افتاده باشد یا به نادرستی تعریف شده باشد، برنامه تولیدشده ممکن است خطاهای زمان کامپایل یا زمان اجرا داشته باشد. این راهنما مثال‌هایی از تعاریف API را در متداول‌ترین حالت‌ها ارائه می‌دهد. .sp ابزار re2java دارای سه مدل API است که مجموعه هسته پریمیتیوهای مورداستفاده در برنامه را تعریف می‌کنند: .INDENT 0.0 .TP .B \fBSimple API\fP این API پیش‌فرض برای بک‌اند جاوا است. این رابط از پریمیتیوهای زیر تشکیل شده است: \fBYYINPUT\fP (که باید به عنوان دنباله‌ای از واحدهای کد، مانند یک رشته تعریف شود) و \fBYYCURSOR\fP، \fBYYMARKER\fP، \fBYYCTXMARKER\fP، \fBYYLIMIT\fP (که باید به عنوان اندیس‌هایی در \fBYYINPUT\fP تعریف شوند). .nf .fi .sp .TP .B \fBRecord API\fP رابط Record API در مواردی مفید است که وضعیت لکسر باید در یک کلاس ذخیره شود. این رابط با گزینه \fB\-\-api record\fP یا پیکربندی \fBre2c:api = record\fP فعال می‌شود. این API شامل متغیری به نام \fByyrecord\fP است (نام آن را می‌توان با \fBre2c:yyrecord\fP بازنویسی کرد) که باید به عنوان کلاسی با فیلدهای \fByyinput\fP، \fByycursor\fP، \fByymarker\fP، \fByyctxmarker\fP و \fByylimit\fP تعریف شود (تنها فیلدهایی که توسط کد تولیدشده استفاده می‌شوند نیاز به تعریف دارند، و نام‌های آن‌ها قابل پیکربندی است). .nf .fi .sp .TP .B \fBGeneric API\fP این منعطف‌ترین نوع API است. این رابط با گزینه \fB\-\-api generic\fP یا پیکربندی \fBre2c:api = generic\fP فعال می‌شود. این رابط شامل پریمیتیوهایی برای عملیات همگانی است: \fBYYPEEK\fP، \fBYYSKIP\fP، \fBYYBACKUP\fP، \fBYYBACKUPCTX\fP، \fBYYSTAGP\fP، \fBYYSTAGN\fP، \fBYYMTAGP\fP، \fBYYMTAGN\fP، \fBYYRESTORE\fP، \fBYYRESTORECTX\fP، \fBYYRESTORETAG\fP، \fBYYSHIFT\fP، \fBYYSHIFTSTAG\fP، \fBYYSHIFTMTAG\fP، \fBYYLESSTHAN\fP، \fBYYEND\fP\&. .UNINDENT .sp در اینجا فهرست کاملی از پریمیتیوهای API که ممکن است توسط کد تولیدشده به منظور ارتباط با برنامه بیرونی به کار روند آمده است: .INDENT 0.0 .TP .B \fBYYCTYPE\fP نوع نویسه‌های ورودی (واحدهای کد). برای کدگذاری‌های ASCII، EBCDIC و UTF\-8 باید عدد صحیح بدون علامت ۱ بایتی باشد. برای UTF\-16 یا UCS\-2 باید عدد صحیح بدون علامت ۲ بایتی باشد. برای UTF\-32 باید عدد صحیح بدون علامت ۴ بایتی باشد. .TP .B \fBYYCURSOR\fP یک مقدار چپ (l\-value) که موقعیت کنونی ورودی را ذخیره می‌کند (یک اشاره‌گر یا آفست عدد صحیح در \fBYYINPUT\fP). در ابتدا \fBYYCURSOR\fP باید به نخستین نویسه ورودی اشاره کند، و در ادامه توسط کد تولیدشده به جلو رانده می‌شود. هنگامی که قاعده‌ای منطبق می‌شود، موقعیت \fBYYCURSOR\fP پس از آخرین نویسه تطبیق‌یافته است. .TP .B \fBYYLIMIT\fP یک مقدار راست (r\-value) که موقعیت پایان ورودی را ذخیره می‌کند (یک اشاره‌گر یا آفست عدد صحیح در \fBYYINPUT\fP). در ابتدا \fBYYLIMIT\fP باید به موقعیت پس از آخرین نویسه ورودیِ در دسترس اشاره کند. این مقدار توسط کد تولیدشده تغییر نمی‌کند. لکسر \fBYYCURSOR\fP را با \fBYYLIMIT\fP مقایسه می‌کند تا مشخص کند آیا نویسه‌های ورودی به اندازه کافی باقی مانده است یا خیر. .TP .B \fBYYMARKER\fP یک مقدار چپ (l\-value) که موقعیت آخرین قاعده تطبیق‌یافته را ذخیره می‌کند (یک اشاره‌گر یا آفست عدد صحیح در \fBYYINPUT\fP). از این مقدار برای بازگرداندن موقعیت \fBYYCURSOR\fP در صورتی استفاده می‌شود که تطبیق طولانی‌تر شکست بخورد و لکسر نیاز به عقب‌گرد داشته باشد. نیازی به مقداردهی اولیه نیست. .TP .B \fBYYCTXMARKER\fP یک مقدار چپ (l\-value) که موقعیت زمینه دنباله‌دار (trailing context) را ذخیره می‌کند (یک اشاره‌گر یا آفست عدد صحیح در \fBYYINPUT\fP). نیازی به مقداردهی اولیه نیست. \fBYYCTXMARKER\fP تنها در صورتی مورد نیاز است که عملگر پیش‌نگری \fB/\fP استفاده شده باشد. .TP .B \fBYYFILL\fP یک پریمیتیو از Generic API با یک متغیر \fBlen\fP\&. \fBYYFILL\fP باید حداقل \fBlen\fP نویسه ورودی دیگر فراهم کند یا ناموفق باشد. اگر \fBre2c:eof\fP استفاده شود، \fBlen\fP همیشه \fB1\fP است و \fBYYFILL\fP باید همواره به تابع فراخواننده بازگردد؛ مقدار بازگشتی صفر نشان‌دهنده موفقیت است. اگر \fBre2c:eof\fP استفاده نشود، مقدار بازگشتی \fBYYFILL\fP نادیده گرفته می‌شود و در صورت بروز شکست نباید بازگردد. بیشینه مقدار \fBlen\fP برابر \fBYYMAXFILL\fP است. .TP .B \fBYYFN\fP پریمیتیوی که پیش‌نمونه تابع را در مدل کد \fB\-\-recursive\-functions\fP تعریف می‌کند. مقدار آن باید آرایه‌ای از یک یا چند رشته باشد، که در آن هر رشته شامل دو یا سه جزء جداشده با رشته مشخص‌شده در پیکربندی \fBre2c:fn:sep\fP (معمولاً یک نقطه‌ویرگول) است. نخستین عنصر آرایه نام تابع و نوع بازگشتی را مشخص می‌کند (برای یک تابع void خالی است). عناصر بعدی آرگومان‌های تابع را مشخص می‌کنند: نخست، عبارت مورد استفاده برای آرگومان در بدنه تابع (معمولاً فقط یک نام)؛ دوم، نوع آرگومان؛ سوم، یک پارامتر صوری اختیاری (به طور پیش‌فرض همان جزء نخست است \- معمولاً هم آرگومان و هم پارامتر یک شناسه یکسان هستند). .TP .B \fBYYINPUT\fP یک مقدار راست (r\-value) که دنباله نویسه‌های ورودی کنونی را ذخیره می‌کند (رشته، بافر، و غیره). .TP .B \fBYYMAXFILL\fP یک ثابت عدد صحیح برابر با بیشینه مقدار آرگومانِ \fBYYFILL\fP\&. می‌توان آن را با یک بلوک \fBmax\fP تولید کرد. .TP .B \fBYYLESSTHAN\fP یک پریمیتیو از Generic API با یک متغیر \fBlen\fP\&. باید به صورت یک مقدار راست (r\-value) از نوع بولی تعریف شود که اگر و تنها اگر کمتر از \fBlen\fP نویسه ورودی باقی مانده باشد، برابر با \fBtrue\fP گردد. .TP .B \fBYYEND\fP یک پریمیتیو از Generic API بدون متغیر. باید به صورت یک مقدار راست (r\-value) از نوع بولی تعریف شود که اگر و تنها اگر پایان \fIمنطقی\fP ورودی فرا رسیده باشد (بدون در نظر گرفتن هرگونه نماد فاصله‌گذاری یا نگهبان)، برابر با \fBtrue\fP گردد. \fBYYEND\fP برای پیاده‌سازی نماد \fB$\fP در عبارات باقاعده به کار می‌رود. این مقدار با \fBYYLESSTHAN\fP تفاوت دارد که برای اطمینان از فراتر نرفتن لکسر از انتهای بافر استفاده می‌شود. .TP .B \fBYYPEEK\fP یک پریمیتیو از Generic API بدون متغیر. باید به عنوان یک مقدار راست (r\-value) از نوع \fBYYCTYPE\fP تعریف شود که برابر با نویسه در موقعیت کنونی ورودی است. .TP .B \fBYYSKIP\fP یک پریمیتیو از Generic API که باید موقعیت کنونی ورودی را به اندازه یک واحد کد به جلو ببرد. .TP .B \fBYYBACKUP\fP یک پریمیتیو از Generic API که باید موقعیت کنونی ورودی را ذخیره کند (تا بعداً با \fBYYRESTORE\fP بازیابی شود). .TP .B \fBYYRESTORE\fP یک پریمیتیو از Generic API که باید موقعیت کنونی ورودی را به مقدار ذخیره‌شده توسط \fBYYBACKUP\fP بازیابی کند. .TP .B \fBYYBACKUPCTX\fP یک پریمیتیو از Generic API که باید موقعیت کنونی ورودی را به عنوان موقعیت زمینه دنباله‌دار ذخیره کند (تا بعداً با \fBYYRESTORECTX\fP بازیابی شود). .TP .B \fBYYRESTORECTX\fP یک پریمیتیو از Generic API که باید موقعیت زمینه دنباله‌دارِ ذخیره‌شده با \fBYYBACKUPCTX\fP را بازیابی کند..TP .B \fBYYRESTORETAG\fP یک عنصر پایه عمومی API با یک متغیر \fBtag\fP که باید موقعیت بافت دنباله‌دار (trailing context) را به مقدار \fBtag\fP بازیابی کند\&. .TP .B \fBYYSTAGP\fP یک عنصر پایه عمومی API با یک متغیر \fBtag\fP، که در آن \fBtag\fP می‌تواند یک اشاره‌گر یا یک آفست در \fBYYINPUT\fP باشد (برای جزئیات به بخش استخراج تطابق فرعی رجوع کنید). \fBYYSTAGP\fP باید مقدار \fBtag\fP را برابر با موقعیت فعلی ورودی قرار دهد. .TP .B \fBYYSTAGN\fP یک عنصر پایه عمومی API با یک متغیر \fBtag\fP، که در آن \fBtag\fP می‌تواند یک اشاره‌گر یا یک آفست در \fBYYINPUT\fP باشد (برای جزئیات به بخش استخراج تطابق فرعی رجوع کنید). \fBYYSTAGN\fP باید مقدار \fBtag\fP را روی مقداری تنظیم کند که نشان‌دهنده موقعیت ورودی ناموجود باشد. .TP .B \fBYYMTAGP\fP یک عنصر پایه عمومی API با یک متغیر \fBtag\fP\&. \fBYYMTAGP\fP باید موقعیت فعلی را به تاریخچه تطابق‌های فرعی \fBtag\fP ضمیمه کند (برای جزئیات به بخش استخراج تطابق فرعی رجوع کنید). .TP .B \fBYYMTAGN\fP یک عنصر پایه عمومی API با یک متغیر \fBtag\fP\&. \fBYYMTAGN\fP باید مقداری را که نشان‌دهنده موقعیت ورودی ناموجود است به تاریخچه تطابق‌های فرعی \fBtag\fP ضمیمه کند (برای جزئیات به بخش استخراج تطابق فرعی رجوع کنید). .TP .B \fBYYSHIFT\fP یک عنصر پایه عمومی API با یک متغیر \fBshift\fP که باید موقعیت فعلی ورودی را به اندازه \fBshift\fP نویسه تغییر مکان دهد (مقدار شیفت ممکن است منفی باشد). .TP .B \fBYYCOPYSTAG\fP یک عنصر پایه عمومی API با دو متغیر \fBlhs\fP و \fBrhs\fP که باید متغیر s\-tag سمت راست، یعنی \fBrhs\fP را در متغیر s\-tag سمت چپ، یعنی \fBlhs\fP کپی کند\&. برای بیشتر زبان‌ها این عنصر پایه یک تعریف پیش‌فرض دارد که \fBlhs\fP را به \fBrhs\fP نسبت می‌دهد\&. .TP .B \fBYYCOPYMTAG\fP یک عنصر پایه عمومی API با دو متغیر \fBlhs\fP و \fBrhs\fP که باید متغیر m\-tag سمت راست، یعنی \fBrhs\fP را در متغیر m\-tag سمت چپ، یعنی \fBlhs\fP کپی کند\&. برای بیشتر زبان‌ها این عنصر پایه یک تعریف پیش‌فرض دارد که \fBlhs\fP را به \fBrhs\fP نسبت می‌دهد\&. .TP .B \fBYYSHIFTSTAG\fP یک عنصر پایه عمومی API با دو متغیر \fBtag\fP و \fBshift\fP که باید \fBtag\fP را به اندازه \fBshift\fP واحد کد (code unit) شیفت دهد (مقدار شیفت ممکن است منفی باشد). .TP .B \fBYYSHIFTMTAG\fP یک عنصر پایه عمومی API با دو متغیر \fBtag\fP و \fBshift\fP که باید آخرین مقدار در تاریخچه \fBtag\fP را به اندازه \fBshift\fP واحد کد شیفت دهد (مقدار شیفت ممکن است منفی باشد). .TP .B \fBYYMAXNMATCH\fP یک ثابت از نوع عدد صحیح برابر با بیشترین تعداد گروه‌های ضبط POSIX در یک قاعده. این ثابت با یک بلوک \fBmaxnmatch\fP تولید می‌شود. .TP .B \fBYYCONDTYPE\fP نوع شمارشی شرط (condition enum). می‌تواند با بلوک \fBconditions\fP یا گزینه \fB\-\-header\fP تولید شود. .TP .B \fBYYGETACCEPT\fP یک عنصر پایه با یک متغیر \fBvar\fP که انتخاب‌کننده عددی قاعده پذیرفته‌شده را ذخیره می‌کند. برای بیشتر زبان‌ها این عنصر پایه یک تعریف پیش‌فرض دارد که از \fBvar\fP می‌خواند\&. .TP .B \fBYYSETACCEPT\fP یک عنصر پایه با دو متغیر: \fBvar\fP (یک l\-value که انتخاب‌کننده عددی قاعده پذیرفته‌شده را ذخیره می‌کند)، و \fBval\fP (مقدار انتخاب‌کننده). برای بیشتر زبان‌ها این عنصر پایه یک تعریف پیش‌فرض دارد که \fBvar\fP را به \fBval\fP نسبت می‌دهد\&. .TP .B \fBYYGETCOND\fP یک r\-value از نوع \fBYYCONDTYPE\fP که برابر با شناسه شرط فعلی است. .TP .B \fBYYSETCOND\fP یک عنصر پایه با یک متغیر \fBcond\fP که باید شناسه شرط فعلی را به \fBcond\fP تنظیم کند\&. .TP .B \fBYYGETSTATE\fP یک r\-value از نوع عدد صحیح که برابر با وضعیت فعلی تحلیل‌گر لغوی است. باید با مقدار \fB\-1\fP مقداردهی اولیه شود\&. .TP .B \fBYYSETSTATE\fP یک عنصر پایه با یک متغیر \fBstate\fP که باید وضعیت فعلی تحلیل‌گر لغوی را روی \fBstate\fP تنظیم کند\&. .TP .B \fBYYDEBUG\fP این عنصر پایه تنها با گزینه \fB\-d\fP، \fB\-\-debug\-output\fP تولید می‌شود. هدف آن افزودن ثبت وقایع (لاگ‌گیری) به کد تولیدشده است (تعریف معمول \fBYYDEBUG\fP یک دستور چاپ است). دستورهای \fBYYDEBUG\fP در هر وضعیت تولید می‌شوند و دو متغیر دارند: \fBstate\fP (یک نمایه وضعیت DFA یا \fB\-1\fP) و \fBsymbol\fP (نماد ورودی فعلی). .TP .B \fByyaccept\fP یک l\-value از نوع عدد صحیح بدون علامت که شماره آخرین قاعده مطابقت‌یافته را ذخیره می‌کند. تعریف توسط کاربر تنها با گزینه \fB\-\-storable\-state\fP لازم است. .TP .B \fByybm\fP جدولی حاوی نگاشت‌های بیتی فشرده‌شده برای حداکثر ۸ انتقال (استفاده‌شده با گزینه \fB\-\-bitmaps\fP). جدول شامل ۲۵۶ عنصر است و با واحدهای کد ۱ بایتی اندیس‌گذاری می‌شود. هر عنصر ۸ بیتی مقادیر بولی را برای حداکثر ۸ انتقال ترکیب می‌کند. بیت k\-ام از عنصر n\-ام درست (true) است اگر و تنها اگر واحد کد n\-ام در محدوده انتقال k\-ام باشد. ایده این بیت‌مپ جایگزینی چندین شاخه \fIif\fP یا حالت \fIswitch\fP با بررسی یک بیت واحد در جدول است. .TP .B \fByych\fP یک l\-value از نوع \fBYYCTYPE\fP که نویسه ورودی فعلی را ذخیره می‌کند. تعریف توسط کاربر فقط با گزینه \fB\-f\fP \fB\-\-storable\-state\fP لازم است. .TP .B \fByyctable\fP جدول پرش تولیدشده برای هدایت شرط اولیه (با ترکیب گزینه‌های \fB\-\-conditions\fP و \fB\-\-computed\-gotos\fP فعال می‌شود). .TP .B \fByyfill\fP یک l\-value که نتیجه فراخوانی \fBYYFILL\fP را ذخیره می‌کند (این ممکن است برای زبان‌های کاملاً تابعی، جایی که \fBYYFILL\fP یک تابع مونادیک با مقدار بازگشتی پیچیده است، لازم باشد). .TP .B \fByynmatch\fP یک l\-value از نوع عدد صحیح بدون علامت که تعداد گروه‌های ضبط POSIX را در قاعده مطابقت‌یافته ذخیره می‌کند. فقط با گزینه \fB\-P\fP \fB\-\-posix\-captures\fP استفاده می‌شود. .TP .B \fByypmatch\fP آرایه‌ای از l\-valueها که برای نگهداری مقادیر برچسب متناظر با پرانتزهای ضبط‌کننده در قاعده مطابقت‌یافته به کار می‌روند. طول آرایه باید حداقل \fByynmatch * 2\fP باشد (معمولاً \fBYYMAXNMATCH * 2\fP انتخاب مناسبی است). فقط با گزینه \fB\-P\fP \fB\-\-posix\-captures\fP استفاده می‌شود. .TP .B \fByystable\fP منسوخ شده است. .TP .B \fByystate\fP یک l\-value که همراه با گزینه \fB\-\-loop\-switch\fP برای ذخیره وضعیت فعلی DFA استفاده می‌شود. .TP .B \fByytarget\fP جدول پرشی که شامل مقصدهای پرش (نشانی‌های برچسب) برای همه انتقال‌ها از یک وضعیت است. این جدول برای هر وضعیت محلی است. تولید جدول‌های \fByytarget\fP با گزینه \fB\-\-computed\-gotos\fP فعال می‌شود. .UNINDENT.SS "گزینه‌ها (OPTIONS)" .sp برخی از گزینه‌ها دارای \fI\%پیکربندی‌های\fP متناظر هستند، برخی دیگر سراسری بوده و پس از شروع خواندن فایل ورودی توسط re2c قابل تغییر نیستند. گزینه‌های اشکال‌زدایی عموماً نیازمند ساخت re2c در پیکربندی اشکال‌زدایی هستند. گزینه‌های داخلی برای آزمایش الگوریتم‌های استفاده‌شده در re2c مفید هستند. .INDENT 0.0 .TP .B \fB\-? \-\-help \-h\fP نمایش پیام راهنما. .TP .B \fB\-\-api \fP مشخص کردن API استفاده‌شده توسط کد تولیدشده برای برقراری ارتباط با کد تعریف‌شده توسط کاربر. گزینهٔ \fBsimple\fP باید در موارد ساده که نیازی به پر کردن مجدد بافر و ذخیرهٔ وضعیت لکسر نیست استفاده شود. گزینهٔ \fBrecord\fP باید زمانی استفاده شود که وضعیت لکسر باید در یک رکورد (struct، class و غیره) ذخیره شود. گزینهٔ \fBgeneric\fP باید در موارد پیچیده‌ای استفاده شود که دو API دیگر به اندازهٔ کافی انعطاف‌پذیر نیستند. .TP .B \fB\-\-bit\-vectors \-b\fP بهینه‌سازی پرش‌های شرطی با استفاده از ماسک‌های بیت. این گزینه به طور ضمنی \fB\-\-nested\-ifs\fP را فعال می‌کند\&. .TP .B \fB\-\-captures\fP, \fB\-\-leftmost\-captures\fP فعال‌سازی استخراج تطبیق‌های فرعی با گروه‌های گیرندهٔ حریصانهٔ چپ‌ترین. نتیجه در یک آرایه به نام \fByybmatch\fP با ظرفیت \fB2 * YYMAXNMATCH\fP جمع‌آوری می‌شود و \fByynmatch\fP روی تعداد گروه‌ها برای قاعدهٔ تطبیق‌یافته تنظیم می‌گردد. .TP .B \fB\-\-captvars\fP, \fB\-\-leftmost\-captvars\fP فعال‌سازی استخراج تطبیق‌های فرعی با گروه‌های گیرندهٔ حریصانهٔ چپ‌ترین. نتیجه برای \fBk\fP\-امین گروه گیرنده در متغیرهای \fByytl\fP و \fByytr\fP جمع‌آوری می‌شود. .TP .B \fB\-\-case\-insensitive\fP در نظر گرفتن رشته‌های درون نقل‌قول تکی و دوگانه به صورت غیرحساس به حروف کوچک و بزرگ. .TP .B \fB\-\-case\-inverted\fP معکوس کردن مفهوم رشته‌های درون نقل‌قول تکی و دوگانه: در نظر گرفتن رشته‌های درون نقل‌قول تکی به صورت حساس به حروف و رشته‌های درون نقل‌قول دوگانه به صورت غیرحساس به حروف. .TP .B \fB\-\-case\-ranges\fP تجمیع موارد متوالی در دستورهای switch به یک بازه به شکل \fBlow ... high\fP\&. این نحو یک افزونهٔ زبان C/C++ است که توسط کامپایلرهایی مانند GCC، Clang و Tcc پشتیبانی می‌شود. مزیت اصلی نسبت به استفاده از موارد تکی، تولید کد کوچک‌تر و زمان تولید سریع‌تر است، اگرچه برای برخی کامپایلرها مانند Tcc منجر به اندازهٔ باینری کوچک‌تر نیز می‌شود. .TP .B \fB\-\-computed\-gotos \-g\fP بهینه‌سازی پرش‌های شرطی با استفاده از افزونهٔ غیراستاندارد \(dqcomputed goto\(dq (که باید توسط کامپایلر پشتیبانی شود). برنامهٔ re2java جداول پرش را تنها در موارد پیچیده با شاخه‌های شرطی فراوان تولید می‌کند. آستانهٔ پیچیدگی را می‌توان با پیکربندی \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: چندین لکسر مرتبط با یکدیگر در یک بلوک واحد. این یک جایگزین برای مشخص کردن دستی بلوک‌های مختلف re2java است که با \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 می‌خواند. re2java فرض می‌کند که محدودهٔ نویسه‌ها 0 \-\- 0xFF و اندازهٔ نویسه ۱ بایت است. .TP .B \fB\-\-empty\-class \fP تعریف نحوهٔ برخورد re2java با کلاس‌های نویسهٔ خالی. با \fBmatch\-empty\fP (پیش‌فرض)، کلاس خالی با ورودی خالی تطبیق می‌یابد (که غیرمنطقی است، اما با نسخه‌های پیشین سازگار است). با \fBmatch\-none\fP کلاس خالی همیشه در تطبیق ناموفق است. با \fBerror\fP کلاس خالی خطای کامپایل ایجاد می‌کند. .TP .B \fB\-\-encoding\-policy \fP تعریف نحوهٔ برخورد re2java با جانشین‌های یونیکد (Unicode surrogates). با \fBfail\fP برنامهٔ re2java در صورت مواجهه با یک جانشین با خطا متوقف می‌شود. با \fBsubstitute\fP برنامهٔ re2java بدون اخطار جانشین‌ها را با نقطه کد خطای 0xFFFD جایگزین می‌کند. با \fBignore\fP (پیش‌فرض) re2java با جانشین‌ها مانند نقاط کد معمولی رفتار می‌کند. استاندارد یونیکد بیان می‌کند که جانشین‌های مستقل نامعتبر هستند، اما کتابخانه‌ها و برنامه‌ها در دنیای واقعی رفتارهای متفاوتی نشان می‌دهند. .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 مشخص کرد\&. در صورت استفاده از شرایط، شمارشگر شرایط (condition enum) به‌طور خودکار به انتهای هدر تولیدشده اضافه می‌شود (مگر اینکه بلوک صریح \fBconditions\fP وجود داشته باشد). .TP .B \fB\-I PATH\fP افزودن \fBPATH\fP به فهرست مکان‌هایی که هنگام جستجوی فایل‌های include استفاده می‌شوند. این گزینه در ترکیب با بلوک یا دستورالعمل \fBinclude\fP مفید است. re2java به دنبال \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 مشخص کردن نحوهٔ تجزیهٔ عبارت‌های منظم توسط re2java. با \fBascii\fP (پیش‌فرض) re2java ورودی را با کدگذاری ASCII در نظر می‌گیرد: هر دنباله‌ای از واحدهای کد، دنباله‌ای از نویسه‌های مستقل ۱ بایتی است. با \fButf8\fP برنامهٔ re2java ورودی را با کدگذاری UTF8 در نظر گرفته و نویسه‌های چندبایتی را تشخیص می‌دهد. .TP .B \fB\-\-invert\-captures\fP معکوس کردن مفهوم گروه‌های گیرنده (capturing) و غیرگیرنده. به صورت پیش‌فرض \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، به طوری که حالت‌های منفرد همان موارد دستور switch هستند. وضعیت در یک متغیر به نام \fByystate\fP ذخیره می‌شود\&. انتقال‌های میان حالت‌ها، \fByystate\fP را به برچسب مورد مربوط به حالت مقصد به‌روزرسانی کرده و اجرا را به ابتدای حلقه ادامه می‌دهند. .TP .B \fB\-\-nested\-ifs \-s\fP استفاده از دستورهای شرطی \fBif\fP تو در تو به جای دستورهای \fBswitch\fP در پرش‌های شرطی. این کار معمولاً در کامپایلرهای بدون بهینه‌سازی منجر به ایجاد کد کارآمدتری می‌شود. .TP .B \fB\-\-no\-debug\-info \-i\fP عدم چاپ دستورالعمل‌های خط (line directives). این گزینه می‌تواند در زمانی که کد تولیدشده در یک سامانهٔ کنترل نسخه ذخیره می‌شود مفید باشد (برای جلوگیری از تفاوت‌های حجیم ناشی از تغییرات کوچک). .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 باید از بررسی محدوده خودداری کند، زیرا لکسر از قبل بررسی‌های پایان ورودی را به روشی کارآمدتر انجام می‌دهد. کاربر می‌تواند یک تعریف ایمن برای \fBYYPEEK\fP ارائه دهد، یا تعریفی که تنها در ساخت‌های release ناامن باشد، که در این حالت گزینهٔ \fB\-\-no\-unsafe\fP به جلوگیری از هشدارهای مربوط به بلوک‌های اضافی \fBunsafe\fP کمک می‌کند. .TP .B \fB\-\-output \-o OUTPUT\fP مشخص کردن فایل خروجی \fBOUTPUT\fP. .TP .B \fB\-\-posix\-captures\fP, \fB\-P\fP فعال‌سازی استخراج تطبیق‌های فرعی با گروه‌های گیرنده به سبک POSIX. نتیجه در یک آرایه به نام \fByybmatch\fP با ظرفیت \fB2 * YYMAXNMATCH\fP جمع‌آوری می‌شود و \fByynmatch\fP روی تعداد گروه‌ها برای قاعدهٔ تطبیق‌یافته تنظیم می‌گردد..TP .B \fB\-\-posix\-captvars\fP فعال‌سازی استخراج زیرتطبیق با گروه‌های گیرانداز به سبک POSIX. نتیجه برای \fBk\fP\-امین گروه گیرانداز در متغیرهای \fByytl\fP و \fByytr\fP جمع‌آوری می‌شود. .TP .B \fB\-\-recursive\-functions\fP استفاده از مدل کد مبتنی بر توابع هم‌بازگشتی، که در آن هر وضعیت DFA یک تابع مجزا است که می‌تواند توابع وضعیت‌های دیگر یا خودش را فراخوانی کند. .TP .B \fB\-\-reusable \-r\fP از نسخه 2.2 منسوخ شده است (بلوک‌های قابل استفاده مجدد اکنون به‌طور پیش‌فرض مجاز هستند). .TP .B \fB\-\-skeleton \-S\fP نادیده‌گرفتن کد رابط تعریف‌شده توسط کاربر و تولید یک برنامه مستقل «اسکلتی» (\(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 را می‌خواند. re2java فرض می‌کند که محدوده نویسه‌ها 0 \-\- 0xFFFF و اندازه نویسه ۲ بایت است. این گزینه مستلزم \fB\-\-nested\-ifs\fP است\&. .TP .B \fB\-\-utf8 \-\-utf\-8 \-8\fP تولید تحلیل‌گری که ورودی را با کدگذاری UTF\-8 می‌خواند. re2java فرض می‌کند که محدوده نویسه‌ها 0 \-\- 0x10FFFF و اندازه نویسه ۱ بایت است. .TP .B \fB\-\-utf16 \-\-utf\-16 \-x\fP تولید تحلیل‌گری که ورودی کدگذاری‌شده با UTF16 را می‌خواند. re2java فرض می‌کند که محدوده نویسه‌ها 0 \-\- 0x10FFFF و اندازه نویسه ۲ بایت است. این گزینه مستلزم \fB\-\-nested\-ifs\fP است\&. .TP .B \fB\-\-utf32 \-\-unicode \-u\fP تولید تحلیل‌گری که ورودی کدگذاری‌شده با UTF32 را می‌خواند. re2java فرض می‌کند که محدوده نویسه‌ها 0 \-\- 0x10FFFF و اندازه نویسه ۴ بایت است. این گزینه مستلزم \fB\-\-nested\-ifs\fP است\&. .TP .B \fB\-\-verbose\fP نمایش یک پیام کوتاه در صورت موفقیت. .TP .B \fB\-\-vernum \-V\fP نمایش اطلاعات نسخه در قالب \fBMMmmpp\fP (اصلی، فرعی، وصله). .TP .B \fB\-\-version \-v\fP نمایش اطلاعات نسخه. .TP .B \fB\-\-single\-pass \-1\fP منسوخ شده است. کاری انجام نمی‌دهد (حالت تک‌گذره اکنون پیش‌فرض است). .UNINDENT .INDENT 0.0 .TP .B \fB\-\-debug\-output \-d\fP درج فراخوانی‌های \fBYYDEBUG\fP در کد تولیدشده. این گزینه برای ردگیری اجرای تحلیل‌گر لغوی مفید است. .TP .B \fB\-\-dump\-adfa\fP گزینه اشکال‌زدایی: خروجی DFA پس از تونل‌زنی (به قالب .dot). .TP .B \fB\-\-dump\-cfg\fP گزینه اشکال‌زدایی: خروجی گراف جریان کنترل برای متغیرهای تگ (به قالب .dot). .TP .B \fB\-\-dump\-closure\-stats\fP گزینه اشکال‌زدایی: خروجی آمار تعداد وضعیت‌ها در بستار (closure). .TP .B \fB\-\-dump\-dfa\-det\fP گزینه اشکال‌زدایی: خروجی DFA بلافاصله پس از قطعی‌سازی (به قالب .dot). .TP .B \fB\-\-dump\-dfa\-min\fP گزینه اشکال‌زدایی: خروجی DFA پس از کمینه‌سازی (به قالب .dot). .TP .B \fB\-\-dump\-dfa\-tagopt\fP گزینه اشکال‌زدایی: خروجی DFA پس از بهینه‌سازی‌های تگ (به قالب .dot). .TP .B \fB\-\-dump\-dfa\-tree\fP گزینه اشکال‌زدایی: خروجی DFA در حال ساخت با وضعیت‌هایی که به شکل درخت‌های تاریخچه تگ نمایش داده شده‌اند (به قالب .dot). .TP .B \fB\-\-dump\-dfa\-raw\fP گزینه اشکال‌زدایی: خروجی DFA در حال ساخت با مجموعه‌وضعیت‌های بسط‌یافته (به قالب .dot). .TP .B \fB\-\-dump\-interf\fP گزینه اشکال‌زدایی: خروجی جدول تداخل حاصل از تحلیل پویایی متغیرهای تگ. .TP .B \fB\-\-dump\-nfa\fP گزینه اشکال‌زدایی: خروجی NFA (به قالب .dot). .TP .B \fB\-\-emit\-dot \-D\fP تولید گراف تحلیل‌گر به قالب .dot به جای خروجی عادی. این خروجی را می‌توان به کمک Graphviz به یک تصویر تبدیل کرد (برای مثال فرمانی مانند \fBdot \-Tpng \-odfa.png dfa.dot\fP). .UNINDENT .INDENT 0.0 .TP .B \fB\-\-dfa\-minimization \fP گزینه درونی: الگوریتم کمینه‌سازی DFA مورد استفاده توسط re2java\&. گزینه \fBmoore\fP الگوریتم مور است (گزینه پیش‌فرض). گزینه \fBtable\fP الگوریتم «پر کردن جدول» (\(dqtable filling\(dq) است. هر دو الگوریتم باید صرف‌نظر از برچسب‌گذاری مجدد وضعیت‌ها DFA یکسانی تولید کنند؛ پر کردن جدول ساده‌تر و بسیار کندتر است و به عنوان یک پیاده‌سازی مرجع به کار می‌رود. .TP .B \fB\-\-eager\-skip\fP گزینه درونی: واداشتن تحلیل‌گر لغوی تولیدشده به پیش بردن سریع موقعیت ورودی \-\- بلافاصله پس از خواندن نماد ورودی. این کار رفتار پیش‌فرض را تغییر می‌دهد که در آن موقعیت ورودی با تاخیر (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 نشان‌دهنده الگوریتم «ترتیب توپولوژیکی سراسری» (\(dqglobal topological order\(dq) است. .TP .B \fB\-\-posix\-prectable \fP گزینه درونی: تعیین الگوریتم مورد استفاده برای محاسبه جدول اولویت POSIX. الگوریتم \fBcomplex\fP جدول اولویت را در یک پیمایش از درخت تاریخچه تگ محاسبه می‌کند و از نظر تعداد وضعیت‌های TNFA دارای پیچیدگی درجه دو است؛ این گزینه پیش‌فرض می‌باشد. الگوریتم \fBnaive\fP در بدترین حالت دارای پیچیدگی درجه سه بر حسب تعداد وضعیت‌های TNFA است، اما بسیار ساده‌تر از \fBcomplex\fP بوده و ممکن است در موارد غیربحرانی کمی سریع‌تر باشد. .TP .B \fB\-\-stadfa\fP گزینه درونی، منسوخ شده است. در گذشته برای فعال‌سازی الگوریتم staDFA استفاده می‌شد، که تفاوت آن با TDFA در این است که عملیات‌های ثبات به جای گذارها، در وضعیت‌ها قرار می‌گیرند. ارزیابی‌ها نشان دادند که کارایی الگوریتم staDFA کمتر از TDFA است. .TP .B \fB\-\-fixed\-tags \fP گزینه درونی: مشخص می‌کند که آیا بهینه‌سازی تگ ثابت باید برای همه تگ‌ها (\fBall\fP)، هیچ‌کدام از آن‌ها (\fBnone\fP)، یا فقط تگ‌های موجود در الحاق بالاترین سطح (\fBtoplevel\fP) اعمال شود یا خیر. مقدار پیش‌فرض \fBall\fP است\&. تگ‌های «ثابت» (\(dqFixed\(dq) تگ‌هایی هستند که در فاصله‌ای ثابت نسبت به یک تگ دیگر (به نام «پایه» یا \(dqbase\(dq) قرار دارند. در چنین مواردی تنها تگ پایه نیاز به ردیابی دارد و مقدار تگ ثابت می‌تواند از مجموع مقدار تگ پایه به علاوه یک آفست ایستا محاسبه شود. برای تگ‌هایی که تحت گزینش یا تکرار قرار دارند نیز لازم است بررسی شود که آیا تگ پایه دارای مقدار عدم‌تطبیق است یا خیر (در این صورت تگ ثابت نیز باید بدون در نظر گرفتن آفست، روی عدم‌تطبیق تنظیم شود). برای تگ‌های موجود در الحاق بالاترین سطح به این بررسی نیازی نیست، زیرا آن‌ها همواره مطابقت دارند. .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 اگر یک عبارت باقاعده حاوی یک کلاس نویسهٔ خالی باشد، هشدار می‌دهد. تلاش برای تطبیق یک کلاس نویسهٔ خالی بی‌معنی است: این عمل همواره باید ناموفق باشد. با این حال، به دلایل سازگاری با نسخه‌های پیشین، re2java کلاس‌های نویسهٔ خالی را مجاز دانسته و با آن‌ها مانند رشته‌های خالی رفتار می‌کند. از گزینهٔ \fB\-\-empty\-class\fP برای تغییر رفتار پیش‌فرض استفاده کنید. .TP .B \fB\-Wmatch\-empty\-string\fP اگر قاعده‌ای پوچ‌پذیر باشد (با یک رشتهٔ خالی تطبیق یابد)، هشدار می‌دهد. اگر تحلیل‌گر واژگانی در یک حلقه اجرا شود و تطبیق تهی غیرعمدی باشد، ممکن است تحلیل‌گر به‌طور غیرمنتظره‌ای در یک حلقهٔ بی‌نهایت متوقف شود. .TP .B \fB\-Wswapped\-range\fP اگر حد پایین یک بازه بزرگ‌تر از حد بالای آن باشد، هشدار می‌دهد. رفتار پیش‌فرض این است که بدون هیچ پیامی جای حدود بازه تعویض می‌شود. .TP .B \fB\-Wundefined\-control\-flow\fP اگر برخی از رشته‌های ورودی باعث جریان کنترل تعریف‌نشده در تحلیل‌گر واژگانی شوند (الگوهای معیوب گزارش می‌شوند)، هشدار می‌دهد. این یک اشتباه رایج و خطرناک است. این مشکل را می‌توان به‌راحتی با افزودن قاعدهٔ پیش‌فرض \fB*\fP برطرف کرد که کمترین اولویت را دارد، با هر واحد کد تطبیق می‌یابد و همیشه یک واحد کد را مصرف می‌کند. .TP .B \fB\-Wunreachable\-rules\fP در مورد قاعده‌هایی که تحت‌الشعاع قاعده‌های دیگر قرار گرفته‌اند و هرگز تطبیق نخواهند یافت، هشدار می‌دهد. .TP .B \fB\-Wdeprecated\-eof_rule\fP در مورد قاعده‌های مستقل پایان ورودی \fB$\fP که با تغییرات آینده شکسته خواهند شد و نیاز به اصلاح دارند، هشدار می‌دهد. در حال حاضر، این قاعده‌ها هنگام تداخل با قاعده‌های دیگر اولویت دارند، اما پس از معرفی نماد تعمیم‌یافتهٔ پایان ورودی \fB$\fP، ترتیب اولویت تغییر خواهد کرد و این قاعده‌ها تحت‌الشعاع دیگر قاعده‌ها قرار خواهند گرفت. .TP .B \fB\-Wuseless\-escape\fP اگر نویسه‌ای در جایی که نباید، گریز داده شود (escape شود)، هشدار می‌دهد. به‌طور پیش‌فرض، re2java چنین نویسه‌های گریزی را بدون هشدار نادیده می‌گیرد، اما این مورد می‌تواند نشان‌دهندهٔ یک غلط تایپی یا خطا در توالی گریز باشد. .TP .B \fB\-Wnondeterministic\-tags\fP اگر یک برچسب دارای درجهٔ \fBn\fP\-ام از غیرقطعی بودن باشد، به طوری که \fBn\fP بزرگ‌تر از ۱ باشد، هشدار می‌دهد. .TP .B \fB\-Wsentinel\-in\-midrule\fP اگر نماد دیده‌بان (sentinel) در میان یک قاعده رخ دهد، هشدار می‌دهد \-\-\- این امر ممکن است باعث خواندن فراتر از انتهای بافر، خرابی‌ها یا فساد حافظه در تحلیل‌گر واژگانی تولیدشده شود. این هشدار تنها زمانی کاربرد دارد که روش دیده‌بان برای بررسی پایان ورودی استفاده شود. اگر از پیکربندی \fBre2c:sentinel\fP استفاده شود، این مورد به عنوان خطا تلقی می‌شود. .TP .B \fB\-Wundefined\-syntax\-config\fP اگر فایل نحو (syntax file) مشخص‌شده با گزینهٔ \fB\-\-syntax\fP فاقد تعاریف برخی از پیکربندی‌ها باشد، هشدار می‌دهد. این امر به نگهداری فایل‌های نحو تعریف‌شده توسط کاربر کمک می‌کند: اگر نسخهٔ جدیدی پیکربندی‌هایی را اضافه کند، فایل نحو قدیمی هشداری صادر کرده و به کاربر اطلاع داده خواهد شد. اگر برخی از پیکربندی‌ها استفاده نمی‌شوند و نیازی به تعریف ندارند، باید به‌طور صریح روی \fB\fP تنظیم شوند. .UNINDENT.SS "فایل‌های نحو (Syntax files)" .sp پشتیبانی از زبان‌های گوناگون در re2c بر پایه ایده \fIفایل‌های نحو\fP استوار است\&. یک فایل نحو، فایلی پیکربندی است که نحو زبان هدف را تعریف می‌کند \-\- نه کل زبان، بلکه بخش کوچکی از آن را که توسط کد تولیدشده استفاده می‌شود. فایل‌های نحو re2c را بسیار انعطاف‌پذیر می‌کنند، اما نباید به عنوان جایگزینی برای پیکربندی‌های \fBre2c:\fP استفاده شوند: هدف آن‌ها تعریف نحو زبان هدف است، نه سفارشی‌سازی یک لکسر خاص. همه زبان‌های پشتیبانی‌شده دارای فایل‌های نحو پیش‌فرضی هستند که بخشی از توزیع برنامه می‌باشند (پوشه فرعی \fBinclude/syntax\fP را ببینید)؛ آن‌ها همچنین در باینری re2java تعبیه شده‌اند. کاربران می‌توانند یک فایل نحو سفارشی ارائه دهند که چند پیکربندی را برای یکی از زبان‌های پشتیبانی‌شده بازنویسی کند، یا می‌توانند همه پیکربندی‌ها را از نو تعریف کنند (در آن حالت باید از گزینه \fB\-\-lang none\fP استفاده شود). فایل‌های نحو شامل پیکربندی‌هایی در چهار نوع مختلف هستند: فهرست‌های ویژگی، پیکربندی‌های زبان، پیکربندی‌های درجا و الگوهای کد. .sp \fBفهرست‌های ویژگی (Feature lists)\fP .INDENT 0.0 .INDENT 3.5 چندین پیکربندی از نوع فهرست، ویژگی‌های گوناگون پشتیبانی‌شده توسط یک بک‌اند مشخص را تعریف می‌کنند تا در صورتی که کاربر برای فعال‌سازی یک ویژگی پشتیبانی‌نشده تلاش کند، re2java بتواند خطای واضحی صادر کند: .INDENT 0.0 .TP .B \fBsupported_apis\fP فهرستی از APIهای پشتیبانی‌شده با عناصر ممکن \fBsimple\fP، \fBrecord\fP و \fBgeneric\fP\&. .TP .B \fBsupported_api_styles\fP فهرستی از شیوه‌های API پشتیبانی‌شده با عناصر ممکن \fBfunctions\fP و \fBfree\-form\fP\&. .TP .B \fBsupported_code_models\fP فهرستی از مدل‌های کد پشتیبانی‌شده با عناصر ممکن \fBgoto\-label\fP، \fBloop\-switch\fP و \fBrecursive\-functions\fP\&. .TP .B \fBsupported_targets\fP فهرستی از مقصدهای تولید کد پشتیبانی‌شده با عناصر ممکن \fBcode\fP، \fBdot\fP و \fBskeleton\fP\&. .TP .B \fBsupported_features\fP فهرستی از ویژگی‌های پشتیبانی‌شده با عناصر ممکن \fBnested\-ifs\fP، \fBbitmaps\fP، \fBcomputed\-gotos\fP، \fBcase\-ranges\fP، \fBmonadic\fP، \fBunsafe\fP، \fBtags\fP، \fBcaptures\fP و \fBcaptvars\fP\&. .UNINDENT .UNINDENT .UNINDENT .sp \fBپیکربندی‌های زبان (Language configurations)\fP .INDENT 0.0 .INDENT 3.5 چندین پیکربندی بولی ویژگی‌هایی از زبان هدف را توصیف می‌کنند که بر تجزیه‌کننده و تولیدکننده کد re2java اثر می‌گذارند: .INDENT 0.0 .TP .B \fBsemicolons\fP غیر صفر اگر زبان پس از دستورات از نقطه‌ویرگول استفاده می‌کند. .TP .B \fBbacktick_quoted_strings\fP غیر صفر اگر زبان دارای رشته‌های محصور در بک‌تیک است. .TP .B \fBsingle_quoted_strings\fP غیر صفر اگر زبان دارای رشته‌های محصور در تک‌کوتیشن است. .TP .B \fBindentation_sensitive\fP غیر صفر اگر زبان به تورفتگی حساس است. .TP .B \fBwrap_blocks_in_braces\fP غیر صفر اگر دستورات مرکب باید در آکولاد محصور شوند. .UNINDENT .UNINDENT .UNINDENT .sp \fBپیکربندی‌های درجا (Inplace configurations)\fP .INDENT 0.0 .INDENT 3.5 فایل‌های نحو مقادیر اولیه تمام پیکربندی‌های \fBre2c:\fP را تعیین می‌کنند، چرا که ممکن است این مقادیر برای زبان‌های مختلف متفاوت باشند. برای فهرست کاملی از تمام پیکربندی‌های درجا و معنای آن‌ها، بخش پیکربندی‌ها را ببینید. .UNINDENT .UNINDENT .sp \fBالگوهای کد (Code templates)\fP .INDENT 0.0 .INDENT 3.5 الگوهای کد، نحو زبان هدف را تعریف می‌کنند. آن‌ها در یک زبان ساده خاص دامنه با گرامر صوری زیر نوشته می‌شوند: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C code\-template :: name \(aq=\(aq code\-exprs \(aq;\(aq | CODE_TEMPLATE \(aq;\(aq | \(aq\(aq \(aq;\(aq code\-exprs :: | code\-exprs code\-expr code\-expr :: STRING | VARIABLE | optional | list optional :: \(aq(\(aq CONDITIONAL \(aq?\(aq code\-exprs \(aq)\(aq | \(aq(\(aq CONDITIONAL \(aq?\(aq code\-exprs \(aq:\(aq code\-exprs \(aq)\(aq list :: \(aq[\(aq VARIABLE \(aq:\(aq code\-exprs \(aq]\(aq | \(aq[\(aq VARIABLE \(aq{\(aq NUMBER \(aq}\(aq \(aq:\(aq code\-exprs \(aq]\(aq | \(aq[\(aq VARIABLE \(aq{\(aq NUMBER \(aq,\(aq NUMBER \(aq}\(aq \(aq:\(aq code\-exprs \(aq]\(aq .ft P .fi .UNINDENT .UNINDENT .sp یک الگوی کد، دنباله‌ای از رشته‌های لفظی، متغیرها، عناصر اختیاری و فهرست‌ها است، یا ارجاعی به یک الگوی کد دیگر، یا مقدار ویژه \fB\fP\&. متغیرها جانگهدارنده‌هایی هستند که در طول مرحله تولید کد جایگزین می‌شوند. متغیرهای فهرستی خاص هستند: هنگام بسط دادن الگوهای فهرستی، re2java عبارات سمت راست دونقطه را چند بار تکرار می‌کند، و هر بار رخدادهای متغیر فهرستی را با مقداری مختص به این تکرار جایگزین می‌سازد. فهرست‌ها دارای کران‌های اختیاری هستند (مقادیر منفی از انتها شمارش می‌شوند، برای نمونه \fB\-1\fP به معنای عنصر آخر است). نام‌های شرطی با یک نقطه شروع می‌شوند. هم شرط‌ها و هم متغیرها می‌توانند محلی (مختص به الگوی کد داده‌شده) یا سراسری (مجاز در تمام الگوهای کد) باشند. هنگامی که re2java یک فایل نحو را می‌خواند، بررسی می‌کند که هر الگوی کد تنها از متغیرها و شرط‌هایی استفاده کند که در آن مجاز هستند. .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 در اینجا فهرستی از تمام الگوهای کد پشتیبانی‌شده توسط re2java همراه با متغیرها و شرط‌های محلی آن‌ها آورده شده است. توجه داشته باشید که یک تعریف خاص می‌تواند، اما ملزم نیست که از متغیرها و شرط‌های محلی استفاده کند. هر الگوی کد استفاده‌نشده باید روی \fB\fP تنظیم شود. .INDENT 0.0.TP .B \fBcode:var_local\fP اعلان یا تعریف یک متغیر محلی. متغیرهای پشتیبانی‌شده: \fBtype\fP (نوع متغیر)، \fBname\fP (نام آن) و \fBinit\fP (مقدار اولیه، در صورت وجود). شرط‌ها: \fB\&.init\fP (اگر یک مقداردهندهٔ اولیه وجود داشته باشد، درست است). .TP .B \fBcode:var_global\fP مشابه \fBcode:var_local\fP، با این تفاوت که در سطح بالا (top\-level) استفاده می‌شود. .TP .B \fBcode:const_local\fP تعریف یک مقدار ثابت محلی. متغیرهای پشتیبانی‌شده: \fBtype\fP (نوع مقدار ثابت)، \fBname\fP (نام آن) و \fBinit\fP (مقدار اولیه). .TP .B \fBcode:const_global\fP مشابه \fBcode:const_local\fP، با این تفاوت که در سطح بالا (top\-level) استفاده می‌شود. .TP .B \fBcode:array_local\fP تعریف یک آرایهٔ محلی (جدول). متغیرهای پشتیبانی‌شده: \fBtype\fP (نوع عناصر آرایه)، \fBname\fP (نام آرایه)، \fBsize\fP (اندازهٔ آن)، \fBrow\fP (یک متغیر فهرستی که به خودی خود هیچ کدی تولید نمی‌کند، اما عبارت فهرست را به تعداد سطرهای جدول بسط می‌دهد) و \fBelem\fP (یک متغیر فهرستی که به تمام عناصر جدول در سطر فعلی بسط می‌یابد \-\- هدف آن قرارگیری به‌صورت تو در تو در فهرست \fBrow\fP است). شرط پشتیبانی‌شده: \fB\&.const\fP (اگر آرایه تغییرناپذیر باشد، درست است). .TP .B \fBcode:array_global\fP مشابه \fBcode:array_local\fP، با این تفاوت که در سطح بالا (top\-level) استفاده می‌شود. .TP .B \fBcode:array_elem\fP ارجاع به عنصری از یک آرایه (جدول). متغیرهای پشتیبانی‌شده: \fBarray\fP (نام آرایه) و \fBindex\fP (شاخص عنصر). .TP .B \fBcode:enum\fP تعریف یک شمارشگر (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 عملگر \(dqمساوی\(dq. .TP .B \fBcode:cmp_ne\fP عملگر \(dqنامساوی\(dq. .TP .B \fBcode:cmp_lt\fP عملگر \(dqکوچک‌تر از\(dq. .TP .B \fBcode:cmp_gt\fP عملگر \(dqبزرگ‌تر از\(dq. .TP .B \fBcode:cmp_le\fP عملگر \(dqکوچک‌تر یا مساوی\(dq. .TP .B \fBcode:cmp_ge\fP عملگر \(dqبزرگ‌تر یا مساوی\(dq. .TP .B \fBcode:if_then_else\fP دستور if\-then\-else با یک یا چند شاخه. متغیرهای پشتیبانی‌شده: \fBbranch\fP (یک متغیر فهرستی که به خودی خود هیچ کدی تولید نمی‌کند، اما عبارت فهرست را به تعداد شاخه‌ها بسط می‌دهد)، \fBcond\fP (شرط شاخهٔ فعلی) و \fBstmt\fP (یک متغیر فهرستی که به تمامی دستورهای شاخهٔ فعلی بسط می‌یابد). شرط‌ها: \fB\&.cond\fP (اگر شاخهٔ فعلی شرطی داشته باشد، درست است)، \fB\&.many\fP (اگر بیش از یک شاخه وجود داشته باشد، درست است). .TP .B \fBcode:if_then_else_oneline\fP حالت خاصی از \fBcode:if_then_else\fP برای حالتی که تمام شاخه‌ها دارای دستورهای تک‌خطی باشند. اگر این مقدار برابر با \fB\fP باشد، در عوض از \fBcode:if_then_else\fP استفاده می‌شود. .TP .B \fBcode:switch\fP یک دستور switch با یک یا چند مورد (case). متغیرهای پشتیبانی‌شده: \fBexpr\fP (عبارتی که switch روی آن انجام می‌شود) و \fBcase\fP (یک متغیر فهرستی که به تمامی گروه‌های case به همراه بلوک‌های کدشان بسط می‌یابد). .TP .B \fBcode:switch_cases\fP گروهی از 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 (اگر این یک تابع غیر تهی (non\-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 (اگر این یک تابع غیر تهی (non\-void) باشد، درست است). .TP .B \fBcode:recursive_functions\fP بدنهٔ برنامه با مدل کد \fB\-\-recursive\-functions\fP. متغیرهای پشتیبانی‌شده: \fBfn\fP (یک متغیر فهرستی که به خودی خود هیچ کدی تولید نمی‌کند، اما عبارت فهرست را به تعداد توابع بسط می‌دهد)، \fBfndecl\fP (اعلان تابع فعلی) و \fBfndef\fP (تعریف تابع فعلی)..TP .B \fBcode:fingerprint\fP اثرانگشت در بالای فایل خروجی تولیدشده. متغیرهای پشتیبانی‌شده: \fBver\fP (نسخهٔ re2java که برای تولید آن استفاده شده) و \fBdate\fP (تاریخ تولید). .TP .B \fBcode:line_info\fP قالب دستورالعمل‌های خط (اگر روی \fB\fP تنظیم شود، هیچ دستورالعملی تولید نمی‌شود). متغیرهای پشتیبانی‌شده: \fBline\fP (شمارهٔ خط) و \fBfile\fP (نام فایل). .TP .B \fBcode:abort\fP دستوری که اجرای برنامه را متوقف (abort) می‌کند. .TP .B \fBcode:yydebug\fP دستور \fBYYDEBUG\fP، احتمالاً سفارشی‌شده برای APIهای مختلف. متغیرهای پشتیبانی‌شده: \fBYYDEBUG\fP، \fByyrecord\fP، \fByych\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBstate\fP (شمارهٔ وضعیت DFA). .TP .B \fBcode:yypeek\fP دستور \fBYYPEEK\fP، احتمالاً سفارشی‌شده برای APIهای مختلف. متغیرهای پشتیبانی‌شده: \fBYYPEEK\fP، \fBYYCTYPE\fP، \fBYYINPUT\fP، \fBYYCURSOR\fP، \fByyrecord\fP، \fByych\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP). شرط‌ها: \fB\&.cast\fP (در صورتی که \fBre2c:yych:conversion\fP روی مقداری غیرصفر تنظیم شده باشد، درست است). .TP .B \fBcode:yyskip\fP دستور \fBYYSKIP\fP، احتمالاً سفارشی‌شده برای APIهای مختلف. متغیرهای پشتیبانی‌شده: \fBYYSKIP\fP، \fBYYCURSOR\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP). .TP .B \fBcode:yybackup\fP دستور \fBYYBACKUP\fP، احتمالاً سفارشی‌شده برای APIهای مختلف. متغیرهای پشتیبانی‌شده: \fBYYBACKUP\fP، \fBYYCURSOR\fP، \fBYYMARKER\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP). .TP .B \fBcode:yybackupctx\fP دستور \fBYYBACKUPCTX\fP، احتمالاً سفارشی‌شده برای APIهای مختلف. متغیرهای پشتیبانی‌شده: \fBYYBACKUPCTX\fP، \fBYYCURSOR\fP، \fBYYCTXMARKER\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP). .TP .B \fBcode:yyskip_yypeek\fP دستور ترکیبی \fBcode:yyskip\fP و \fBcode:yypeek\fP (به‌طور پیش‌فرض \fBcode:yyskip\fP و به دنبال آن \fBcode:yypeek\fP). .TP .B \fBcode:yypeek_yyskip\fP دستور ترکیبی \fBcode:yypeek\fP و \fBcode:yyskip\fP (به‌طور پیش‌فرض \fBcode:yypeek\fP و به دنبال آن \fBcode:yyskip\fP). .TP .B \fBcode:yyskip_yybackup\fP دستور ترکیبی \fBcode:yyskip\fP و \fBcode:yybackup\fP (به‌طور پیش‌فرض \fBcode:yyskip\fP و به دنبال آن \fBcode:yybackup\fP). .TP .B \fBcode:yybackup_yyskip\fP دستور ترکیبی \fBcode:yybackup\fP و \fBcode:yyskip\fP (به‌طور پیش‌فرض \fBcode:yybackup\fP و به دنبال آن \fBcode:yyskip\fP). .TP .B \fBcode:yybackup_yypeek\fP دستور ترکیبی \fBcode:yybackup\fP و \fBcode:yypeek\fP (به‌طور پیش‌فرض \fBcode:yybackup\fP و به دنبال آن \fBcode:yypeek\fP). .TP .B \fBcode:yyskip_yybackup_yypeek\fP دستور ترکیبی \fBcode:yyskip\fP، \fBcode:yybackup\fP و \fBcode:yypeek\fP (به‌طور پیش‌فرض \(ga\(gacode:yyskip\(ga\(ga و به دنبال آن \fBcode:yybackup\fP و سپس \fBcode:yypeek\fP). .TP .B \fBcode:yybackup_yypeek_yyskip\fP دستور ترکیبی \fBcode:yybackup\fP، \fBcode:yypeek\fP و \fBcode:yyskip\fP (به‌طور پیش‌فرض \(ga\(gacode:yybackup\(ga\(ga و به دنبال آن \fBcode:yypeek\fP و سپس \fBcode:yyskip\fP). .TP .B \fBcode:yyrestore\fP دستور \fBYYRESTORE\fP، احتمالاً سفارشی‌شده برای APIهای مختلف. متغیرهای پشتیبانی‌شده: \fBYYRESTORE\fP، \fBYYCURSOR\fP، \fBYYMARKER\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP). .TP .B \fBcode:yyrestorectx\fP دستور \fBYYRESTORECTX\fP، احتمالاً سفارشی‌شده برای APIهای مختلف. متغیرهای پشتیبانی‌شده: \fBYYRESTORECTX\fP، \fBYYCURSOR\fP، \fBYYCTXMARKER\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP). .TP .B \fBcode:yyrestoretag\fP دستور \fBYYRESTORETAG\fP، احتمالاً سفارشی‌شده برای APIهای مختلف. متغیرهای پشتیبانی‌شده: \fBYYRESTORETAG\fP، \fBYYCURSOR\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBtag\fP (نام متغیر تگ که برای بازیابی موقعیت استفاده می‌شود). .TP .B \fBcode:yyshift\fP دستور \fBYYSHIFT\fP، احتمالاً سفارشی‌شده برای APIهای مختلف. متغیرهای پشتیبانی‌شده: \fBYYSHIFT\fP، \fBYYCURSOR\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBoffset\fP (تعداد واحدهای کد برای جابه‌جایی موقعیت فعلی). .TP .B \fBcode:yyshiftstag\fP دستور \fBYYSHIFTSTAG\fP، احتمالاً سفارشی‌شده برای APIهای مختلف. متغیرهای پشتیبانی‌شده: \fBYYSHIFTSTAG\fP، \fByyrecord\fP، \fBnegative\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBtag\fP (متغیر تگی که باید جابه‌جا شود)، \fBoffset\fP (تعداد واحدهای کد برای جابه‌جایی). شرط‌ها: \fB\&.nested\fP (در صورتی که این یک تگ تودرتو باشد درست است \-\- در این حالت مقدار آن ممکن است برابر با \fBre2c:tags:negative\fP باشد، که نباید جابه‌جا شود). .TP .B \fBcode:yyshiftmtag\fP دستور \fBYYSHIFTMTAG\fP، احتمالاً سفارشی‌شده برای APIهای مختلف. متغیرهای پشتیبانی‌شده: \fBYYSHIFTMTAG\fP (نگاشت به پیکربندی متناظر \fBre2c:\fP)، \fBtag\fP (متغیر تگی که باید جابه‌جا شود)، \fBoffset\fP (تعداد واحدهای کد برای جابه‌جایی). .TP .B \fBcode:yystagp\fP دستور \fBYYSTAGP\fP، احتمالاً سفارشی‌شده برای APIهای مختلف. متغیرهای پشتیبانی‌شده: \fBYYSTAGP\fP، \fBYYCURSOR\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBtag\fP (متغیر تگی که باید به‌روزرسانی شود). .TP .B \fBcode:yymtagp\fP دستور \fBYYMTAGP\fP، احتمالاً سفارشی‌شده برای APIهای مختلف. متغیرهای پشتیبانی‌شده: \fBYYMTAGP\fP (نگاشت به پیکربندی متناظر \fBre2c:\fP)، \fBtag\fP (متغیر تگی که باید به‌روزرسانی شود). .TP .B \fBcode:yystagn\fP دستور \fBYYSTAGN\fP، احتمالاً سفارشی‌شده برای APIهای مختلف. متغیرهای پشتیبانی‌شده: \fBYYSTAGN\fP، \fBnegative\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBtag\fP (متغیر تگی که باید به‌روزرسانی شود). .TP .B \fBcode:yymtagn\fP دستور \fBYYMTAGN\fP، احتمالاً سفارشی‌شده برای APIهای مختلف. متغیرهای پشتیبانی‌شده: \fBYYMTAGN\fP (نگاشت به پیکربندی متناظر \fBre2c:\fP)، \fBtag\fP (متغیر تگی که باید به‌روزرسانی شود). .TP .B \fBcode:yycopystag\fP دستور \fBYYCOPYSTAG\fP، احتمالاً سفارشی‌شده برای APIهای مختلف. متغیرهای پشتیبانی‌شده: \fBYYCOPYSTAG\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBlhs\fP، \fBrhs\fP (متغیرهای تگ سمت چپ و راست عملیات رونوشت). .TP .B \fBcode:yycopymtag\fP دستور \fBYYCOPYMTAG\fP، احتمالاً سفارشی‌شده برای APIهای مختلف. متغیرهای پشتیبانی‌شده: \fBYYCOPYMTAG\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBlhs\fP، \fBrhs\fP (متغیرهای تگ سمت چپ و راست عملیات رونوشت). .TP .B \fBcode:yygetaccept\fP دستور \fBYYGETACCEPT\fP، احتمالاً سفارشی‌شده برای APIهای مختلف. متغیرهای پشتیبانی‌شده: \fBYYGETACCEPT\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBvar\fP (نگاشت به پیکربندی \fBre2c:yyaccept\fP). .TP .B \fBcode:yysetaccept\fP دستور \fBYYSETACCEPT\fP، احتمالاً سفارشی‌شده برای APIهای مختلف. متغیرهای پشتیبانی‌شده: \fBYYSETACCEPT\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBvar\fP (نگاشت به پیکربندی \fBre2c:yyaccept\fP) و \fBval\fP (مقدار عددی قاعدهٔ پذیرفته‌شده). .TP .B \fBcode:yygetcond\fP دستور \fBYYGETCOND\fP، احتمالاً سفارشی‌شده برای APIهای مختلف. متغیرهای پشتیبانی‌شده: \fBYYGETCOND\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBvar\fP (نگاشت به پیکربندی \fBre2c:yycond\fP). .TP .B \fBcode:yysetcond\fP دستور \fBYYSETCOND\fP، احتمالاً سفارشی‌شده برای APIهای مختلف. متغیرهای پشتیبانی‌شده: \fBYYSETCOND\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBvar\fP (نگاشت به پیکربندی \fBre2c:yycond\fP) و \fBval\fP (شناسهٔ عددی شرط). .TP .B \fBcode:yygetstate\fP دستور \fBYYGETSTATE\fP، احتمالاً سفارشی‌شده برای APIهای مختلف. متغیرهای پشتیبانی‌شده: \fBYYGETSTATE\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBvar\fP (نگاشت به پیکربندی \fBre2c:yystate\fP). .TP .B \fBcode:yysetstate\fP دستور \fBYYSETSTATE\fP، احتمالاً سفارشی‌شده برای APIهای مختلف. متغیرهای پشتیبانی‌شده: \fBYYSETSTATE\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBvar\fP (نگاشت به پیکربندی \fBre2c:yystate\fP) و \fBval\fP (شمارهٔ وضعیت). .TP .B \fBcode:yylessthan\fP دستور \fBYYLESSTHAN\fP، احتمالاً سفارشی‌شده برای APIهای مختلف. متغیرهای پشتیبانی‌شده: \fBYYLESSTHAN\fP، \fBYYCURSOR\fP، \fBYYLIMIT\fP، \fByyrecord\fP (نگاشت به پیکربندی‌های متناظر \fBre2c:\fP)، \fBneed\fP (تعداد واحدهای کد برای بررسی در برابر آن). شرط: \fB\&.many\fP (در صورتی که مقدار \fBneed\fP بیشتر از یک باشد، درست است)..TP .B \fBcode:yyend\fP عبارت \fBYYEND\fP، احتمالاً سفارشی‌شده برای APIهای مختلف. متغیرهای پشتیبانی‌شده: \fBYYEND\fP، \fBYYCURSOR\fP، \fBYYLIMIT\fP\&. .TP .B \fBcode:yybm_filter\fP شرطی که برای پالایش مقادیر \fByych\fP که تحت پوشش جدول \fByybm\fP قرار ندارند به کار می‌رود (همراه با گزینهٔ \fB\-\-bitmaps\fP استفاده می‌شود). متغیر پشتیبانی‌شده: \fByych\fP (به پیکربندی \fBre2c:yych\fP نگاشت می‌شود). .TP .B \fBcode:yybm_match\fP قالب بررسی جدول \fByybm\fP (تولیدشده با گزینهٔ \fB\-\-bitmaps\fP). متغیرهای پشتیبانی‌شده: \fByybm\fP، \fByych\fP (به پیکربندی‌های متناظر \fBre2c:\fP نگاشت می‌شوند)، \fBoffset\fP (آفست در جدول \fByybm\fP که باید به \fByych\fP اضافه شود) و \fBmask\fP (ماسک بیتی که باید روی مدخل جدول اعمال شود تا مقدار بولی مورد بررسی بازیابی گردد). .TP .B \fBcode:yytarget_filter\fP شرطی که برای فیلتر کردن مقادیر \fByych\fP که تحت پوشش جدول \fByytarget\fP قرار ندارند به کار می‌رود (همراه با گزینهٔ \fB\-\-computed\-gotos\fP استفاده می‌شود). متغیر پشتیبانی‌شده: \fByych\fP (به پیکربندی \fBre2c:yych\fP نگاشت می‌شود). .UNINDENT .sp در اینجا فهرستی از تمام متغیرهای سراسری مجاز در فایل‌های نحو آمده است: .INDENT 0.0 .TP .B \fBnl\fP یک خط جدید (newline). .TP .B \fBindent\fP متغیری که هیچ کدی تولید نمی‌کند، اما دارای اثر جانبی افزایش سطح تورفتگی است. .TP .B \fBdedent\fP متغیری که هیچ کدی تولید نمی‌کند، اما دارای اثر جانبی کاهش سطح تورفتگی است. .TP .B \fBtopindent\fP رشتهٔ تورفتگی برای عبارت جاری. سطح تورفتگی توسط تولیدکنندهٔ کد ردیابی شده و به‌طور خودکار به‌روزرسانی می‌شود. .UNINDENT .sp در اینجا فهرستی از تمام شرطی‌های سراسری مجاز در فایل‌های نحو آمده است: .INDENT 0.0 .TP .B \fB\&.api.simple\fP درست (True) در صورتی که API ساده به کار رفته باشد (\fB\-\-api simple\fP یا \fBre2c:api = simple\fP). .TP .B \fB\&.api.generic\fP درست (True) در صورتی که API عمومی (generic) به کار رفته باشد (\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) در صورتی که ویژگی بازه‌های case فعال باشد (\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) در صورتی که اثر انگشت (fingerprint) تولیدشده باید حاوی تاریخ تولید باشد. .TP .B \fB\&.loop_label\fP درست (True) در صورتی که حلقه‌های تولیدشده توسط re2java باید برچسب داشته باشند (\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) در صورتی که re2java برای تولید کد سریع‌تر باید از بلوک‌های \(dqunsafe\(dq استفاده کند (\fB\-\-unsafe\fP، \fBre2c:unsafe = 1\fP). این مورد تنها برای زبان‌هایی که ویژگی \(dqunsafe\(dq را دارند مرتبط است. .TP .B \fB\&.version\fP درست (True) در صورتی که اثر انگشت تولیدشده باید شامل نسخهٔ re2java باشد. .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 یکی از مشکلات اصلی لکسر این است که بداند چه زمانی باید متوقف شود. چندین شرط پایان‌دهنده وجود دارد: .INDENT 0.0 .IP \(bu 2 لکسر ممکن است با یک قاعده (شامل قاعده پیش‌فرض \fB*\fP) تطبیق یافته و به یک وضعیت نهایی برسد .IP \(bu 2 لکسر ممکن است در تطبیق با هر قاعده‌ای شکست بخورد و به یک وضعیت پیش‌فرض برسد .IP \(bu 2 لکسر ممکن است به پایان ورودی برسد .UNINDENT .sp دو شرط اول لکسر را به روشی «طبیعی» (\(dqnatural\(dq) متوقف می‌کنند: لکسر به وضعیتی بدون انتقال‌های خروجی می‌رسد و فرآیند تطبیق به‌طور خودکار متوقف می‌شود. شرط سوم، یعنی پایان ورودی، متفاوت است: این حالت ممکن است در هر وضعیتی رخ دهد و لکسر باید قادر به مدیریت آن باشد. بررسی پایان ورودی، جریان کاری عادی لکسر را متوقف کرده و انشعاب‌های شرطی را به برنامه تولیدشده می‌افزاید؛ بنابراین لازم است تعداد این بررسی‌ها به حداقل برسد. ابزار re2java از چند روش مختلف برای مدیریت پایان ورودی پشتیبانی می‌کند. انتخاب روش مناسب به پیچیدگی عبارات باقاعده، نیاز به بافرسازی، ملاحظات کارایی و سایر عوامل بستگی دارد. در ادامه فهرستی از این روش‌ها آورده شده است: .INDENT 0.0 .IP \(bu 2 \fBروش Sentinel (نگهبان).\fP این روش نیاز به بررسی‌های پایان ورودی را به‌کلی برطرف می‌کند. این روش ساده و کارآمد است، اما محدود به حالتی است که یک نویسه «sentinel» طبیعی وجود داشته باشد که هرگز در ورودی معتبر رخ ندهد. این نویسه ممکن است در ورودی نامعتبر ظاهر شود، اما نباید توسط عبارات باقاعده مجاز باشد، مگر شاید به عنوان آخرین نویسه از یک قاعده. نویسه sentinel به انتهای ورودی ضمیمه شده و به عنوان یک سیگنال توقف عمل می‌کند: هنگامی که لکسر این نویسه را می‌خواند، یا یک خطای نحوی است یا پایان ورودی. در هر دو حالت لکسر باید متوقف شود. این روش در صورتی استفاده می‌شود که \fBYYFILL\fP با \fBre2c:yyfill:enable = 0;\fP غیرفعال شده و \fBre2c:eof\fP مقدار پیش‌فرض \fB\-1\fP را داشته باشد\&. .nf .fi .sp .IP \(bu 2 \fBروش Sentinel به‌همراه بررسی‌های مرزی (Sentinel with bounds checks).\fP این روش عمومی است: به کاربر اجازه می‌دهد هر ورودی را بدون محدودیت در عبارات باقاعده مدیریت کند. ایده این است که تعداد بررسی‌های پایان ورودی از طریق انجام آن‌ها تنها روی نویسه‌های خاصی کاهش یابد. مشابه روش «sentinel»، یکی از نویسه‌ها به عنوان «sentinel» انتخاب شده و به انتهای ورودی ضمیمه می‌شود. با این حال، هیچ محدودیتی در محل وقوع sentinel وجود ندارد (در واقع هر نویسه‌ای می‌تواند به عنوان sentinel انتخاب شود). هنگامی که لکسر این نویسه را می‌خواند، علاوه بر آن یک بررسی مرزی انجام می‌دهد. اگر موقعیت فعلی در محدوده مجاز باشد، لکسر تطبیق را از سر گرفته و با نویسه sentinel مانند یک نویسه عادی رفتار می‌کند. در غیر این صورت، \fBYYFILL\fP را فراخوانی می‌کند (مگر اینکه غیرفعال شده باشد). اگر ورودی بیشتری فراهم شود، لکسر نویسه آخر را مجدداً تطبیق داده و طوری ادامه می‌دهد که گویی sentinel وجود نداشته است. در غیر این صورت، این باید پایان واقعی ورودی باشد و لکسر متوقف می‌شود. این روش زمانی استفاده می‌شود که \fBre2c:eof\fP مقداری غیرمنفی داشته باشد (باید روی مقدار عددی sentinel تنظیم شود). استفاده از \fBYYFILL\fP اختیاری است. .nf .fi .sp .IP \(bu 2 \fBبررسی‌های مرزی با پدینگ (Bounds checks with padding).\fP این روش عمومی است و ممکن است سریع‌تر از روش «sentinel به‌همراه بررسی‌های مرزی» باشد، اما پیچیده‌تر نیز هست. ایده این است که وضعیت‌های 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 امکان بازنویسی عملیات‌های پایه‌ای مانند خواندن یک نویسه را فراهم می‌کند، که گنجاندن بررسی‌های پایان ورودی را به عنوان بخشی از آن‌ها ممکن می‌سازد. این رویکرد مستعد خطا است و باید با احتیاط استفاده شود. برای استفاده از یک روش سفارشی، 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 // re2java $INPUT \-o $OUTPUT class Main { // Expects a null\-terminated string. static int lex(String yyinput) { int yycursor = 0; int count = 0; loop: while (true) { /*!re2c re2c:YYCTYPE = \(dqchar\(dq; re2c:YYPEEK = \(dqyyinput.charAt(yycursor)\(dq; re2c:yyfill:enable = 0; * { return \-1; } [\ex00] { return count; } [a\-z]+ { count += 1; continue loop; } [ ]+ { continue loop; } */ } } public static void main(String []args) { assert lex(\(dq\e0\(dq) == 0; assert lex(\(dqone two three\e0\(dq) == 3; assert lex(\(dqf0ur\e0\(dq) == \-1; } }; .ft P .fi .UNINDENT .UNINDENT .SS نگهبان همراه با بررسی‌های محدوده (Sentinel with bounds checks) .sp این مثال از نگهبان همراه با بررسی‌های محدوده برای مدیریت پایان ورودی استفاده می‌کند (این روش در نسخهٔ 1.2 اضافه شد). این برنامه رشته‌های محصور در علامت نقل‌قول تکی (single-quoted) را که با فاصله جدا شده‌اند شمارش می‌کند. نویسهٔ نگهبان null است که با پیکربندی \fBre2c:eof = 0;\fP مشخص می‌شود. همانند روش \fI\%sentinel\fP، نویسهٔ null آخرین نویسهٔ هر رشتهٔ ورودی است، اما در میانهٔ یک قاعده مجاز است (برای نمونه، \fB\(aqaaa\e0aa\(aq\e0\fP ورودی معتبری است، اما \fB\(aqaaa\e0\fP یک خطای نحوی است). بررسی‌های محدوده در هر وضعیتی که با یک نویسهٔ ورودی مطابقت دارد تولید می‌شوند، اما دامنهٔ آن‌ها به شاخه‌ای که null را مدیریت می‌کند محدود است. بررسی‌های محدوده با API عمومی به صورت \fBYYLIMIT <= YYCURSOR\fP یا \fBYYLESSTHAN(1)\fP هستند. اگر شرط بررسی درست باشد، تحلیل‌گر لغوی به پایان ورودی رسیده است و باید متوقف شود (\fBYYFILL\fP با \fBre2c:yyfill:enable = 0;\fP غیرفعال می‌شود چرا که ورودی در یک بافر جای می‌گیرد؛ برای نمونه‌ای که از \fBYYFILL\fP استفاده می‌کند به بخش \fI\%YYFILL with sentinel\fP مراجعه کنید). رسیدن به انتهای ورودی سه احتمال را مطرح می‌کند: اگر تحلیل‌گر لغوی در وضعیت اولیه باشد با قاعدهٔ پایان ورودی \fB$\fP مطابقت پیدا خواهد کرد، در غیر این صورت ممکن است به یک قاعدهٔ مطابقت‌یافتهٔ قبلی بازگردد (از جمله قاعدهٔ پیش‌فرض \fB*\fP) یا به یک وضعیت پیش‌فرض برود که موجب بروز هشدار \fI\%\-Wundefined\-control\-flow\fP\& می‌شود. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2java $INPUT \-o $OUTPUT class Main { // Expects a null\-terminated string. static int lex(String yyinput) { int yycursor = 0; int yymarker = 0; int yylimit = yyinput.length() \- 1; // yylimit points at the terminating null int count = 0; loop: while (true) { /*!re2c re2c:YYCTYPE = \(dqchar\(dq; re2c:YYPEEK = \(dqyyinput.charAt(yycursor)\(dq; re2c:yyfill:enable = 0; re2c:eof = 0; str = [\(aq] ([^\(aq\e\e] | [\e\e][^])* [\(aq]; * { return \-1; } $ { return count; } str { count += 1; continue loop; } [ ]+ { continue loop; } */ } } public static void main(String []args) { assert lex(\(dq\e0\(dq) == 0; assert lex(\(dq\(aqqu\e0tes\(aq \(aqare\(aq \(aqfine: \e\e\(aq\(aq \e0\(dq) == 3; assert lex(\(dq\(aqunterminated\e\e\(aq\e0\(dq) == \-1; } }; .ft P .fi .UNINDENT .UNINDENT.SS "بررسی‌های محدوده با لایه‌گذاری (Bounds checks with padding)" .sp این مثال از بررسی‌های محدوده به همراه لایه‌گذاری برای مدیریت انتهای ورودی استفاده می‌کند (این روش به‌صورت پیش‌فرض فعال است). برنامه رشته‌های محصور در نقل‌قول تکی را که با فاصله از هم جدا شده‌اند، می‌شمارد. یک لایه‌گذاری شامل \fBYYMAXFILL\fP کاراکتر null به انتهای ورودی ضمیمه شده است، که در آن مقدار \fBYYMAXFILL\fP به‌طور خودکار توسط یک بلوک \fBmax\fP تولید می‌شود. استفاده از null برای لایه‌گذاری الزامی نیست \-\-\- از هر کاراکتری می‌توان استفاده کرد، به شرط آن‌که پسوند معتبری برای یک نشانه (lexeme) نسازد (در این مثال، لایه‌گذاری نباید شامل نقل‌قول تکی باشد، چرا که ممکن است به عنوان پسوندی از یک رشتهٔ محصور در نقل‌قول تکی به اشتباه در نظر گرفته شود). یک قاعدهٔ \(dqstop\(dq وجود دارد که با نخستین کاراکتر لایه‌گذاری (null) مطابقت یافته و به کار lexer پایان می‌دهد (توجه داشته باشید که این قاعده بررسی می‌کند آیا null در ابتدای لایه‌گذاری قرار دارد یا خیر، در غیر این صورت یک خطای نحوی است). بررسی‌های محدوده فقط در برخی از حالت‌ها تولید می‌شوند که توسط مؤلفه‌های قویاً همبندِ اتوماتون زیربنایی تعیین شده‌اند. بررسی‌ها به فرم \fB(YYLIMIT \- YYCURSOR) < n\fP یا با generic API به فرم \fBYYLESSTHAN(n)\fP هستند، که در آن \fBn\fP حداقل تعداد کاراکترهای لازم برای ادامهٔ کار lexer است (این موضوع همچنین بدان معناست که بررسی محدودهٔ بعدی حداکثر تا \fBn\fP کاراکتر دیگر رخ خواهد داد). اگر شرط بررسی برقرار باشد (true)، یعنی lexer به انتهای ورودی رسیده است و \fBYYFILL(n)\fP را فراخوانی می‌کند که باید یا حداقل \fBn\fP کاراکتر ورودی را تامین کند یا بازگشتی نداشته باشد. در این مثال، \fBYYFILL\fP همواره شکست می‌خورد و lexer را با یک خطا متوقف می‌کند (که مشکلی ایجاد نمی‌کند، زیرا ورودی در یک بافر می‌گنجد). برای نمونه‌ای که بافر ورودی را با \fBYYFILL\fP دوباره پر می‌کند، بخش \fI\%YYFILL with padding\fP را ببینید\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2java $INPUT \-o $OUTPUT class Main { /*!max:re2c*/ // Expects yymaxfill\-padded string. static int lex(byte[] str) { // Pad string with yymaxfill zeroes at the end. byte[] yyinput = new byte[str.length + YYMAXFILL]; System.arraycopy(str, 0, yyinput, 0, str.length); int yycursor = 0; int yylimit = yyinput.length; int count = 0; loop: while (true) { /*!re2c re2c:YYCTYPE = \(dqint\(dq; re2c:YYPEEK = \(dqByte.toUnsignedInt(yyinput[yycursor])\(dq; re2c:YYFILL = \(dqreturn \-1;\(dq; str = [\(aq] ([^\(aq\e\e] | [\e\e][^])* [\(aq]; [\ex00] { // Check that it is the sentinel, not some unexpected null. return (yycursor \- 1 == str.length) ? count : \-1; } str { count += 1; continue loop; } [ ]+ { continue loop; } * { return \-1; } */ } } public static void main(String []args) { assert lex(\(dq\(dq.getBytes()) == 0; assert lex(\(dq\(aqqu\e0tes\(aq \(aqare\(aq \(aqfine: \e\e\(aq\(aq \(dq.getBytes()) == 3; assert lex(\(dq\(aqunterminated\e\e\(aq\(dq.getBytes()) == \-1; assert lex(\(dq\(aqunexpected \e00 null\e\e\(aq\(dq.getBytes()) == \-1; } }; .ft P .fi .UNINDENT .UNINDENT .SS "بررسی‌های سفارشی (Custom checks)" .sp این مثال از یک روش سفارشی مدیریت انتهای ورودی مبتنی بر generic API استفاده می‌کند. برنامه رشته‌های محصور در نقل‌قول تکی را که با فاصله از هم جدا شده‌اند، می‌شمارد. این مثال همانند مثال \fI\%sentinel\fP است، با این تفاوت که ورودی با null خاتمه نمی‌یابد. برای جبران نبود کاراکتر نگهبان (sentinel) در انتهای ورودی، \fBYYPEEK\fP مجدداً تعریف شده است تا قبل از خواندن کاراکتر بعدی ورودی، یک بررسی محدوده انجام دهد. این روش ناکارآمد است زیرا بررسی‌ها بسیار مکرر انجام می‌شوند. اگر شرط بررسی برقرار نباشد، \fBYYPEEK\fP کاراکتر واقعی را بازمی‌گرداند، در غیر این صورت یک کاراکتر نگهبان ساختگی را برمی‌گرداند. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2java $INPUT \-o $OUTPUT class Main { // Expects a string without terminating null. static int lex(String str) { byte[] yyinput = str.getBytes(); int yycursor = 0; int count = 0; loop: while (true) { /*!re2c re2c:api = generic; re2c:YYCTYPE = \(dqint\(dq; re2c:YYPEEK = \(dq(yycursor < yyinput.length)\(dq \(dq ? Byte.toUnsignedInt(yyinput[yycursor]) : 0\(dq; re2c:YYSKIP = \(dqyycursor += 1;\(dq; re2c:yyfill:enable = 0; * { return \-1; } [\ex00] { return count; } [a\-z]+ { count += 1; continue loop; } [ ]+ { continue loop; } */ } } public static void main(String []args) { assert lex(\(dq\(dq) == 0; assert lex(\(dqone two three\(dq) == 3; assert lex(\(dqf0ur\(dq) == \-1; } }; .ft P .fi .UNINDENT .UNINDENT.SH "پر کردن مجدد بافر (BUFFER REFILLING)" .sp نیاز به بافرینگ زمانی پیش می‌آید که ورودی نتواند به‌یک‌باره در حافظه نگاشت شود: یا بیش از حد بزرگ است، یا به صورت جریانی (مانند خواندن از یک سوکت) دریافت می‌شود. روش معمول در چنین مواردی تخصیص یک بافر حافظه با اندازهٔ ثابت و پردازش ورودی در قالب تکه‌هایی است که در بافر جا می‌گیرند. هنگامی که تکهٔ جاری پردازش شد، به بیرون منتقل شده و داده‌های جدید وارد می‌شوند. در عمل این موضوع تا حدی پیچیده‌تر است، زیرا وضعیت lexer تنها از یک موقعیت ورودی منفرد تشکیل نشده، بلکه مجموعه‌ای از موقعیت‌های به‌هم‌پیوسته است: .INDENT 0.0 .IP \(bu 2 مکان‌نما (cursor): نویسهٔ ورودی بعدی برای خوانده شدن (\fBYYCURSOR\fP در API اشاره‌گر C یا \fBYYSKIP\fP/\fBYYPEEK\fP در API عمومی) .IP \(bu 2 حد (limit): موقعیت پس از آخرین نویسهٔ ورودی در دسترس (\fBYYLIMIT\fP در API اشاره‌گر C، که به صورت ضمنی توسط \fBYYLESSTHAN\fP در API عمومی مدیریت می‌شود) .IP \(bu 2 نشانه‌گذار (marker): موقعیت تازه‌ترین تطابق، در صورت وجود (\fBYYMARKER\fP در API پیش‌فرض یا \fBYYBACKUP\fP/\fBYYRESTORE\fP در API عمومی) .IP \(bu 2 توکن (token): آغاز لکسم (lexeme) جاری (در API مربوط به re2java ضمنی است، زیرا برای عملکرد عادی lexer نیازی به آن نیست و می‌تواند توسط کاربر تعریف و به‌روزرسانی شود) .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، بهتر است تا حد امکان نویسه‌های ورودی بیشتری پر شوند (حتی اگر نویسه‌های کمتری برای از سرگیری کار lexer کافی باشند). جزئیات پیاده‌سازی \fBYYFILL\fP بسته به روشِ مدیریت EOF مورد استفاده کمی تفاوت دارد: حالت قاعدهٔ EOF تا حدودی ساده‌تر از حالت بررسی مرزها با پدگذاری (padding) است. همچنین توجه داشته باشید که اگر گزینهٔ \fB\-f \-\-storable\-state\fP استفاده شود، \fBYYFILL\fP معناشناسی کمی متفاوتی خواهد داشت (که در بخش مربوط به storable state شرح داده شده است). .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 باید نماد نگهبان مشخص‌شده توسط پیکربندی \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 // re2java $INPUT \-o $OUTPUT import java.io.*; import java.nio.file.*; class Lexer { public static final int BUFSIZE = 4096; private BufferedInputStream stream; private byte[] yyinput; private int yycursor; private int yymarker; private int yylimit; private int token; private boolean eof; public Lexer(File file) throws FileNotFoundException { stream = new BufferedInputStream(new FileInputStream(file)); // Sentinel at \(gayylimit\(ga offset is set to zero, which triggers YYFILL. yyinput = new byte[BUFSIZE + 1]; yycursor = yymarker = yylimit = token = BUFSIZE; eof = false; } private int fill() throws IOException { if (eof) { return \-1; } // unexpected EOF // Error: lexeme too long. In real life can reallocate a larger buffer. if (token < 1) { return \-2; } // Shift buffer contents (discard everything up to the current token). System.arraycopy(yyinput, token, yyinput, 0, yylimit \- token); yycursor \-= token; yymarker \-= token; yylimit \-= token; token = 0; // Fill free space at the end of buffer with new data from file. yylimit += stream.read(yyinput, yylimit, BUFSIZE \- yylimit); yyinput[yylimit] = 0; // append sentinel symbol // If read less than expected, this is the end of input. eof = yylimit < BUFSIZE; return 0; } // Expects a null\-terminated string. public int lex() throws IOException { int count = 0; loop: while (true) { token = yycursor; /*!re2c re2c:YYCTYPE = \(dqint\(dq; re2c:YYPEEK = \(dqByte.toUnsignedInt(yyinput[yycursor])\(dq; re2c:YYFILL = \(dqfill() == 0\(dq; re2c:eof = 0; str = [\(aq] ([^\(aq\e\e] | [\e\e][^])* [\(aq]; * { return \-1; } $ { return count; } str { count += 1; continue loop; } [ ]+ { continue loop; } */ } } public static void main(String []args) throws FileNotFoundException, IOException { String fname = \(dqinput\(dq; String content = \(dq\(aqqu\e0tes\(aq \(aqare\(aq \(aqfine: \e\e\(aq\(aq \(dq.repeat(Lexer.BUFSIZE); // Prepare input file: a few times the size of the buffer, containing // strings with zeroes and escaped quotes. Files.writeString(Paths.get(fname), content); int count = 3 * Lexer.BUFSIZE; // number of quoted strings written to file // Prepare lexer state: all offsets are at the end of buffer. File file = new File(\(dq.\(dq, fname); Lexer lexer = new Lexer(file); // Run the lexer. int n = lexer.lex(); assert n == count; // Cleanup: remove input file. file.delete(); } }; .ft P .fi .UNINDENT .UNINDENT.SS "YYFILL همراه با پدینگ (padding)" .sp در حالت پیش‌فرض (زمانی که از قاعده EOF استفاده نمی‌شود) \fBYYFILL\fP یک دستور اولیهٔ شبه‌تابع (function\-like primitive) است که یک آرگومان دریافت می‌کند و هیچ مقداری را برنمی‌گرداند. فراخوانی \fBYYFILL\fP با شرط \fB(YYLIMIT \- YYCURSOR) < n\fP در API اشاره‌گر C و با \fBYYLESSTHAN(n)\fP در 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 // re2java $INPUT \-o $OUTPUT import java.io.*; import java.nio.file.*; import java.util.Arrays; class Lexer { /*!max:re2c*/ public static final int BUFSIZE = 4096; private BufferedInputStream stream; private byte[] yyinput; private int yycursor; private int yylimit; private int token; private boolean eof; public Lexer(File file) throws FileNotFoundException { stream = new BufferedInputStream(new FileInputStream(file)); // Prepare lexer state: all offsets are at the end of buffer. // This immediately triggers YYFILL, as the YYLESSTHAN condition is true. yyinput = new byte[BUFSIZE + YYMAXFILL]; yycursor = yylimit = token = BUFSIZE; eof = false; } private int fill(int need) throws IOException { if (eof) { return \-1; } // unexpected EOF // Error: lexeme too long. In real life can reallocate a larger buffer. if (token < need) { return \-2; } // Shift buffer contents (discard everything up to the current token). System.arraycopy(yyinput, token, yyinput, 0, yylimit \- token); yycursor \-= token; yylimit \-= token; token = 0; // Fill free space at the end of buffer with new data from file. yylimit += stream.read(yyinput, yylimit, BUFSIZE \- yylimit); yyinput[yylimit] = 0; // append sentinel symbol // If read less than expected, this is the end of input. if (yylimit < BUFSIZE) { eof = true; Arrays.fill(yyinput, yylimit, yylimit + YYMAXFILL, (byte)0); yylimit += YYMAXFILL; } return 0; } // Expects a null\-terminated string. public int lex() throws IOException { int count = 0; loop: while (true) { token = yycursor; /*!re2c re2c:YYCTYPE = \(dqint\(dq; re2c:YYPEEK = \(dqByte.toUnsignedInt(yyinput[yycursor])\(dq; re2c:YYFILL = \(dqif (fill(@@) != 0) { return \-2; }\(dq; str = [\(aq] ([^\(aq\e\e] | [\e\e][^])* [\(aq]; [\ex00] { // Check that it is the sentinel, not some unexpected null. return (token == yylimit \- YYMAXFILL) ? count : \-1; } str { count += 1; continue loop; } [ ]+ { continue loop; } * { return \-1; } */ } } public static void main(String []args) throws FileNotFoundException, IOException { String fname = \(dqinput\(dq; String content = \(dq\(aqqu\e0tes\(aq \(aqare\(aq \(aqfine: \e\e\(aq\(aq \(dq.repeat(Lexer.BUFSIZE); // Prepare input file: a few times the size of the buffer, containing // strings with zeroes and escaped quotes. Files.writeString(Paths.get(fname), content); int count = 3 * Lexer.BUFSIZE; // number of quoted strings written to file // Prepare lexer state: all offsets are at the end of buffer. File file = new File(\(dq.\(dq, fname); Lexer lexer = new Lexer(file); // Run the lexer. int n = lexer.lex(); assert n == count; // Cleanup: remove input file. file.delete(); } }; .ft P .fi .UNINDENT .UNINDENT.SH "ویژگی‌ها (FEATURES)" .SS "بلوک‌های چندگانه (Multiple blocks)" .sp گاهی داشتن چندین تحلیل‌گر لغوی (lexer) مرتبط با یکدیگر ضروری است (برای مثال، اگر یک ماشین حالت سطح بالا وجود داشته باشد که بین حالت‌های لکسر جابه‌جا می‌شود). این کار می‌تواند با استفاده از چندین بلوک به‌هم‌پیوسته re2java پیاده‌سازی شود. گزینه دیگر استفاده از \fI\%شرط‌های شروع (start conditions)\fP\& است. .sp پیاده‌سازی ارتباط بین بلوک‌ها به زبان مقصد بستگی دارد. در زبان‌هایی که دستور \fBgoto\fP دارند (مانند C/C++ و Go) می‌توان تمامی بلوک‌ها را درون یک تابع قرار داد که پیش از هر یک از آن‌ها یک برچسب (label) قرار گرفته باشد. جابه‌جایی از یک بلوک به بلوک دیگر یک \fBgoto\fP\& ساده است. در زبان‌هایی که دستور \fBgoto\fP ندارند (مانند Rust) استفاده از یک حلقه همراه با switch روی یک متغیر حالت ضروری است؛ مشابه حلقه/switch مربوط به \fByystate\fP که توسط re2java تولید می‌شود، یا اینکه باید هر بلوک را درون یک تابع قرار داد و از فراخوانی توابع بهره برد. .sp مثال زیر از چندین بلوک برای تجزیه اعداد دودویی (binary)، هشت‌هشتی (octal)، ده‌دهی (decimal) و شانزده‌شانزدهی (hexadecimal) استفاده می‌کند. هر مبنا بلوک مخصوص به خود را دارد. بلوک اولیه مبنا را تعیین کرده و کنترل را به بلوک‌های دیگر واگذار می‌کند. پیکربندی‌های مشترک در یک بلوک جداگانه در ابتدای برنامه تعریف شده‌اند؛ این پیکربندی‌ها توسط بلوک‌های دیگر به ارث برده می‌شوند. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2java $INPUT \-o $OUTPUT class Parser { private String yyinput; private int yycursor; private int yymarker; private int number; private void add_digit(int base, int offset) throws ArithmeticException { number = Math.addExact( Math.multiplyExact(number, base), yyinput.charAt(yycursor \- 1) \- offset); } public int parse(String str) throws ArithmeticException, IllegalArgumentException { yyinput = str; yycursor = 0; number = 0; try { /*!re2c re2c:YYCTYPE = \(dqchar\(dq; re2c:YYPEEK = \(dqyyinput.charAt(yycursor)\(dq; re2c:yyfill:enable = 0; end = \(dq\ex00\(dq; \(aq0b\(aq / [01] { return parse_bin(); } \(dq0\(dq { return parse_oct(); } \(dq\(dq / [1\-9] { return parse_dec(); } \(aq0x\(aq / [0\-9a\-fA\-F] { return parse_hex(); } * { throw new IllegalArgumentException(\(dqnot a number\(dq); } */ } catch (Exception e) { return \-1; } } private int parse_bin() throws ArithmeticException, IllegalArgumentException { /*!re2c end { return number; } [01] { add_digit(2, 48); return parse_bin(); } * { throw new IllegalArgumentException(\(dqill\-formed binary number\(dq); } */ } private int parse_oct() throws ArithmeticException, IllegalArgumentException { /*!re2c end { return number; } [0\-7] { add_digit(8, 48); return parse_oct(); } * { throw new IllegalArgumentException(\(dqill\-formed octal number\(dq); } */ } private int parse_dec() throws ArithmeticException, IllegalArgumentException { /*!re2c end { return number; } [0\-9] { add_digit(10, 48); return parse_dec(); } * { throw new IllegalArgumentException(\(dqill\-formed decimal number\(dq); } */ } private int parse_hex() throws ArithmeticException, IllegalArgumentException { /*!re2c end { return number; } [0\-9] { add_digit(16, 48); return parse_hex(); } [a\-f] { add_digit(16, 87); return parse_hex(); } [A\-F] { add_digit(16, 55); return parse_hex(); } * { throw new IllegalArgumentException(\(dqill\-formed hexadecimal number\(dq); } */ } public static void main(String []args) { Parser parser = new Parser(); assert parser.parse(\(dq1234567890\e0\(dq) == 1234567890; assert parser.parse(\(dq0b1101\e0\(dq) == 0b1101; assert parser.parse(\(dq0x007Fe\e0\(dq) == 0x7fe; assert parser.parse(\(dq0644\e0\(dq) == 0644; assert parser.parse(\(dq9999999999\e0\(dq) == \-1; assert parser.parse(\(dq123??\e0\(dq) == \-1; } }; .ft P .fi .UNINDENT .UNINDENT.SS شرایط شروع (Start conditions) .sp شرایط شروع با گزینهٔ \fB\-\-start\-conditions\fP فعال می‌شوند. آن‌ها روشی را برای کدگذاری چندین اتوماتای مرتبط با یکدیگر در یک بلوک یکسان re2java فراهم می‌کنند. .sp هر شرط متناظر با یک اتوماتای منفرد است و دارای یک نام منحصربه‌فرد مشخص‌شده توسط کاربر و یک شمارهٔ داخلی منحصربه‌فرد تعریف‌شده توسط re2java\& است. این شماره‌ها برای جابه‌جایی بین شرایط به کار می‌روند: کد تولیدشده از پایه‌های \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 کدی که re2java برای شرایط تولید می‌کند بستگی به این دارد که re2java از رویکرد goto/label یا رویکرد loop/switch برای کدگذاری اتوماتا استفاده کند. .sp در زبان‌هایی که دارای دستور \fBgoto\fP هستند (مانند C/C++ و Go)، شرایط به‌طور طبیعی به عنوان بلوک‌هایی از کد با پیشوند برچسب‌هایی به فرم \fByyc_\fP پیاده‌سازی می‌شوند، که در آن \fBcond\fP نام یک شرط است (پیشوند برچسب می‌تواند با \fBre2c:cond:prefix\fP تغییر یابد). گذارها بین شرایط با استفاده از \fBgoto\fP و برچسب‌های شرط پیاده‌سازی می‌شوند. پیش از همهٔ شرایط، re2java یک switch اولیه بر روی \fBYYGETSTATE\fP تولید می‌کند که به وضعیت شروعِ شرط جاری می‌پرد. قواعد میان‌بر \fB:=>\fP از switch اولیه عبور کرده و مستقیماً به شرط تعیین‌شده پرش می‌کنند (برای تغییر رفتار پیش‌فرض می‌توان از \fBre2c:cond:goto\fP استفاده کرد). قواعد دارای کنش‌های معنایی به‌طور خودکار به شرط بعدی نمی‌پرند؛ این کار باید توسط کد کنشِ تعریف‌شده توسط کاربر انجام شود. .sp در زبان‌هایی که فاقد \fBgoto\fP هستند (مانند Rust)، re2java متغیر \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 // re2java $INPUT \-o $OUTPUT \-c class Parser { /*!conditions:re2c*/ private String yyinput; private int yycursor; private int yymarker; private int number; private void add_digit(int base, int offset) throws ArithmeticException { number = Math.addExact( Math.multiplyExact(number, base), yyinput.charAt(yycursor \- 1) \- offset); } public int parse(String str) throws ArithmeticException, IllegalArgumentException { yyinput = str; yycursor = 0; int yycond = YYC_init; number = 0; try { loop: while (true) { /*!re2c re2c:YYCTYPE = \(dqchar\(dq; re2c:YYPEEK = \(dqyyinput.charAt(yycursor)\(dq; re2c:yyfill:enable = 0; <*> * { throw new IllegalArgumentException(\(dqill\-formed number\(dq); } \(aq0b\(aq / [01] :=> bin \(dq0\(dq :=> oct \(dq\(dq / [1\-9] :=> dec \(aq0x\(aq / [0\-9a\-fA\-F] :=> hex \(dq\ex00\(dq { return number; } [01] { add_digit(2, 48); continue loop; } [0\-7] { add_digit(8, 48); continue loop; } [0\-9] { add_digit(10, 48); continue loop; } [0\-9] { add_digit(16, 48); continue loop; } [a\-f] { add_digit(16, 87); continue loop; } [A\-F] { add_digit(16, 55); continue loop; } */ } } catch (Exception e) { return \-1; } } public static void main(String []args) { Parser parser = new Parser(); assert parser.parse(\(dq1234567890\e0\(dq) == 1234567890; assert parser.parse(\(dq0b1101\e0\(dq) == 0b1101; assert parser.parse(\(dq0x007Fe\e0\(dq) == 0x7fe; assert parser.parse(\(dq0644\e0\(dq) == 0644; assert parser.parse(\(dq9999999999\e0\(dq) == \-1; assert parser.parse(\(dq123??\e0\(dq) == \-1; } }; .ft P .fi .UNINDENT .UNINDENT.SS "وضعیت قابل ذخیره‌سازی (Storable state)" .sp با گزینهٔ \fB\-\-storable\-state\fP، برنامهٔ re2java تحلیل‌گر لغوی‌ای تولید می‌کند که می‌تواند وضعیت فعلی خود را ذخیره کند، به فراخواننده بازگردد، و بعداً عملیات را دقیقاً از همان‌جایی که رها کرده بود از سر بگیرد. حالت پیش‌فرض عملکرد در re2java یک مدل «کِششی» (\(dqpull\(dq) است که در آن تحلیل‌گر لغوی هر زمان که نیاز داشته باشد، ورودی بیشتری را «می‌کشد» (\(dqpulls\(dq). این امر ممکن است در مواردی که ورودی به‌صورت تکه‌تکه در دسترس قرار می‌گیرد غیرقابل‌قبول باشد (برای مثال، اگر تحلیل‌گر لغوی توسط تجزیه‌کننده فراخوانی شود، یا اگر برنامهٔ تحلیل‌گر لغوی از طریق یک پروتکل سوکت با برنامهٔ دیگری ارتباط برقرار کند که باید پیش از ارسال پیام بعدی، منتظر پاسخی از تحلیل‌گر لغوی بماند). قابلیت وضعیت قابل ذخیره‌سازی دقیقاً برای چنین مواردی در نظر گرفته شده است: این قابلیت امکان تولید تحلیل‌گرهای لغوی‌ای را می‌دهد که در یک مدل «رانشی» (\(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) ممکن است کار نکند زیرا مشخص نیست چه زمانی باید لایه‌گذاری را اضافه کرد: پایان فعلی ورودی ممکن است پایان نهایی ورودی نباشد، و اضافه کردن زودهنگام لایه‌گذاری ممکن است یک واحد لغوی (lexeme) حریصانه را که تا حدی خوانده شده است قطع کند. علاوه بر این، با توجه به منطق سطح بالای برنامه، دریافت ورودی بیشتر ممکن است به پردازش واحد لغوی در انتهای بافر وابسته باشد (که از قبل به‌دلیل شرایط پایان ورودی مسدود شده است). .UNINDENT .sp در اینجا مثالی از یک تحلیل‌گر لغوی با مدل \(dqpush\(dq آورده شده است که خواندن بسته‌ها از یک سوکت را شبیه‌سازی می‌کند. تحلیل‌گر لغوی تا زمانی که با پایان ورودی مواجه شود حلقه می‌زند و به تابع فراخواننده بازمی‌گردد. تابع فراخواننده با «ارسال» (\(dqsending\(dq) بستهٔ بعدی، ورودی بیشتری تأمین می‌کند و تحلیل لغوی را از سر می‌گیرد. این فرایند زمانی که تمام بسته‌ها ارسال شوند، یا خطایی رخ دهد، متوقف می‌شود. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2java $INPUT \-o $OUTPUT \-f import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.Pipe; class Lexer { enum Status { END, READY, WAITING, BIG_PACKET, BAD_PACKET }; // Use a small buffer to cover the case when a lexeme doesn\(aqt fit. // In real world use a larger buffer. public static final int BUFSIZE = 10; public static class State { Pipe.SourceChannel source; byte[] yyinput; int yycursor; int yymarker; int yylimit; int token; int yystate; int received; public State(Pipe pipe) { source = pipe.source(); // Sentinel at \(gayylimit\(ga offset is set to zero, which triggers YYFILL. yyinput = new byte[BUFSIZE + 1]; yycursor = yymarker = yylimit = token = BUFSIZE; yystate = \-1; received = 0; } } private static void log(String format, Object... args) { if (false) { System.out.printf(format + \(dq\en\(dq, args); } } private static Status fill(State st) throws IOException { // Error: lexeme too long. In real life can reallocate a larger buffer. if (st.token < 1) { return Status.BIG_PACKET; } // Shift buffer contents (discard everything up to the current token). System.arraycopy(st.yyinput, st.token, st.yyinput, 0, st.yylimit \- st.token); st.yycursor \-= st.token; st.yymarker \-= st.token; st.yylimit \-= st.token; st.token = 0; // Fill free space at the end of buffer with new data from file. ByteBuffer buffer = ByteBuffer.wrap(st.yyinput, st.yylimit, BUFSIZE \- st.yylimit); int have = st.source.read(buffer); if (have != \-1) st.yylimit += have; // \-1 means that pipe is closed st.yyinput[st.yylimit] = 0; // append sentinel symbol return Status.READY; } private static Status lex(State yyrecord) { int yych; loop: while (true) { yyrecord.token = yyrecord.yycursor; /*!re2c re2c:api = record; re2c:YYCTYPE = \(dqint\(dq; re2c:YYPEEK = \(dqByte.toUnsignedInt(yyrecord.yyinput[yyrecord.yycursor])\(dq; re2c:YYFILL = \(dqreturn Status.WAITING;\(dq; re2c:eof = 0; packet = [a\-z]+[;]; * { return Status.BAD_PACKET; } $ { return Status.END; } packet { yyrecord.received += 1; continue loop; } */ } } public static void test(String[] packets, Status expect) throws IOException { // Create a pipe. Pipe pipe = Pipe.open(); Pipe.SinkChannel sink = pipe.sink(); // Initialize lexer state Lexer.State st = new Lexer.State(pipe); // 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. int send = 0; Status status; while (true) { status = lex(st); if (status == Status.END) { log(\(dqdone: got %d packets\(dq, st.received); break; } else if (status == Status.WAITING) { log(\(dqwaiting...\(dq); if (send < packets.length) { log(\(dqsent packet %d: %s\(dq, send, packets[send]); ByteBuffer buffer = ByteBuffer.wrap(packets[send].getBytes()); sink.write(buffer); send += 1; } else { sink.close(); } status = fill(st); if (status == Status.BIG_PACKET) { log(\(dqerror: packet too big\(dq); break; } assert status == Status.READY; } else { assert status == Status.BAD_PACKET; log(\(dqerror: ill\-formed packet\(dq); break; } } // Check results. assert status == expect; if (status == Status.END) { assert send == st.received; } } public static void main(String []args) throws IOException { test(new String[]{}, Status.END); test(new String[]{\(dqzero;\(dq, \(dqone;\(dq, \(dqtwo;\(dq, \(dqthree;\(dq, \(dqfour;\(dq}, Status.END); test(new String[]{\(dqzer0;\(dq}, Status.BAD_PACKET); test(new String[]{\(dqgoooooooooogle;\(dq}, Status.BIG_PACKET); } }; .ft P .fi .UNINDENT .UNINDENT.SS بلوک‌های با قابلیت استفاده مجدد (Reusable blocks) .sp بلوک‌های با قابلیت استفاده مجدد به شکل \fB/*!rules:re2c[:] ... */\fP یا \fB%{rules[:] ... %}\fP را می‌توان به هر تعداد بار مجدداً استفاده کرد و با سایر بلوک‌های re2java ترکیب نمود. بخش \fB\fP اختیاری است. یک بلوک rules را می‌توان در یک بلوک یا دستورالعمل \fBuse\fP به کار برد. کد یک بلوک rules در هر نقطه‌ای که استفاده شود، تولید می‌گردد. .sp بلوک‌های use با \fB/*!use:re2c[:] ... */\fP یا \fB%{use[:] ... %}\fP\& تعریف می‌شوند. بخش \fB\fP اختیاری است: اگر مشخص نشود، بلوک rules مرتبط جدیدترین بلوک خواهد بود (چه نام‌گذاری شده باشد، چه بدون نام). یک بلوک use می‌تواند تعاریف نام‌دار، پیکربندی‌ها و قوانین مختص به خود را اضافه کند. یک مورد استفاده مهم برای بلوک‌های use، تحلیل‌گر لغوی‌ای است که از چندین کدگذاری ورودی پشتیبانی می‌کند: همان بلوک rules چندین بار با پیکربندی‌های خاص هر کدگذاری استفاده مجدد می‌شود (مثال زیر را ببینید). .sp دستورالعمل درون‌بلوکی \fB!use:;\fP را می‌توان از داخل یک بلوک re2java استفاده کرد. این دستورالعمل بلوک ارجاع‌داده‌شده \fB\fP را در بلوک فعلی ادغام می‌کند. اگر برخی از قوانین و پیکربندی‌های ادغام‌شده با موارد تعریف‌شده پیشین هم‌پوشانی داشته باشند، تداخل‌ها به روش معمول حل‌وفصل می‌شوند: اولین قاعده اولویت دارد و آخرین پیکربندی بر موارد پیشین بازنویسی می‌شود. یک استثنا، قواعد خاص \fB*\fP، \fB$\fP و (در حالت شرط) \fB\fP هستند که برای آن‌ها یک تعریف محلی در بلوک، بر هر تعریف به ارث‌برده‌شده ارجحیت دارد. دستورالعمل use به شخص امکان می‌دهد بلوک‌های مختلف re2java را در یک بلوک با هم ترکیب کند (مثال زیر را ببینید). .sp بلوک‌های نام‌دار و دستورالعمل درون‌بلوکی use در نسخه 2.2 برنامه re2java اضافه شدند. از آن نسخه به بعد، بلوک‌های با قابلیت استفاده مجدد به صورت پیش‌فرض مجاز هستند (نیازی به گزینه خاصی نیست). پیش از نسخه 2.2، حالت استفاده مجدد با گزینه \fB\-r \-\-reusable\fP فعال می‌شد. پیش از نسخه 1.2، بلوک‌های با قابلیت استفاده مجدد نمی‌توانستند با بلوک‌های معمولی ترکیب شوند. .SS مثالی از دستورالعمل \fB!use\fP .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2java $INPUT \-o $OUTPUT // This example shows how to combine reusable re2c blocks: two blocks // (\(aqcolors\(aq and \(aqfish\(aq) are merged into one. The \(aqsalmon\(aq rule occurs // in both blocks; the \(aqfish\(aq block takes priority because it is used // earlier. Default rule * occurs in all three blocks; the local (not // inherited) definition takes priority. /*!rules:re2c:colors * { throw new IllegalArgumentException(\(dqah\(dq); } \(dqred\(dq | \(dqsalmon\(dq | \(dqmagenta\(dq { return Ans.COLOR; } */ /*!rules:re2c:fish * { throw new IllegalArgumentException(\(dqoh\(dq); } \(dqhaddock\(dq | \(dqsalmon\(dq | \(dqeel\(dq { return Ans.FISH; } */ class Main { enum Ans {COLOR, FISH, DUNNO}; static Ans lex(String yyinput) { // no\-throw, as \(aq*\(aq rules are overridden int yycursor = 0; int yymarker = 0; /*!re2c re2c:yyfill:enable = 0; re2c:YYCTYPE = \(dqchar\(dq; re2c:YYPEEK = \(dqyyinput.charAt(yycursor)\(dq; !use:fish; !use:colors; * { return Ans.DUNNO; } // overrides inherited \(aq*\(aq rules */ } public static void main(String []args) { assert lex(\(dqsalmon\(dq) == Ans.FISH; assert lex(\(dqwhat?\(dq) == Ans.DUNNO; } }; .ft P .fi .UNINDENT .UNINDENT.SS نمونه‌ای از یک بلوک \fB/*!use:re2c ... */\fP .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2java $INPUT \-o $OUTPUT \-\-input\-encoding utf8 // This example supports multiple input encodings: UTF\-8 and UTF\-32. // Both lexers are generated from the same rules block, and the use // blocks add only encoding\-specific configurations. /*!rules:re2c re2c:yyfill:enable = 0; re2c:YYPEEK = \(dqyyinput[yycursor]\(dq; re2c:indent:top = 1; \(dq∀x ∃y\(dq { return true; } * { return false; } */ class Main { static boolean lex_utf8(int[] yyinput) { int yycursor = 0; int yymarker = 0; /*!use:re2c re2c:YYCTYPE = \(dqint\(dq; // Java lacks unsigned 8\-bit integer type re2c:encoding:utf8 = 1; */ } static boolean lex_utf32(int[] yyinput) { int yycursor = 0; int yymarker = 0; /*!use:re2c re2c:YYCTYPE = \(dqint\(dq; re2c:encoding:utf32 = 1; */ } public static void main(String []args) { // we have to use \(gaint\(ga, because \(gabyte\(gain Java cannot represent values greater than 127 int[] s_utf8 = new int[]{0xe2, 0x88, 0x80, 0x78, 0x20, 0xe2, 0x88, 0x83, 0x79}; assert lex_utf8(s_utf8); int[] s_utf32 = new int[]{0x2200, 0x78, 0x20, 0x2203, 0x79}; assert lex_utf32(s_utf32); } }; .ft P .fi .UNINDENT .UNINDENT .SS استخراج زیرتطابق (Submatch extraction) .sp ابزار re2java دو گزینه برای استخراج زیرتطابق‌ها دارد. .INDENT 0.0 .TP .B \fBTags\fP نخستین راهکار استفاده از \fIبرچسب‌های\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گروه‌های گیراندازی\fP (capturing groups) است. آن‌ها با گزینهٔ \fB\-\-captures\fP یا پیکربندی \fBre2c:captures = 1\fP فعال می‌شوند. دو حالت برای سیاست‌های مختلف رفع ابهام وجود دارد؛ \fB\-\-leftmost\-captures\fP (پیش‌فرض) برای سیاست چپ‌ترین حریصانه است، و \fB\-\-posix\-captures\fP برای سیاست طولانی‌ترین تطابق پازیکس (POSIX longest\-match) می‌باشد. در این حالت تمام زیرعبارت‌های درون پرانتز، گروه‌های گیرانداز در نظر گرفته می‌شوند، و از علامت تعجب می‌توان برای مشخص کردن گروه‌های غیرگیرانداز استفاده کرد: \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، ابزار re2java متغیرهای \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 برای سیاست طولانی‌ترین تطابق پازیکس. .UNINDENT .sp در پشت صحنه، تمام این گزینه‌ها به برچسب‌ها و \fI\%خودکاره‌های متناهی معین برچسب‌دار با پیش‌نگری\fP (TDFA) ترجمه می‌شوند. ایدهٔ اصلی TDFA به حداقل رساندن بار اضافی (overhead) روی استخراج زیرتطابق است. در حالت نهایی، اگر هیچ برچسب یا گیراندازی‌ای در یک عبارت باقاعده نباشد، TDFA صرفاً یک DFA معمولی خواهد بود. اگر تعداد برچسب‌ها متعادل باشد، بار اضافی به سختی محسوس است. TDFA تولیدشده از تعدادی \fIمتغیر برچسب\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 عمومی (generic 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 پیش‌فرض و هم با API عمومی .IP \(bu 2 الحاق مقدار پیش‌فرض به یک m\-tag: عملیات تعریف‌شده توسط کاربر \fBYYMTAGN(t)\fP هم با API پیش‌فرض و هم با 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 // re2java $INPUT \-o $OUTPUT import java.util.Optional; class Main { static class SemVer { int major; int minor; int patch; public SemVer(int m, int n, int k) { major = m; minor = n; patch = k; } public boolean equals(SemVer v) { return major == v.major && minor == v.minor && patch == v.patch; } }; static Optional parse(String yyinput) { int yycursor = 0; int yymarker = 0; // Final tag variables available in semantic action. /*!svars:re2c format = \(dqint @@;\(dq; */ // Intermediate tag variables used by the lexer (must be autogenerated). /*!stags:re2c format = \(dqint @@ = \-1;\(dq; */ /*!re2c re2c:YYCTYPE = \(dqchar\(dq; re2c:YYPEEK = \(dqyyinput.charAt(yycursor)\(dq; re2c:yyfill:enable = 0; re2c:tags = 1; num = [0\-9]+; @t1 num @t2 \(dq.\(dq @t3 num @t4 (\(dq.\(dq @t5 num)? [\ex00] { int major = Integer.valueOf(yyinput.substring(t1, t2)); int minor = Integer.valueOf(yyinput.substring(t3, t4)); int patch = (t5 == \-1) ? 0 : Integer.valueOf(yyinput.substring(t5, yycursor \- 1)); return Optional.of(new SemVer(major, minor, patch)); } * { return Optional.empty(); } */ } public static void main(String []args) { assert parse(\(dq23.34\e0\(dq).get().equals(new SemVer(23, 34, 0)); assert parse(\(dq1.2.99999\e0\(dq).get().equals(new SemVer(1, 2, 99999)); assert !parse(\(dq1.a\e0\(dq).isPresent(); } }; .ft P .fi .UNINDENT .UNINDENT.sp در اینجا مثال پیچیده‌تری از به‌کارگیری s\-tagها با \fBYYFILL\fP برای تجزیهٔ فایلی با نسخه‌های معنایی (semantic versions) جداشده با خط جدید آمده است. متغیرهای برچسب بخشی از وضعیت لکسر هستند و مانند سایر موقعیت‌های ورودی، در \fBYYFILL\fP تنظیم می‌شوند. توجه داشته باشید که این کار برای s\-tagها ضروری است، چرا که مقادیر آن‌ها پس از جابه‌جایی محتوای بافر باطل می‌شوند. در یک پیاده‌سازی سفارشی که در آن متغیرهای برچسب آفست‌ها را به‌جای بافر نسبت به ابتدای رشتهٔ ورودی ذخیره می‌کنند (که می‌تواند دربارهٔ m\-tagها صدق کند)، ممکن است نیازی به این کار نباشد. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2java $INPUT \-o $OUTPUT import java.io.*; import java.nio.file.*; import java.util.*; class Lexer { static class SemVer { int major; int minor; int patch; public SemVer(int m, int n, int k) { major = m; minor = n; patch = k; } public boolean equals(SemVer v) { return major == v.major && minor == v.minor && patch == v.patch; } }; public static final int BUFSIZE = 4096; private BufferedInputStream stream; private byte[] yyinput; private int yycursor; private int yymarker; private int yylimit; private int token; // Intermediate tag variables used by the lexer (must be autogenerated). /*!stags:re2c format = \(dqprivate int @@;\en\(dq; */ private boolean eof; public Lexer(File file) throws FileNotFoundException { stream = new BufferedInputStream(new FileInputStream(file)); // Sentinel at \(gayylimit\(ga offset is set to zero, which triggers YYFILL. yyinput = new byte[BUFSIZE + 1]; yycursor = yymarker = yylimit = token = BUFSIZE; /*!stags:re2c format = \(dq@@ = \-1;\en\(dq; */ eof = false; } private int fill() throws IOException { if (eof) { return \-1; } // unexpected EOF // Error: lexeme too long. In real life can reallocate a larger buffer. if (token < 1) { return \-2; } // Shift buffer contents (discard everything up to the current token). System.arraycopy(yyinput, token, yyinput, 0, yylimit \- token); yycursor \-= token; yymarker \-= token; yylimit \-= token; /*!stags:re2c format = \(dqif (@@ != \-1) {@@ \-= token;}\en\(dq; */ token = 0; // Fill free space at the end of buffer with new data from file. yylimit += stream.read(yyinput, yylimit, BUFSIZE \- yylimit); yyinput[yylimit] = 0; // append sentinel symbol // If read less than expected, this is the end of input. eof = yylimit < BUFSIZE; return 0; } private int readInt(int tag1, int tag2) { int n = 0; for (int i = tag1; i < tag2; ++i) { n = n * 10 + (yyinput[i] \- 48); } return n; } public Optional> lex() throws IOException { ArrayList vers = new ArrayList(); // Final tag variables available in semantic action. /*!svars:re2c format = \(dqint @@;\(dq; */ loop: while (true) { token = yycursor; /*!re2c re2c:YYCTYPE = \(dqint\(dq; re2c:YYPEEK = \(dqByte.toUnsignedInt(yyinput[yycursor])\(dq; re2c:YYFILL = \(dqfill() == 0\(dq; re2c:eof = 0; re2c:tags = 1; num = [0\-9]+; @t1 num @t2 \(dq.\(dq @t3 num @t4 (\(dq.\(dq @t5 num)? [\en] { int major = readInt(t1, t2); int minor = readInt(t3, t4); int patch = (t5 == \-1) ? 0 : readInt(t5, yycursor \- 1); vers.add(new SemVer(major, minor, patch)); continue loop; } $ { return Optional.of(vers); } * { return Optional.empty(); } */ } } public static void main(String []args) throws FileNotFoundException, IOException { String fname = \(dqinput\(dq; String content = \(dq1.22.333\en\(dq.repeat(Lexer.BUFSIZE); // Prepare input file: a few times the size of the buffer, containing // strings with zeroes and escaped quotes. Files.writeString(Paths.get(fname), content); // Prepare lexer state: all offsets are at the end of buffer. File file = new File(\(dq.\(dq, fname); Lexer lexer = new Lexer(file); // Run the lexer. Optional> vers = lexer.lex(); // Check results. assert vers.isPresent() && vers.get().size() == BUFSIZE; SemVer v = new SemVer(1, 22, 333); for (int i = 0; i < BUFSIZE; ++i) { assert vers.get().get(i).equals(v); } // Cleanup: remove input file. file.delete(); } }; .ft P .fi .UNINDENT .UNINDENT .sp در اینجا مثالی از استفاده از گروه‌های تسخیر (capturing groups) برای تجزیه نسخه‌های معنایی آمده است. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2java $INPUT \-o $OUTPUT import java.util.Optional; class Main { static class SemVer { int major; int minor; int patch; public SemVer(int m, int n, int k) { major = m; minor = n; patch = k; } public boolean equals(SemVer v) { return major == v.major && minor == v.minor && patch == v.patch; } }; static Optional parse(String yyinput) { int yycursor = 0; int yymarker = 0; // Final tag variables available in semantic action. /*!svars:re2c format = \(dqint @@;\(dq; */ // Intermediate tag variables used by the lexer (must be autogenerated). /*!stags:re2c format = \(dqint @@ = \-1;\(dq; */ /*!re2c re2c:YYCTYPE = \(dqchar\(dq; re2c:YYPEEK = \(dqyyinput.charAt(yycursor)\(dq; re2c:yyfill:enable = 0; re2c:captvars = 1; num = [0\-9]+; (num) \(dq.\(dq (num) (\(dq.\(dq num)? [\ex00] { int major = Integer.valueOf(yyinput.substring(yytl1, yytr1)); int minor = Integer.valueOf(yyinput.substring(yytl2, yytr2)); int patch = (yytl3 == \-1) ? 0 : Integer.valueOf(yyinput.substring(yytl3 + 1, yytr3)); return Optional.of(new SemVer(major, minor, patch)); } * { return Optional.empty(); } */ } public static void main(String []args) { assert parse(\(dq23.34\e0\(dq).get().equals(new SemVer(23, 34, 0)); assert parse(\(dq1.2.99999\e0\(dq).get().equals(new SemVer(1, 2, 99999)); assert !parse(\(dq1.a\e0\(dq).isPresent(); } }; .ft P .fi .UNINDENT .UNINDENT.sp در اینجا مثالی از کاربرد m\-tagها برای تجزیه یک نسخه با تعداد متغیری از مؤلفه‌ها آورده شده است. متغیرهای برچسب در یک ترای (trie) ذخیره می‌شوند. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2java $INPUT \-o $OUTPUT import java.util.*; class Main { static Optional parse(String yyinput) { int yycursor = 0; int yymarker = 0; // Final tag variables available in semantic action. /*!svars:re2c format = \(dqint @@;\(dq; */ /*!mvars:re2c format = \(dqList @@;\(dq; */ // Intermediate tag variables used by the lexer (must be autogenerated). /*!stags:re2c format = \(dqint @@ = \-1;\(dq; */ /*!mtags:re2c format = \(dqList @@ = new ArrayList<>();\(dq; */ /*!re2c re2c:YYCTYPE = \(dqchar\(dq; re2c:YYPEEK = \(dqyyinput.charAt(yycursor)\(dq; re2c:YYMTAGP = \(dq@@.add(yycursor);\(dq; re2c:YYMTAGN = \(dq\(dq; // do nothing re2c:yyfill:enable = 0; re2c:tags = 1; num = [0\-9]+; @t1 num @t2 (\(dq.\(dq #t3 num #t4)* [\ex00] { int[] vers = new int[t3.size() + 1]; vers[0] = Integer.valueOf(yyinput.substring(t1, t2)); for (int i = 0; i < t3.size(); ++i) { vers[i + 1] = Integer.valueOf(yyinput.substring(t3.get(i), t4.get(i))); } return Optional.of(vers); } * { return Optional.empty(); } */ } public static void main(String []args) { assert Arrays.equals(parse(\(dq1\e0\(dq).get(), new int[]{1}); assert Arrays.equals(parse(\(dq1.2.3.4.5.6.7\e0\(dq).get(), new int[]{1, 2, 3, 4, 5, 6, 7}); assert !parse(\(dq1.2.\e0\(dq).isPresent(); } }; .ft P .fi .UNINDENT .UNINDENT .SS پشتیبانی از کدگذاری (Encoding support) .sp درک تفاوت بین \fBنقطه‌کدها\fP (code points) و \fBواحدکدها\fP (code units) ضروری است\&. یک نقطه‌کد، یک شناسه عددی برای یک نماد است. یک واحدکد، کوچک‌ترین واحد ذخیره‌سازی در متن کدگذاری‌شده است. یک نقطه‌کد منفرد ممکن است با یک یا چند واحدکد نشان داده شود. در یک کدگذاری با طول ثابت، همه نقطه‌کدها با تعداد یکسانی از واحدکدها نمایش داده می‌شوند. در یک کدگذاری با طول متغیر، نقطه‌کدها ممکن است با تعداد متفاوتی از واحدکدها نشان داده شوند. توجه داشته باشید که قاعده «هر چیز» \fB[^]\fP با هر نقطه‌کدی مطابقت دارد، اما لزوماً با هر واحدکدی منطبق نمی‌شود (تنها راه برای تطبیق با هر واحدکد بدون در نظر گرفتن نوع کدگذاری، قاعده پیش‌فرض \fB*\fP است). تحلیل‌گر لغوی تولیدشده با جریانی از واحدکدها کار می‌کند: \fByych\fP یک واحدکد را ذخیره می‌کند، و \fBYYCTYPE\fP نوع واحدکد است. از سوی دیگر، عبارت‌های منظم بر اساس نقطه‌کدها مشخص می‌شوند. هنگامی که re2java عبارت‌های منظم را به اتوماتا کامپایل می‌کند، نقطه‌کدها را به واحدکدها ترجمه می‌نماید. این کار معمولاً یک نگاشت ساده نیست: در کدگذاری‌های با طول متغیر، بازه‌ای از یک نقطه‌کد منفرد ممکن است به یک گراف پیچیده از واحدکدها تبدیل شود. کدگذاری‌های زیر پشتیبانی می‌شوند: .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 تعاریف re2java را برای بلوک‌ها، دسته‌بندی‌ها و ویژگی‌های توصیف‌شده در استاندارد یونیکد ارائه می‌دهند. .sp گزینه \fB\-\-input\-encoding\fP کدگذاری فایل مبدأ را مشخص می‌کند که می‌تواند برای فعال‌سازی لیترال‌های یونیکد در عبارت‌های منظم به کار رود. برای مثال \fB\-\-input\-encoding utf8\fP به re2java اعلام می‌کند که فایل مبدأ با کدگذاری UTF8 است (این گزینه با \fB\-\-utf8\fP که کدگذاری متن ورودی را تعیین می‌کند متفاوت است). گزینه \fB\-\-encoding\-policy\fP شیوه‌ای را که re2java جانشین‌های یونیکد (نقطه‌کدهای موجود در بازه \fB[0xD800\-0xDFFF]\fP) را مدیریت می‌کند مشخص می‌سازد. .sp در زیر مثالی از یک تحلیل‌گر لغوی برای شناسه‌های یونیکد کدگذاری‌شده با UTF8 آمده است. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2java $INPUT \-o $OUTPUT \-\-utf8 \-s /*!include:re2c \(dqunicode_categories.re\(dq */ class Main { static boolean lex(String yyinput) { int yycursor = 0; int yymarker = 0; /*!re2c re2c:YYCTYPE = \(dqchar\(dq; re2c:YYPEEK = \(dqyyinput.charAt(yycursor)\(dq; re2c:yyfill:enable = 0; // Simplified \(dqUnicode Identifier and Pattern Syntax\(dq // (see https://unicode.org/reports/tr31) id_start = L | Nl | [$_]; id_continue = id_start | Mn | Mc | Nd | Pc | [\eu200D\eu05F3]; identifier = id_start+; // It should be \(gaid_start id_continue*\(ga, but that causes \(gaerror: code too large\(ga identifier { return true; } * { return false; } */ } public static void main(String []args) { assert lex(\(dq_Ыдентификатор\e0\(dq); } }; .ft P .fi .UNINDENT .UNINDENT.SS فایل‌های الحاقی (Include files) .sp ابزار re2java به شما امکان می‌دهد با استفاده از بلوکی به قالب \fB/*!include:re2c FILE */\fP یا \fB%{include FILE %}\fP، یا دستور درون‌بلوکی \fB!include FILE ;\fP فایل‌های دیگر را بگنجانید، که در آن \fBFILE\fP مسیر فایلی است که باید گنجانده شود. ابزار re2java فایل‌های الحاقی را در دایرکتوریِ فایلی که عمل الحاق را انجام داده و همچنین در مکان‌های include که می‌توان آن‌ها را با گزینهٔ \fB\-I\fP تعیین کرد، جستجو می‌کند. بلوک‌ها/دستورهای include در re2java همانند \fB#include\fP در C/C++ عمل می‌کنند: محتوای \fBFILE\fP عیناً و بدون تغییر در جای بلوک/دستور قرار می‌گیرد. فایل‌های الحاقی می‌توانند خود شامل موارد include دیگری باشند. از گزینهٔ \fB\-\-depfile\fP برای ردگیری وابستگی‌های ساخت فایل خروجی به فایل‌های الحاقی استفاده کنید. ابزار re2java تعدادی فایل الحاقی از پیش‌تعریف‌شده ارائه می‌دهد که در زیردایرکتوری \fBinclude/\fP پروژه یافت می‌شوند. این فایل‌ها شامل تعاریفی هستند که ممکن است برای سایر پروژه‌ها نیز مفید باشند (مانند دسته‌بندی‌های یونیکد) و ساختاری شبیه به یک کتابخانهٔ استاندارد برای re2java تشکیل می‌دهند\&. در ادامه مثالی از کاربرد فایل‌های الحاقی آورده شده است. .SS فایل الحاقی ۱ (definitions.java) .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C /*!re2c number = [1\-9][0\-9]*; */ .ft P .fi .UNINDENT .UNINDENT .SS فایل الحاقی ۲ (extra_rules.re.inc) .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // floating\-point numbers frac = [0\-9]* \(dq.\(dq [0\-9]+ | [0\-9]+ \(dq.\(dq; exp = \(aqe\(aq [+\-]? [0\-9]+; float = frac exp? | [0\-9]+ exp; float { return Num.FLOAT; } .ft P .fi .UNINDENT .UNINDENT .SS فایل ورودی (Input file) .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2java $INPUT \-o $OUTPUT /*!include:re2c \(dqdefinitions.java\(dq */ class Main { enum Num {INT, FLOAT, NAN}; static Num lex(String yyinput) { int yycursor = 0; int yymarker = 0; /*!re2c re2c:YYCTYPE = \(dqchar\(dq; re2c:YYPEEK = \(dqyyinput.charAt(yycursor)\(dq; re2c:yyfill:enable = 0; * { return Num.NAN; } number { return Num.INT; } !include \(dqextra_rules.re.inc\(dq; */ } public static void main(String []args) { assert lex(\(dq123\e0\(dq) == Num.INT; assert lex(\(dq123.4567\e0\(dq) == Num.FLOAT; } }; .ft P .fi .UNINDENT .UNINDENT.SS "فایل‌های هدر (Header files)" .sp ابزار re2java امکان تولید فایل هدر از فایل ورودی \fB\&.re\fP را با استفاده از گزینهٔ \fB\-\-header\fP یا پیکربندی \fBre2c:header\fP و جفت‌بلوک‌هایی به شکل \fB/*!header:re2c:on*/\fP و \fB/*!header:re2c:off*/\fP، یا \fB%{header:on%}\fP و \fB%{header:off%}\fP فراهم می‌کند\&. بلوک نخست آغاز فایل هدر و بلوک دوم پایان آن را مشخص می‌کند. تمام موارد میان این بلوک‌ها توسط re2java پردازش شده و کد تولیدشده در فایلی که با گزینهٔ \fB\-\-header\fP یا پیکربندی \fBre2c:header\fP تعیین شده (یا در صورت عدم استفاده از گزینه یا پیکربندی، در \fBstdout\fP) نوشته می‌شود. تولید خودکار فایل هدر ممکن است در مواردی نیاز باشد که از re2java برای ایجاد تعاریفی استفاده می‌شود که باید از سایر واحدهای ترجمه (translation units) قابل دسترسی باشند. .sp در ادامه مثالی از تولید یک فایل هدر آورده شده است که شامل تعریف وضعیت تحلیل‌گر لغوی (lexer state) به همراه متغیرهای برچسب (tag variables) است (تعداد متغیرها به گرامر باقاعده بستگی داشته و برای برنامه‌نویس نامشخص است). .SS "فایل ورودی (Input file)" .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // re2java $INPUT \-o $OUTPUT \-\-header lexer/state.java package headers; import headers.lexer.State; /*!header:re2c:on*/ package headers.lexer; public class State { public String yyinput; public int yycursor; /*!stags:re2c format = \(dqpublic int @@;\en\(dq; */ public State(String str) { yyinput = str; yycursor = 0; /*!stags:re2c format = \(dq@@ = 0;\en\(dq; */ } }; /*!header:re2c:off*/ class Main { static int lex(String str) { State yyrecord = new State(str); int t; /*!re2c re2c:api = record; re2c:tags = 1; re2c:yyfill:enable = 0; re2c:YYCTYPE = \(dqchar\(dq; re2c:YYPEEK = \(dqyyrecord.yyinput.charAt(yyrecord.yycursor)\(dq; re2c:header = \(dqlexer/state.java\(dq; [a]* @t [b]* { return t; } */ } public static void main(String []args) { assert lex(\(dqab\e0\(dq) == 1; } }; .ft P .fi .UNINDENT .UNINDENT .SS "فایل هدر (Header file)" .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C // Generated by re2c package headers.lexer; public class State { public String yyinput; public int yycursor; public int yyt1; public State(String str) { yyinput = str; yycursor = 0; yyt1 = 0; } }; .ft P .fi .UNINDENT .UNINDENT.SS برنامه‌های اسکلتی (Skeleton programs) .sp با گزینهٔ \fB\-S, \-\-skeleton\fP، ابزار re2java تمام کدهای غیر re2java را نادیده گرفته و یک برنامهٔ C خودکفا و مستقل تولید می‌کند که می‌تواند در ادامه کامپایل و اجرا شود. این برنامه از کد تحلیل‌گر لغوی (lexer) و داده‌های ورودی تشکیل شده است. به ازای هر DFA ساخته‌شده (بلوک یا شرط)، re2java یک تحلیل‌گر لغوی مستقل و دو فایل تولید می‌کند: یک فایل \fB\&.input\fP با رشته‌های مشتق‌شده از DFA و یک فایل \fB\&.keys\fP با نتایج تطابق مورد انتظار. این برنامه هر تحلیل‌گر لغوی را روی فایل \fB\&.input\fP متناظر اجرا کرده و نتایج را با انتظارات مقایسه می‌کند. برنامه‌های اسکلتی به دلایل متعددی بسیار مفید هستند: .INDENT 0.0 .IP \(bu 2 آن‌ها می‌توانند درستی بهینه‌سازی‌های گوناگون re2java را بررسی کنند (داده‌ها در اوایل فرآیند و پیش از اعمال هرگونه تغییر و تبدیل در DFA تولید می‌شوند). .IP \(bu 2 تولید مجموعه‌ای از داده‌های ورودی با پوشش مناسب می‌تواند هم برای آزمون و هم برای سنجش کارایی (benchmarking) مفید باشد. .IP \(bu 2 تولید برنامه‌های اجرایی مستقل امکان دسترسی به نمونه‌های آزمون کمینه‌شده را فراهم می‌کند (کد اصلی ممکن است بزرگ بوده یا وابستگی‌های فراوانی داشته باشد). .UNINDENT .sp دشواری تولید داده‌های ورودی در این است که به جز در ساده‌ترین حالت‌ها، تعداد رشته‌های ورودیِ ممکن بیش از حد زیاد است (حتی اگر طول رشته محدود باشد). re2java این دشواری را با تولید رشته‌های کافی برای پوشش دادن تقریباً تمام انتقال‌های DFA برطرف می‌کند. این ابزار از الگوریتم زیر استفاده می‌کند. نخست، اسکلتی از DFA می‌سازد. برای رمزگذاری‌هایی با اندازهٔ واحد کد ۱ بایتی (مانند ASCII، UTF\-8 و EBCDIC) اسکلت صرفاً یک رونوشت دقیق از DFA اصلی است. برای رمزگذاری‌هایی با واحدهای کد چندبایتی، اسکلت رونوشتی از DFA با حذف برخی از انتقال‌ها است: بدین صورت که re2java حداکثر ۲۵۶ واحد کد را برای هر بازهٔ پیوسته و مجزا که با یک انتقال DFA متناظر است، در نظر می‌گیرد. مقادیر انتخاب‌شده به طور یکنواخت توزیع شده و شامل کران‌های بازه نیز هستند. به جای تلاش برای پوشش تمام مسیرهای ممکن در اسکلت (که نشدنی است)، re2java مسیرهای کافی برای پوشش تمام انتقال‌های اسکلت تولید می‌کند تا بدین ترتیب پرش‌های شرطی مربوطه در تحلیل‌گر لغوی فعال شوند. پیاده‌سازی این الگوریتم به حدود ۱ گیگابایت انتقال محدود شده و مقدار ثابتی حافظه مصرف می‌کند (re2java داده‌ها را به محض تولید در فایل می‌نویسد). .SS مصورسازی و اشکال‌زدایی (Visualization and debug) .sp با گزینهٔ \fB\-D, \-\-emit\-dot\fP، ابزار re2java کدی تولید نمی‌کند؛ در عوض، DFA تولیدشده را در قالب DOT ذخیره (dump) می‌کند. می‌توان این خروجی را با استفاده از Graphviz یا کتابخانه‌ای دیگر به تصویری از DFA تبدیل کرد. توجه داشته باشید که این گزینه DFA نهایی را پس از گذراندن شماری از بهینه‌سازی‌ها و تبدیلات نمایش می‌دهد. مراحل اولیه را می‌توان با گزینه‌های اشکال‌زدایی مختلفی مانند \fB\-\-dump\-nfa\fP، \fB\-\-dump\-dfa\-raw\fP و غیره ذخیره کرد (فهرست کامل گزینه‌ها را ببینید). .SH "همچنین ببینید (SEE ALSO)" .sp می‌توانید اطلاعات بیشتری دربارهٔ re2c در وبگاه رسمی بیابید: \fI\%http://re2c.org\fP\&. برنامه‌های مشابه عبارتند از flex(1)، lex(1)، quex(\fI\%http://quex.sourceforge.net\fP). .SH "نویسندگان (AUTHORS)" .sp برنامهٔ re2java در ابتدا توسط 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. .