.\" 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 "RE2HS" 1 "" "" "" .SH "نام (NAME)" re2hs \- تولید تحلیل‌گرهای لغوی سریع برای Haskell .SH "خلاصه دستور (SYNOPSIS)" .sp re2hs \fB[ OPTIONS ]\fP \fB[ WARNINGS ]\fP \fBINPUT\fP .sp ورودی می‌تواند یک فایل یا \fB\-\fP برای stdin باشد. .SH "مقدمه (INTRODUCTION)" .sp ابزار re2hs به عنوان یک پیش‌پردازنده عمل می‌کند. این ابزار فایل ورودی را (که معمولاً یک برنامه به زبان Haskell است، اما می‌تواند هر چیز دیگری نیز باشد) خوانده و به دنبال بلوک‌های کدی می‌گردد که در نشانگرهای آغاز/پایان با ساختار ویژه محصور شده‌اند. متن‌های خارج از این بلوک‌ها عیناً در فایل خروجی کپی می‌شوند. محتویات درون بلوک‌ها توسط re2hs پردازش می‌شوند. این ابزار آن‌ها را به کد Haskell ترجمه کرده و کد تولیدشده را به جای بلوک اصلی در خروجی قرار می‌دهد. .sp در ادامه مثالی از یک برنامه کوچک آورده شده است که بررسی می‌کند آیا یک رشته داده‌شده حاوی یک عدد ده‌دهی است یا خیر: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C \-\- re2hs $INPUT \-o $OUTPUT \-i {\-# LANGUAGE OverloadedStrings #\-} {\-# OPTIONS_GHC \-Wno\-unused\-record\-wildcards #\-} import Data.ByteString (ByteString, index) data State = State { _yyinput :: ByteString, _yycursor :: Int } %{ re2c:YYFN = [\(dqlexer;Bool\(dq, \(dqState{..};State\(dq]; re2c:yyfill:enable = 0; [1\-9][0\-9]* { True } * { False } %} main :: IO () main = case lexer State{_yyinput = \(dq1234\e0\(dq, _yycursor = 0} of True \-> return () False \-> error \(dqlexer failed!\(dq .ft P .fi .UNINDENT .UNINDENT .sp در خروجی، re2hs بلوک میانی را با کد تولیدشده جایگزین کرده است: .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C \-\- Generated by re2hs {\-# LANGUAGE RecordWildCards #\-} \-\- re2hs $INPUT \-o $OUTPUT \-i {\-# LANGUAGE OverloadedStrings #\-} {\-# OPTIONS_GHC \-Wno\-unused\-record\-wildcards #\-} import Data.ByteString (ByteString, index) data State = State { _yyinput :: ByteString, _yycursor :: Int } yy0 :: State \-> Bool yy0 State{..} = let yych = index _yyinput _yycursor in let __ = _yycursor + 1 in let _yycursor = __ in case yych of _c | 0x31 <= _c && _c <= 0x39 \-> yy2 State{..} _c | True \-> yy1 State{..} yy1 :: State \-> Bool yy1 State{..} = False yy2 :: State \-> Bool yy2 State{..} = let yych = index _yyinput _yycursor in case yych of _c | 0x30 <= _c && _c <= 0x39 \-> let __ = _yycursor + 1 in let _yycursor = __ in yy2 State{..} _c | True \-> yy3 State{..} yy3 :: State \-> Bool yy3 State{..} = True lexer :: State \-> Bool lexer State{..} = yy0 State{..} main :: IO () main = case lexer State{_yyinput = \(dq1234\e0\(dq, _yycursor = 0} of True \-> return () False \-> error \(dqlexer failed!\(dq .ft P .fi .UNINDENT .UNINDENT.SH "مبانی (BASICS)" .sp یک برنامه re2hs از توالی‌ای از \fIبلوک‌ها\fP آمیخته با کد زبان مقصد تشکیل شده است. یک بلوک می‌تواند شامل \fIتعاریف\fP، \fIپیکربندی‌ها\fP، \fIقواعد\fP، \fIکنش‌ها\fP و \fIدستورالعمل‌ها\fP با هر ترتیبی باشد: .INDENT 0.0 .TP .B \fBname = regular\-expression ;\fP یک \fIتعریف\fP، \fBname\fP را به \fBregular\-expression\fP مقید می‌کند\&. نام‌ها می‌توانند شامل نویسه‌های الفبایی\-عددی و خط زیرین باشند. بخش \fI\%regular expressions\fP مروری بر نحو re2hs برای عبارت‌های منظم ارائه می‌دهد. پس از تعریف، \fBname\fP می‌تواند در سایر عبارت‌های منظم و قواعد استفاده شود. بازگشت (توابع بازگشتی) در تعاریف نام‌گذاری‌شده مجاز نیست و هر نام باید پیش از استفاده تعریف شود. یک بلوک تعاریف نام‌گذاری‌شده را از حوزه سراسری (global scope) به ارث می‌برد. بازتعریف نامی که در حوزه فعلی وجود دارد یک خطا است. .TP .B \fBconfiguration = value ;\fP یک \fIپیکربندی\fP امکان تغییر رفتار re2hs و شخصی‌سازی کد تولید‌شده را فراهم می‌سازد. برای دیدن فهرست کاملی از پیکربندی‌های پشتیبانی‌شده توسط re2hs به بخش \fI\%configurations\fP مراجعه کنید. بسته به نوع پیکربندی، \fBvalue\fP می‌تواند یک کلیدواژه، یک عدد صحیح غیرمنفی یا یک رشته تک‌خطی باشد که باید درون گیومه تکی یا جفتی قرار گیرد مگر اینکه فقط از نویسه‌های الفبایی\-عددی تشکیل شده باشد. یک بلوک پیکربندی‌ها را از حوزه سراسری به ارث می‌برد و می‌تواند آن‌ها را بازتعریف کرده یا موارد جدیدی را بیفزاید. پیکربندی‌های تعریف‌شده درون یک بلوک بر کل بلوک تأثیر می‌گذارند، حتی اگر در انتهای آن قرار داشته باشند. .TP .B \fBregular\-expression code\fP یک \fIقاعده\fP، \fBregular\-expression\fP را به کنش معنایی آن (یک بلوک کد درون آکولاد، یا یک بلوک کد که با \fB:=\fP آغاز شده و در یک خط جدید و به دنبال آن هر نویسه غیر فاصله خاتمه می‌یابد) مقید می‌کند. اگر \fBregular\-expression\fP تطبیق یابد، \fBcode\fP مرتبط اجرا می‌شود. اگر چند قاعده تطبیق یابند، طولانی‌ترین تطبیق اولویت دارد. اگر چند قاعده با یک رشته یکسان تطبیق یابند، اولین قاعده اولویت دارد. دو قاعده ویژه وجود دارد: قاعده پیش‌فرض \fB*\fP و قاعده پایان ورودی \fB$\fP\&. قاعده پیش‌فرض باید همیشه تعریف شود، صرف‌نظر از موقعیتش در بلوک کمترین اولویت را دارد و با هر واحد کد مطابقت می‌یابد (نه لزوماً یک نویسه معتبر، به بخش \fI\%encoding support\fP مراجعه کنید). قاعده پایان ورودی باید در صورتی تعریف شود که متد متناظر برای \fI\%handling the end of input\fP به کار رفته باشد. با فعال بودن \fI\%start conditions\fP، قواعد نحو پیچیده‌تری خواهند داشت. .TP .B \fB!action code\fP یک \fIکنش\fP یک بلوک تعریف‌شده توسط کاربر از \fBcode\fP را به یک مکان خاص در ماشین حالت متناهی تولیدشده متصل می‌کند (به همان شیوه‌ای که کنش‌های معنایی کد را به حالت‌های پایانی پیوند می‌دهند). برای فهرست کامل کنش‌های از پیش تعریف‌شده به بخش \fI\%actions\fP مراجعه کنید. .TP .B \fB!directive ;\fP یک \fIدستورالعمل\fP یکی از گزاره‌های خاص از پیش تعریف‌شده است. هر دستورالعمل یک هدف منحصربه‌فرد دارد. برای جزئیات به بخش \fI\%directives\fP مراجعه کنید. .UNINDENT .SS "بلوک‌ها (Blocks)" .sp نشانگرهای شروع و پایان بلوک یا \fB/*!re2c\fP و \fB*/\fP هستند، یا \fB%{\fP و \fB%}\fP (از هر دو سبک پشتیبانی می‌شود). از نسخه 2.2 بلوک‌ها می‌توانند نام‌های اختیاری داشته باشند که امکان ارجاع به آن‌ها در بلوک‌های دیگر را فراهم می‌کند. انواع گوناگونی از بلوک‌ها وجود دارد: .INDENT 0.0 .TP .B \fB/*!re2c[:] ... */\fP or \fB%{[:] ... %}\fP یک \fIبلوک سراسری\fP شامل تعاریف، پیکربندی‌ها، قواعد و دستورالعمل‌ها است. re2hs عبارت‌های منظم مرتبط با هر قاعده را به یک اتوماتون متناهی معین (DFA) کامپایل می‌کند، آن را به شکل پرش‌های شرطی در زبان مقصد کدگذاری کرده و بلوک را با کد تولیدشده جایگزین می‌کند. نام‌ها و پیکربندی‌های تعریف‌شده در یک بلوک سراسری به حوزه سراسری اضافه می‌شوند و برای بلوک‌های بعدی قابل مشاهده خواهند بود. در آغاز برنامه حوزه سراسری با \fI\%options\fP خط فرمان مقداردهی اولیه می‌شود. .TP .B \fB/*!local:re2c[:] ... */\fP or \fB%{local[:] ... %}\fP یک \fIبلوک محلی\fP مانند یک بلوک سراسری است، اما نام‌ها و پیکربندی‌های درون آن دارای حوزه محلی هستند (بر سایر بلوک‌ها تأثیری نمی‌گذارند). .TP .B \fB/*!rules:re2c[:] ... */\fP or \fB%{rules[:] ... %}\fP یک \fIبلوک قواعد\fP شبیه یک بلوک محلی است، اما خودش به تنهایی کدی تولید نمی‌کند و هیچ تعریفی را به حوزه سراسری اضافه نمی‌نماید \-\- هدف آن استفاده مجدد در سایر بلوک‌ها است. این یک روش برای به اشتراک‌گذاری کد است (جزئیات بیشتر در بخش \fI\%reusable blocks\fP). پیش از نسخه 2.2 re2hs، بلوک‌های قواعد نیازمند گزینه \fB\-r \-\-reusable\fP بودند. .TP .B \fB/*!use:re2c[:] ... */\fP or \fB%{use[:] ... %}\fP یک بلوک use که به یک بلوک قواعد از پیش تعریف‌شده ارجاع می‌دهد. اگر نام مشخص شده باشد، re2hs به دنبال یک بلوک قواعد با این نام می‌گردد. در غیر این صورت آخرین بلوک قواعد استفاده می‌شود (خواه نام‌گذاری‌شده باشد یا بدون نام). یک بلوک use می‌تواند تعاریف، پیکربندی‌ها و قواعد خاص خود را بیفزاید که به موارد بلوک قواعد مرجع اضافه می‌شوند. پیش از نسخه 2.2 re2hs، بلوک‌های 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 تولیدشده توسط re2hs بسط داده می‌شود\&. یک فهرست اختیاری از نام بلوک‌ها مشخص می‌کند که هنگام محاسبه مجموعه متغیرهای تگ کدام بلوک‌ها باید گنجانده شوند (اگر فهرست خالی باشد، تمام بلوک‌ها لحاظ می‌شوند). دو پیکربندی اختیاری وجود دارد: \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) یا به‌طور ضمنی توسط re2hs تولید شده است (با گزینه‌های \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 ناسازگار است، چرا که نیازمند انتقال‌های میان‌بلوکی (cross\-block) است که بدون \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 برای تولید وابستگی‌های سیستم ساخت (build system) به فایل‌های پیوست‌شده به کار رود. .TP .B \fB/*!header:re2c:on*/\fP or \fB%{header:on %}\fP این بلوک شروع فایل هدر را مشخص می‌کند. همه چیز پس از آن و تا بلوک بعدی \fBheader:off\fP توسط re2hs پردازش شده و در فایل هدر مشخص‌شده با گزینه \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 در ادامه فهرست کاملی از پیکربندی‌های پشتیبانی‌شده توسط re2hs آمده است: .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) ارائه می‌شوند، نه برای زمینهٔ کلی تحلیل‌گر لغوی (lexer)؛ بنابراین اولیه‌ها رفتاری شبیه به ماکروها در C/C++ یا بستارها (closures) در Go و Rust دارند. در سبک free\-form، اولیه‌های API شکل ثابتی ندارند: آن‌ها باید به عنوان رشته‌هایی حاوی قطعه‌کدهای آزاد با متغیرهای الحاقی (interpolated) به شکل \fB@@{var}\fP یا \fB@@\fP تعریف شوند (این‌ها متناظر با آرگومان‌ها در سبک تابع‌گونه هستند). این پیکربندی ممکن است برای اولیه‌های جداگانهٔ API بازنویسی شود؛ برای نمونه به پیکربندی \fBre2c:YYFILL:naked\fP برای \fBYYFILL\fP مراجعه کنید\&. .TP .B \fBre2c:bit\-vectors\fP, \fBre2c:flags:bit\-vectors\fP, \fBre2c:flags:b\fP مشابه گزینهٔ \fB\-\-bit\-vectors\fP، اما می‌تواند بر پایهٔ هر بلوک به‌طور جداگانه پیکربندی شود. .TP .B \fBre2c:captures\fP, \fBre2c:leftmost\-captures\fP مشابه گزینهٔ \fB\-\-leftmost\-captures\fP، اما می‌تواند بر پایهٔ هر بلوک به‌طور جداگانه پیکربندی شود. .TP .B \fBre2c:captvars\fP, \fBre2c:leftmost\-captvars\fP مشابه گزینهٔ \fB\-\-leftmost\-captvars\fP، اما می‌تواند بر پایهٔ هر بلوک به‌طور جداگانه پیکربندی شود. .TP .B \fBre2c:case\-insensitive\fP, \fBre2c:flags:case\-insensitive\fP مشابه گزینهٔ \fB\-\-case\-insensitive\fP، اما می‌تواند بر پایهٔ هر بلوک به‌طور جداگانه پیکربندی شود. .TP .B \fBre2c:case\-inverted\fP, \fBre2c:flags:case\-inverted\fP مشابه گزینهٔ \fB\-\-case\-inverted\fP، اما می‌تواند بر پایهٔ هر بلوک به‌طور جداگانه پیکربندی شود. .TP .B \fBre2c:case\-ranges\fP, \fBre2c:flags:case\-ranges\fP مشابه گزینهٔ \fB\-\-case\-ranges\fP، اما می‌تواند بر پایهٔ هر بلوک به‌طور جداگانه پیکربندی شود. .TP .B \fBre2c:computed\-gotos\fP, \fBre2c:flags:computed\-gotos\fP, \fBre2c:flags:g\fP مشابه گزینهٔ \fB\-\-computed\-gotos\fP، اما می‌تواند بر پایهٔ هر بلوک به‌طور جداگانه پیکربندی شود. .TP .B \fBre2c:computed\-gotos:relative\fP, \fBre2c:cgoto:relative\fP مشابه گزینهٔ \fB\-\-computed\-gotos\-relative\fP، اما می‌تواند بر پایهٔ هر بلوک به‌طور جداگانه پیکربندی شود. .TP .B \fBre2c:computed\-gotos:threshold\fP, \fBre2c:cgoto:threshold\fP اگر از \fBgoto\fPی محاسبه‌شده استفاده شود، این پیکربندی آستانهٔ پیچیدگی را مشخص می‌کند که باعث تولید جدول‌های پرش به جای دستورهای تودرتوی \fBif\fP و نگاشت‌های بیتی (bitmaps) می‌شود. مقدار پیش‌فرض \fB9\fP است\&. .TP .B \fBre2c:cond:abort\fP اگر روی یک مقدار عدد صحیح مثبت تنظیم شود، حالت پیش‌فرض (default case) در توزیع شرط تولیدشده، اجرای برنامه را متوقف (abort) می‌کند. .TP .B \fBre2c:cond:goto\fP قطعه‌کد مورد استفاده برای قواعد میان‌بر خودکار تولیدشدهٔ \fB:=>\fP در شرط‌ها را مشخص می‌کند. مقدار پیش‌فرض \fBgoto @@;\fP است\&. جای‌نگه‌دار \fB@@\fP با نام شرط جایگزین می‌شود (پیکربندی‌های \fBre2c:api:sigil\fP و \fBre2c:cond:goto@cond\fP را ببینید)\&. .TP .B \fBre2c:cond:goto@cond\fP نشانگر مورد استفاده برای جایگزینی آرگومان در تعریف \fBre2c:cond:goto\fP را مشخص می‌کند. مقدار پیش‌فرض \fB@@\fP است\&. پیکربندی عمومی‌تر \fBre2c:api:sigil\fP را لغو و بازنویسی می‌کند\&. .TP .B \fBre2c:cond:divider\fP جداکنندهٔ بلوک‌های شرط را تعیین می‌کند. مقدار پیش‌فرض \fB/* *********************************** */\fP است\&. جای‌نگه‌دارها با نام شرط جایگزین می‌شوند (\fBre2c:api;sigil\fP و \fBre2c:cond:divider@cond\fP را ببینید)\&. .TP .B \fBre2c:cond:divider@cond\fP نشانگر مورد استفاده برای جایگزینی آرگومان در تعریف \fBre2c:cond:divider\fP را مشخص می‌کند. مقدار پیش‌فرض \fB@@\fP است\&. پیکربندی عمومی‌تر \fBre2c:api:sigil\fP را لغو و بازنویسی می‌کند\&. .TP .B \fBre2c:cond:prefix\fP, \fBre2c:condprefix\fP پیشوند مورد استفاده برای برچسب‌های شرط را مشخص می‌کند. مقدار پیش‌فرض \fByyc_\fP است\&. .TP .B \fBre2c:cond:enumprefix\fP, \fBre2c:condenumprefix\fP پیشوند مورد استفاده برای شناسه‌های شرط را مشخص می‌کند. مقدار پیش‌فرض \fByyc\fP است\&. .TP .B \fBre2c:debug\-output\fP, \fBre2c:flags:debug\-output\fP, \fBre2c:flags:d\fP مشابه گزینهٔ \fB\-\-debug\-output\fP، اما می‌تواند بر پایهٔ هر بلوک به‌طور جداگانه پیکربندی شود. .TP .B \fBre2c:empty\-class\fP, \fBre2c:flags:empty\-class\fP مشابه گزینهٔ \fB\-\-empty\-class\fP، اما می‌تواند بر پایهٔ هر بلوک به‌طور جداگانه پیکربندی شود. .TP .B \fBre2c:encoding:ebcdic\fP, \fBre2c:flags:ecb\fP, \fBre2c:flags:e\fP مشابه گزینهٔ \fB\-\-ebcdic\fP، اما می‌تواند بر پایهٔ هر بلوک به‌طور جداگانه پیکربندی شود. .TP .B \fBre2c:encoding:ucs2\fP, \fBre2c:flags:wide\-chars\fP, \fBre2c:flags:w\fP مشابه گزینهٔ \fB\-\-ucs2\fP، اما می‌تواند بر پایهٔ هر بلوک به‌طور جداگانه پیکربندی شود. .TP .B \fBre2c:encoding:utf8\fP, \fBre2c:flags:utf\-8\fP, \fBre2c:flags:8\fP مشابه گزینهٔ \fB\-\-utf8\fP، اما می‌تواند بر پایهٔ هر بلوک به‌طور جداگانه پیکربندی شود. .TP .B \fBre2c:encoding:utf16\fP, \fBre2c:flags:utf\-16\fP, \fBre2c:flags:x\fP مشابه گزینهٔ \fB\-\-utf16\fP، اما می‌تواند بر پایهٔ هر بلوک به‌طور جداگانه پیکربندی شود. .TP .B \fBre2c:encoding:utf32\fP, \fBre2c:flags:unicode\fP, \fBre2c:flags:u\fP مشابه گزینهٔ \fB\-\-utf32\fP، اما می‌تواند بر پایهٔ هر بلوک به‌طور جداگانه پیکربندی شود. .TP .B \fBre2c:encoding\-policy\fP, \fBre2c:flags:encoding\-policy\fP مشابه گزینهٔ \fB\-\-encoding\-policy\fP، اما می‌تواند بر پایهٔ هر بلوک به‌طور جداگانه پیکربندی شود. .TP .B \fBre2c:eof\fP نماد نگهبان (sentinel symbol) مورد استفاده با قاعدهٔ پایان ورودی \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 است\&. رشتهٔ تورفتگی باید تنها شامل نویسه‌های فاصله خالی (whitespace) باشد. برای غیرفعال کردن کامل تورفتگی، این پیکربندی را روی یک رشتهٔ خالی تنظیم کنید. .TP .B \fBre2c:indent:top\fP حداقل مقدار تورفتگی مورد استفاده را مشخص می‌کند. مقدار پیش‌فرض صفر است. این مقدار باید یک عدد صحیح نامنفی باشد. .TP .B \fBre2c:invert\-captures\fP مشابه گزینهٔ \fB\-\-invert\-captures\fP، اما می‌تواند بر پایهٔ هر بلوک به‌طور جداگانه پیکربندی شود. .TP .B \fBre2c:label:prefix\fP, \fBre2c:labelprefix\fP پیشوند مورد استفاده برای برچسب‌های وضعیت DFA را مشخص می‌کند. مقدار پیش‌فرض \fByy\fP است\&. .TP .B \fBre2c:label:start\fP, \fBre2c:startlabel\fP تولید برچسب شروع بلوک را کنترل می‌کند. مقدار پیش‌فرض صفر است، به این معنی که برچسب شروع تنها در صورت استفاده تولید می‌شود. یک مقدار عدد صحیح بزرگ‌تر از صفر، تولید برچسب شروع را اجباری می‌کند حتی اگر توسط تحلیل‌گر لغوی استفاده نشده باشد. یک مقدار رشته‌ای نیز تولید برچسب شروع را اجباری کرده و نام برچسب را روی رشتهٔ مشخص‌شده تنظیم می‌کند. این پیکربندی تنها برای بلوک فعلی اعمال می‌شود (برای بلوک بعدی به مقدار پیش‌فرض بازنشانی می‌شود)\&. .TP .B \fBre2c:label:yyFillLabel\fP پیشوند برچسب‌های \fBYYFILL\fP مورد استفاده همراه با \fBre2c:eof\fP و در حالت وضعیت قابل‌ذخیره (storable state) را مشخص می‌کند. .TP .B \fBre2c:label:yyloop\fP نام برچسب نشان‌دهندهٔ شروع حلقهٔ تحلیل‌گر لغوی با گزینهٔ \fB\-\-loop\-switch\fP را مشخص می‌کند. مقدار پیش‌فرض \fByyloop\fP است\&. .TP .B \fBre2c:label:yyNext\fP نام برچسب اختیاری را مشخص می‌کند که پس از سوییچ \fBYYGETSTATE\fP در حالت وضعیت قابل‌ذخیره می‌آید (فعال‌شده با \fBre2c:state:nextlabel\fP). مقدار پیش‌فرض \fByyNext\fP است\&. .TP .B \fBre2c:lookahead\fP, \fBre2c:flags:lookahead\fP منسوخ شده است (گزینهٔ منسوخ‌شدهٔ \fB\-\-no\-lookahead\fP را ببینید). .TP .B \fBre2c:monadic\fP اگر روی مقداری غیر از صفر تنظیم شود، تحلیل‌گر لغوی تولیدشده از نشانه‌گذاری مونادیک استفاده خواهد کرد (این پیکربندی مخصوص Haskell است)..TP .B \fBre2c:nested\-ifs\fP, \fBre2c:flags:nested\-ifs\fP, \fBre2c:flags:s\fP همانند گزینهٔ \fB\-\-nested\-ifs\fP است، اما می‌تواند بر مبنای هر بلوک پیکربندی شود. .TP .B \fBre2c:posix\-captures\fP, \fBre2c:flags:posix\-captures\fP, \fBre2c:flags:P\fP همانند گزینهٔ \fB\-\-posix\-captures\fP است، اما می‌تواند بر مبنای هر بلوک پیکربندی شود. .TP .B \fBre2c:posix\-captvars\fP همانند گزینهٔ \fB\-\-posix\-captvars\fP است، اما می‌تواند بر مبنای هر بلوک پیکربندی شود. .TP .B \fBre2c:tags\fP, \fBre2c:flags:tags\fP, \fBre2c:flags:T\fP همانند گزینهٔ \fB\-\-tags\fP است، اما می‌تواند بر مبنای هر بلوک پیکربندی شود. .TP .B \fBre2c:tags:expression\fP عبارت مورد استفاده برای متغیرهای برچسب را مشخص می‌کند. به‌طور پیش‌فرض re2hs عبارت‌هایی به شکل \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 خواهد بود). .TP .B \fBre2c:tags:prefix\fP پیشوند نام متغیرهای برچسب را مشخص می‌کند. مقدار پیش‌فرض \fByyt\fP است. .TP .B \fBre2c:sentinel\fP نماد نگهبان (sentinel) مورد استفاده برای بررسی‌های پایان ورودی (زمانی که بررسی‌های مرزی با \fBre2c:yyfill:enable = 0;\fP غیرفعال شده و \fBre2c:eof\fP تنظیم نشده باشد) را مشخص می‌کند. این پیکربندی تأثیری بر تولید کد ندارد: هدف آن حصول اطمینان از مجاز نبودن نماد نگهبان در میانهٔ یک قاعده، و تضمین این است که تحلیل‌گر لغوی فراتر از پایان بافر را نخواند. مقدار پیش‌فرض \fI\-1\(ga\fP است (در این حالت re2hs فرض می‌کند که نماد نگهبان صفر است، که رایج‌ترین حالت می‌باشد). فقط اعداد ده‌دهی شناسایی می‌شوند. .TP .B \fBre2c:state:abort\fP اگر روی یک مقدار عدد صحیح مثبت تنظیم شود، حالت پیش‌فرض (default case) در هدایت وضعیت تولیدشده، اجرای برنامه را لغو (abort) می‌کند و یک حالت صریح \fB\-1\fP شامل انتقال به ابتدای بلوک خواهد بود. .TP .B \fBre2c:state:nextlabel\fP کنترل می‌کند که آیا سوییچ \fBYYGETSTATE\fP با برچسب \fByyNext\fP دنبال شود یا خیر (مقدار پیش‌فرض صفر است که متناظر با نبود برچسب است). به‌عنوان روشی جایگزین می‌توان از \fBre2c:label:start\fP برای تولید یک برچسب شروع مشخص، یا یک بلوک صریح \fBgetstate\fP برای تولید سوییچ \fBYYGETSTATE\fP به‌طور جداگانه از بلوک لکسر استفاده کرد. .TP .B \fBre2c:unsafe\fP, \fBre2c:flags:unsafe\fP همانند گزینهٔ \fB\-\-no\-unsafe\fP است، اما می‌تواند بر مبنای هر بلوک پیکربندی شود. اگر روی صفر تنظیم شود، از تولید پوشش‌های \fBunsafe\fP در اطراف \fBYYPEEK\fP جلوگیری می‌کند. مقدار پیش‌فرض غیرصفر است (پوشش‌ها تولید می‌شوند). این پیکربندی مختص به Rust است. .TP .B \fBre2c:YYBACKUP\fP, \fBre2c:define:YYBACKUP\fP پریمیتیو عمومی API به نام \fBYYBACKUP\fP را تعریف می‌کند. .TP .B \fBre2c:YYBACKUPCTX\fP, \fBre2c:define:YYBACKUPCTX\fP پریمیتیو عمومی API به نام \fBYYBACKUPCTX\fP را تعریف می‌کند. .TP .B \fBre2c:YYCONDTYPE\fP, \fBre2c:define:YYCONDTYPE\fP پریمیتیو API به نام \fBYYCONDTYPE\fP را تعریف می‌کند. .TP .B \fBre2c:YYCTYPE\fP, \fBre2c:define:YYCTYPE\fP پریمیتیو API به نام \fBYYCTYPE\fP را تعریف می‌کند. .TP .B \fBre2c:YYCTXMARKER\fP, \fBre2c:define:YYCTXMARKER\fP پریمیتیو API به نام \fBYYCTXMARKER\fP را تعریف می‌کند. .TP .B \fBre2c:YYCURSOR\fP, \fBre2c:define:YYCURSOR\fP پریمیتیو API به نام \fBYYCURSOR\fP را تعریف می‌کند. .TP .B \fBre2c:YYDEBUG\fP, \fBre2c:define:YYDEBUG\fP پریمیتیو API به نام \fBYYDEBUG\fP را تعریف می‌کند. .TP .B \fBre2c:YYFILL\fP, \fBre2c:define:YYFILL\fP پریمیتیو API به نام \fBYYFILL\fP را تعریف می‌کند. .TP .B \fBre2c:YYFILL@len\fP, \fBre2c:define:YYFILL@len\fP علامت (sigil) مورد استفاده برای جایگزینی آرگومان در تعریف \fBYYFILL\fP را مشخص می‌کند. پیش‌فرض \fB@@\fP است. پیکربندی عمومی‌تر \fBre2c:api:sigil\fP را بازنویسی می‌کند. .TP .B \fBre2c:YYFILL:naked\fP, \fBre2c:define:YYFILL:naked\fP پیکربندی عمومی‌تر \fBre2c:api:style\fP را برای \fBYYFILL\fP بازنویسی می‌کند. مقدار صفر متناظر با سبک آزاد API (free\-form) است. .TP .B \fBre2c:YYFN\fP پریمیتیو API به نام \fBYYFN\fP را تعریف می‌کند. .TP .B \fBre2c:YYINPUT\fP پریمیتیو API به نام \fBYYINPUT\fP را تعریف می‌کند. .TP .B \fBre2c:YYGETCOND\fP, \fBre2c:define:YYGETCONDITION\fP پریمیتیو API به نام \fBYYGETCOND\fP را تعریف می‌کند. .TP .B \fBre2c:YYGETCOND:naked\fP, \fBre2c:define:YYGETCONDITION:naked\fP پیکربندی عمومی‌تر \fBre2c:api:style\fP را برای \fBYYGETCOND\fP بازنویسی می‌کند. مقدار صفر متناظر با سبک آزاد API است. .TP .B \fBre2c:YYGETSTATE\fP, \fBre2c:define:YYGETSTATE\fP پریمیتیو API به نام \fBYYGETSTATE\fP را تعریف می‌کند. .TP .B \fBre2c:YYGETSTATE:naked\fP, \fBre2c:define:YYGETSTATE:naked\fP پیکربندی عمومی‌تر \fBre2c:api:style\fP را برای \fBYYGETSTATE\fP بازنویسی می‌کند. مقدار صفر متناظر با سبک آزاد API است. .TP .B \fBre2c:YYGETACCEPT\fP, \fBre2c:define:YYGETACCEPT\fP پریمیتیو API به نام \fBYYGETACCEPT\fP را تعریف می‌کند. .TP .B \fBre2c:YYLESSTHAN\fP, \fBre2c:define:YYLESSTHAN\fP پریمیتیو عمومی API به نام \fBYYLESSTHAN\fP را تعریف می‌کند. .TP .B \fBre2c:YYLIMIT\fP, \fBre2c:define:YYLIMIT\fP پریمیتیو API به نام \fBYYLIMIT\fP را تعریف می‌کند. .TP .B \fBre2c:YYMARKER\fP, \fBre2c:define:YYMARKER\fP پریمیتیو API به نام \fBYYMARKER\fP را تعریف می‌کند. .TP .B \fBre2c:YYMTAGN\fP, \fBre2c:define:YYMTAGN\fP پریمیتیو عمومی API به نام \fBYYMTAGN\fP را تعریف می‌کند. .TP .B \fBre2c:YYMTAGP\fP, \fBre2c:define:YYMTAGP\fP پریمیتیو عمومی API به نام \fBYYMTAGP\fP را تعریف می‌کند. .TP .B \fBre2c:YYPEEK\fP, \fBre2c:define:YYPEEK\fP پریمیتیو عمومی API به نام \fBYYPEEK\fP را تعریف می‌کند. .TP .B \fBre2c:YYRESTORE\fP, \fBre2c:define:YYRESTORE\fP پریمیتیو عمومی API به نام \fBYYRESTORE\fP را تعریف می‌کند. .TP .B \fBre2c:YYRESTORECTX\fP, \fBre2c:define:YYRESTORECTX\fP پریمیتیو عمومی API به نام \fBYYRESTORECTX\fP را تعریف می‌کند. .TP .B \fBre2c:YYRESTORETAG\fP, \fBre2c:define:YYRESTORETAG\fP پریمیتیو عمومی API به نام \fBYYRESTORETAG\fP را تعریف می‌کند. .TP .B \fBre2c:YYSETCOND\fP, \fBre2c:define:YYSETCONDITION\fP پریمیتیو API به نام \fBYYSETCOND\fP را تعریف می‌کند. .TP .B \fBre2c:YYSETCOND@cond\fP, \fBre2c:define:YYSETCONDITION@cond\fP علامت (sigil) مورد استفاده برای جایگزینی آرگومان در تعریف \fBYYSETCOND\fP را مشخص می‌کند. مقدار پیش‌فرض \fB@@\fP است. پیکربندی عمومی‌تر \fBre2c:api:sigil\fP را بازنویسی می‌کند. .TP .B \fBre2c:YYSETCOND:naked\fP, \fBre2c:define:YYSETCONDITION:naked\fP پیکربندی عمومی‌تر \fBre2c:api:style\fP را برای \fBYYSETCOND\fP بازنویسی می‌کند. مقدار صفر متناظر با سبک آزاد API است. .TP .B \fBre2c:YYSETSTATE\fP, \fBre2c:define:YYSETSTATE\fP پریمیتیو API به نام \fBYYSETSTATE\fP را تعریف می‌کند. .TP .B \fBre2c:YYSETSTATE@state\fP, \fBre2c:define:YYSETSTATE@state\fP علامت (sigil) مورد استفاده برای جایگزینی آرگومان در تعریف \fBYYSETSTATE\fP را مشخص می‌کند. مقدار پیش‌فرض \fB@@\fP است. پیکربندی عمومی‌تر \fBre2c:api:sigil\fP را بازنویسی می‌کند. .TP .B \fBre2c:YYSETSTATE:naked\fP, \fBre2c:define:YYSETSTATE:naked\fP پیکربندی عمومی‌تر \fBre2c:api:style\fP را برای \fBYYSETSTATE\fP بازنویسی می‌کند. مقدار صفر متناظر با سبک آزاد API است. .TP .B \fBre2c:YYSETACCEPT\fP, \fBre2c:define:YYSETACCEPT\fP پریمیتیو API به نام \fBYYSETACCEPT\fP را تعریف می‌کند. .TP .B \fBre2c:YYSKIP\fP, \fBre2c:define:YYSKIP\fP پریمیتیو عمومی API به نام \fBYYSKIP\fP را تعریف می‌کند. .TP .B \fBre2c:YYSHIFT\fP, \fBre2c:define:YYSHIFT\fP پریمیتیو عمومی API به نام \fBYYSHIFT\fP را تعریف می‌کند. .TP .B \fBre2c:YYCOPYMTAG\fP, \fBre2c:define:YYCOPYMTAG\fP پریمیتیو عمومی API به نام \fBYYCOPYMTAG\fP را تعریف می‌کند. .TP .B \fBre2c:YYCOPYSTAG\fP, \fBre2c:define:YYCOPYSTAG\fP پریمیتیو عمومی API به نام \fBYYCOPYSTAG\fP را تعریف می‌کند..TP .B \fBre2c:YYSHIFTMTAG\fP, \fBre2c:define:YYSHIFTMTAG\fP عنصر پایهٔ API عمومی \fBYYSHIFTMTAG\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYSHIFTSTAG\fP, \fBre2c:define:YYSHIFTSTAG\fP عنصر پایهٔ API عمومی \fBYYSHIFTSTAG\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYSTAGN\fP, \fBre2c:define:YYSTAGN\fP عنصر پایهٔ API عمومی \fBYYSTAGN\fP را تعریف می‌کند\&. .TP .B \fBre2c:YYSTAGP\fP, \fBre2c:define:YYSTAGP\fP عنصر پایهٔ API عمومی \fBYYSTAGP\fP را تعریف می‌کند\&. .TP .B \fBre2c:yyaccept\fP, \fBre2c:variable:yyaccept\fP عنصر پایهٔ API با نام \fByyaccept\fP را تعریف می‌کند\&. .TP .B \fBre2c:yybm\fP, \fBre2c:variable:yybm\fP عنصر پایهٔ API با نام \fByybm\fP را تعریف می‌کند\&. .TP .B \fBre2c:yybm:hex\fP, \fBre2c:variable:yybm:hex\fP اگر روی مقداری غیر از صفر تنظیم شود، نگاشت‌های بیتی برای گزینهٔ \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 اگر روی مقداری غیر از صفر تنظیم شود، re2hs با هر بار خواندن \fByych\fP، به‌طور خودکار تبدیل به \fBYYCTYPE\fP را تولید می‌کند. پیش‌فرض صفر است (بدون تبدیل). .TP .B \fBre2c:yych:literals\fP, \fBre2c:variable:yych:literals\fP شکل مقادیر لفظی را که \fByych\fP در برابر آن‌ها تطبیق داده می‌شود مشخص می‌کند. مقادیر ممکن عبارت‌اند از: \fBchar\fP (نویسه‌های لفظی در گیومه تکی؛ نویسه‌های غیرقابل‌چاپ از توالی‌های گریز که با بک‌اسلش آغاز می‌شوند استفاده می‌کنند)، \fBhex\fP (اعداد صحیح هگزادسیمال) و \fBchar_or_hex\fP (ترکیبی از هر دو؛ نویسه‌های لفظی برای نویسه‌های قابل‌چاپ و اعداد صحیح هگزادسیمال برای سایر موارد). .TP .B \fBre2c:yyctable\fP, \fBre2c:variable:yyctable\fP عنصر پایهٔ API با نام \fByyctable\fP را تعریف می‌کند\&. .TP .B \fBre2c:yynmatch\fP, \fBre2c:variable:yynmatch\fP عنصر پایهٔ API با نام \fByynmatch\fP را تعریف می‌کند\&. .TP .B \fBre2c:yypmatch\fP, \fBre2c:variable:yypmatch\fP عنصر پایهٔ API با نام \fByypmatch\fP را تعریف می‌کند\&. .TP .B \fBre2c:yytarget\fP, \fBre2c:variable:yytarget\fP عنصر پایهٔ API با نام \fByytarget\fP را تعریف می‌کند\&. .TP .B \fBre2c:yystable\fP, \fBre2c:variable:yystable\fP منسوخ شده است. .TP .B \fBre2c:yystate\fP, \fBre2c:variable:yystate\fP عنصر پایهٔ API با نام \fByystate\fP را تعریف می‌کند\&. .TP .B \fBre2c:yyfill\fP, \fBre2c:variable:yyfill\fP عنصر پایهٔ API با نام \fByyfill\fP را تعریف می‌کند\&. .TP .B \fBre2c:yyfill:check\fP اگر روی صفر تنظیم شود، از تولید بررسی پیش از \fBYYFILL\fP برای تعداد نویسه‌های ورودی (تعریف \fBYYLESSTHAN\fP در API عمومی و مقایسهٔ مبتنی بر \fBYYLIMIT\fP در API اشاره‌گر C) جلوگیری می‌کند. پیش‌فرض مقداری غیر از صفر است (بررسی تولید می‌شود). .TP .B \fBre2c:yyfill:enable\fP اگر روی صفر تنظیم شود، از تولید \fBYYFILL\fP (به‌همراه بررسی مربوط به آن) جلوگیری می‌کند. این تنظیم زمانی باید استفاده شود که تمام ورودی در یک بخش پیوسته از حافظه جا می‌گیرد (نیازی به میان‌گیرسازی نیست) و بررسی‌های پایان ورودی به بررسی‌های \fBYYFILL\fP متکی نیستند (برای نمونه هنگامی که از نویسهٔ نگهبان استفاده می‌شود). از هشدارها (گزینهٔ \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 ابزار re2hs از ساختار دستوری زیر برای عبارات باقاعده استفاده می‌کند: .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 هر کاراکتری به جز خط جدید (newline). .TP .B \fBR \e S\fP تفاضل کلاس‌های کاراکتری \fBR\fP و \fBS\fP\&. .TP .B \fBR*\fP صفر یا چند بار تکرار \fBR\fP\&. .TP .B \fBR+\fP یک یا چند بار تکرار \fBR\fP\&. .TP .B \fBR?\fP مورد اختیاری \fBR\fP\&. .TP .B \fBR{n}\fP تکرار \fBR\fP دقیقاً \fBn\fP بار. .TP .B \fBR{n,}\fP تکرار \fBR\fP حداقل \fBn\fP بار. .TP .B \fBR{n,m}\fP تکرار \fBR\fP از \fBn\fP تا \fBm\fP بار. .TP .B \fB(R)\fP صرفاً \fBR\fP؛ از پرانتزها برای لغو و تغییر اولویت استفاده می‌شود. اگر استخراج زیرتطابق فعال باشد، بسته به گزینهٔ \fB\-\-invert\-captures\fP، مورد \fB(R)\fP یک گروه ضبط‌کننده یا غیرضبط‌کننده خواهد بود. .TP .B \fB(!R)\fP اگر استخراج زیرتطابق فعال باشد، بسته به گزینهٔ \fB\-\-invert\-captures\fP، مورد \fB(!R)\fP یک گروه غیرضبط‌کننده یا ضبط‌کننده خواهد بود. .TP .B \fBR S\fP الحاق: \fBR\fP و به دنبال آن \fBS\fP\&. .TP .B \fBR | S\fP جایگزین: \fBR یا S\fP\&. .TP .B \fBR / S\fP دید به جلو (Lookahead): \fBR\fP و به دنبال آن \fBS\fP، اما \fBS\fP مصرف نمی‌شود. .TP .B \fBname\fP عبارت باقاعدهٔ تعریف‌شده به عنوان \fBname\fP (یا رشتهٔ لفظی \fB\(dqname\(dq\fP در حالت سازگاری با Flex). .TP .B \fB{name}\fP عبارت باقاعدهٔ تعریف‌شده به عنوان \fBname\fP در حالت سازگاری با Flex. .TP .B \fB@stag\fP یک \fIs\-tag\fP: آخرین موقعیت ورودی که در آن \fB@stag\fP مطابقت می‌یابد را در متغیری به نام \fBstag\fP ذخیره می‌کند. .TP .B \fB#mtag\fP یک \fIm\-tag\fP: تمام موقعیت‌های ورودی که در آن‌ها \fB#mtag\fP مطابقت می‌یابد را در متغیری به نام \fBmtag\fP ذخیره می‌کند. .TP .B \fB$\fP پایان ورودی. .UNINDENT .sp کلاس‌های کاراکتری و رشته‌های لفظی می‌توانند شامل توالی‌های گریز زیر باشند: \fB\ea\fP، \fB\eb\fP، \fB\ef\fP، \fB\en\fP، \fB\er\fP، \fB\et\fP، \fB\ev\fP، \fB\e\e\fP، گریزهای هشت‌هشتی (octal) \fB\eooo\fP و گریزهای شانزده‌شانزدهی (hexadecimal) \fB\exhh\fP، \fB\euhhhh\fP و \fB\eUhhhhhhhh\fP\&. .SS "کنش‌ها (Actions)" .sp در اینجا فهرستی از کنش‌های از پیش تعریف‌شده که توسط re2hs پشتیبانی می‌شوند آمده است: .INDENT 0.0 .TP .B \fB!entry code\fP کنش ورودی (Entry action)، یک بلوک از \fBcode\fP تعریف‌شده توسط کاربر را به حالت شروع ماشین حالت متناهی فعلی پیوند می‌دهد. اگر از \fI\%شرایط شروع (start conditions)\fP استفاده شود، کنش ورودی می‌تواند به‌طور جداگانه برای هر شرط تنظیم شود. از این کنش می‌توان برای انجام مقداردهی اولیه استفاده کرد؛ مثلاً برای ذخیرهٔ موقعیت شروع یک نشانه (lexeme). .TP .B \fB!pre_rule code\fP کنش پیش‌قاعده (Pre\-rule action)، یک بلوک از \fBcode\fP تعریف‌شده توسط کاربر را به ابتدای کنش‌های معنایی تمام قواعد در بلوک فعلی (یا شرط، در صورت استفاده از \fI\%شرایط شروع (start conditions)\fP) می‌افزاید. از این کنش می‌توان برای جداسازی بخش مشترک تمام کنش‌های معنایی استفاده کرد (مانند ذخیره کردن موقعیت پایان یک نشانه). .TP .B \fB!post_rule code\fP کنش پس‌قاعده (Post\-rule action)، یک بلوک از \fBcode\fP تعریف‌شده توسط کاربر را به انتهای کنش‌های معنایی تمام قواعد در بلوک فعلی (یا شرط، در صورت استفاده از \fI\%شرایط شروع (start conditions)\fP) ملحق می‌کند. از این کنش می‌توان برای درج دستورهای تله (trap) به منظور محافظت در برابر جریان کنترل ناخواسته استفاده نمود. .UNINDENT.SS "دستورالعمل‌ها (Directives)" .sp در اینجا فهرست کاملی از دستورالعمل‌های پشتیبانی‌شده توسط re2hs آمده است: .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 کد تولیدشده به کمک \fIprimitives\fP (عناصر پایه) که در مجموع با نام \fIAPI\fP شناخته می‌شوند، با برنامهٔ بیرونی ارتباط برقرار می‌کند. اینکه کدام عناصر پایه باید برای یک برنامهٔ خاص تعریف شوند به عوامل متعددی بستگی دارد، از جمله پیچیدگی عبارات باقاعده، نحوهٔ نمایش ورودی، بافرینگ و استفاده از قابلیت‌های گوناگون. تمام عناصر پایهٔ لازم باید توسط کاربر در قالب ماکروها، توابع، متغیرها یا هر شکل مناسب دیگری که کد تولیدشده را از نظر نحوی و معنایی درست کند، تعریف شوند. re2hs تعاریف را بررسی نمی‌کند (و نمی‌تواند بکند)، بنابراین در صورت نبود یا نادرست تعریف شدن هر مورد، برنامهٔ تولیدشده ممکن است با خطاهای زمان کامپایل یا زمان اجرا مواجه شود. این راهنما مثال‌هایی از تعاریف API در رایج‌ترین حالت‌ها ارائه می‌دهد. .sp ابزار re2hs دارای دو نوع رابط (API flavor) است که مجموعهٔ اصلی عناصر پایهٔ مورد استفادهٔ برنامه را مشخص می‌کنند: .INDENT 0.0 .TP .B \fBRecord API\fP رابط Record API رابط پیش‌فرض برای backend زبان Haskell است. این API شامل یک مقیدسازی (binding) به نام \fByyrecord\fP است (نام آن با \fBre2c:yyrecord\fP قابل بازنویسی است) که باید به صورت یک رکورد با فیلدهای \fB_yyinput\fP، \fB_yycursor\fP، \fB_yymarker\fP، \fB_yyctxmarker\fP و \fB_yylimit\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، \fBYYCOPYSTAG\fP، \fBYYCOPYMTAG\fP، \fBYYSHIFT\fP، \fBYYSHIFTSTAG\fP، \fBYYSHIFTMTAG\fP، \fBYYLESSTHAN\fP، \fBYYEND\fP\&. .UNINDENT .sp در اینجا فهرست کاملی از عناصر پایهٔ API آمده است که ممکن است توسط کد تولیدشده جهت ارتباط با برنامهٔ بیرونی استفاده شوند. .INDENT 0.0 .TP .B \fBYYCTYPE\fP نوع نویسه‌های ورودی (واحدهای کد یا code units). برای کدگذاری‌های ASCII، EBCDIC و UTF\-8 باید یک عدد صحیح بدون علامت ۱ بایتی باشد. برای UTF\-16 یا UCS\-2 باید یک عدد صحیح بدون علامت ۲ بایتی باشد. برای UTF\-32 باید یک عدد صحیح بدون علامت ۴ بایتی باشد. .TP .B \fBYYCURSOR\fP یک مقدار چپ (l\-value) که موقعیت ورودی فعلی را ذخیره می‌کند (یک اشاره‌گر یا آفست عدد صحیح در \fBYYINPUT\fP). در ابتدا \fBYYCURSOR\fP باید به نخستین نویسهٔ ورودی اشاره کند، و در ادامه توسط کد تولیدشده به جلو برده می‌شود. هنگامی که یک قاعده مطابقت می‌یابد، موقعیت \fBYYCURSOR\fP در مکان پس از آخرین نویسهٔ منطبق‌شده قرار می‌گیرد. .TP .B \fBYYLIMIT\fP یک مقدار راست (r\-value) که موقعیت پایان ورودی را ذخیره می‌کند (یک اشاره‌گر یا آفست عدد صحیح در \fBYYINPUT\fP). در ابتدا \fBYYLIMIT\fP باید به موقعیت پس از آخرین نویسهٔ ورودی موجود اشاره کند. این مقدار توسط کد تولیدشده تغییر نمی‌یابد. تحلیل‌گر لغوی \fBYYCURSOR\fP را با \fBYYLIMIT\fP مقایسه می‌کند تا تشخیص دهد آیا نویسه‌های ورودی به اندازهٔ کافی باقی مانده‌اند یا خیر. .TP .B \fBYYMARKER\fP یک مقدار چپ (l\-value) که موقعیت آخرین قاعدهٔ منطبق‌شده را ذخیره می‌کند (یک اشاره‌گر یا آفست عدد صحیح در \fBYYINPUT\fP). از آن برای بازیابی موقعیت \fBYYCURSOR\fP در صورتی استفاده می‌شود که تطابق طولانی‌تر شکست بخورد و تحلیل‌گر لغوی نیاز به بازگشت به عقب (rollback) داشته باشد. نیازی به مقداردهی اولیه نیست. .TP .B \fBYYCTXMARKER\fP یک مقدار چپ (l\-value) که موقعیت بافت پس‌آیند (trailing context) را ذخیره می‌کند (یک اشاره‌گر یا آفست عدد صحیح در \fBYYINPUT\fP). نیازی به مقداردهی اولیه نیست. \fBYYCTXMARKER\fP تنها در صورتی مورد نیاز است که عملگر پیش‌نگری \fB/\fP به کار رفته باشد. .TP .B \fBYYFILL\fP یک عنصر پایه در API عمومی با یک متغیر \fBlen\fP\&. \fBYYFILL\fP باید دست‌کم \fBlen\fP نویسهٔ ورودی دیگر را تأمین کند یا با شکست مواجه شود. اگر از \fBre2c:eof\fP استفاده شده باشد، آنگاه \fBlen\fP همیشه \fB1\fP است و \fBYYFILL\fP باید همواره به تابع فراخواننده بازگردد؛ مقدار بازگشتی صفر نشان‌دهندهٔ موفقیت است. اگر از \fBre2c:eof\fP استفاده نشود، مقدار بازگشتی \fBYYFILL\fP نادیده گرفته می‌شود و در صورت شکست نباید بازگردد. بیشینهٔ مقدار \fBlen\fP برابر با \fBYYMAXFILL\fP است. .TP .B \fBYYFN\fP عنصری پایه که پیش‌نمونهٔ تابع را در مدل کد \fB\-\-recursive\-functions\fP تعریف می‌کند. مقدار آن باید آرایه‌ای از یک یا چند رشته باشد، که در آن هر رشته شامل دو یا سه مؤلفه است که توسط رشتهٔ مشخص‌شده در پیکربندی \fBre2c:fn:sep\fP (معمولاً یک نقطه‌ویرگول) جدا شده‌اند. نخستین عنصر آرایه نام تابع و نوع بازگشتی را مشخص می‌کند (برای یک تابع تهی یا void، خالی است). عناصر بعدی آرگومان‌های تابع را تعریف می‌کنند: نخست، عبارت مربوط به آرگومان مورد استفاده در بدنهٔ تابع (معمولاً فقط یک نام)؛ دوم، نوع آرگومان؛ سوم، یک پارامتر رسمی اختیاری (به‌طور پیش‌فرض همان مؤلفهٔ اول است \- معمولاً هر دو آرگومان و پارامتر یک شناسه هستند). .TP .B \fBYYINPUT\fP یک مقدار راست (r\-value) که دنبالهٔ نویسه‌های ورودی فعلی (رشته، بافر، و غیره) را ذخیره می‌کند. .TP .B \fBYYMAXFILL\fP یک ثابت عدد صحیح برابر با بیشینهٔ مقدار آرگومان ورودی به \fBYYFILL\fP\&. این مقدار می‌تواند با یک بلوک \fBmax\fP تولید شود. .TP .B \fBYYLESSTHAN\fP یک عنصر پایه در API عمومی با یک متغیر \fBlen\fP\&. باید به عنوان یک مقدار راست (r\-value) از نوع بولی تعریف شود که اگر و تنها اگر کمتر از \fBlen\fP نویسهٔ ورودی باقی مانده باشد، برابر با \fBtrue\fP شود. .TP .B \fBYYEND\fP یک عنصر پایه در API عمومی بدون متغیر. باید به صورت یک مقدار راست (r\-value) از نوع بولی تعریف شود که اگر و تنها اگر انتهای \fIمنطقی\fP ورودی فرا رسیده باشد (بدون در نظر گرفتن هرگونه نویسهٔ پرکننده یا نشانگرهای مرزی)، برابر با \fBtrue\fP باشد. \fBYYEND\fP برای پیاده‌سازی نماد \fB$\fP در عبارات باقاعده استفاده می‌شود. این با \fBYYLESSTHAN\fP تفاوت دارد، که برای اطمینان از اینکه تحلیل‌گر لغوی فراتر از پایان بافر را نخواند به کار می‌رود. .TP .B \fBYYPEEK\fP یک عنصر پایه در API عمومی بدون متغیر. باید به صورت یک مقدار راست (r\-value) از نوع \fBYYCTYPE\fP تعریف شود که برابر با نویسه در موقعیت ورودی فعلی است. .TP .B \fBYYSKIP\fP یک عنصر پایه در API عمومی که باید موقعیت ورودی فعلی را به اندازهٔ یک واحد کد جلو ببرد. .TP .B \fBYYBACKUP\fP یک عنصر پایه در API عمومی که باید موقعیت ورودی فعلی را ذخیره کند (تا بعداً با \fBYYRESTORE\fP بازیابی شود). .TP .B \fBYYRESTORE\fP یک عنصر پایه در API عمومی که باید موقعیت ورودی فعلی را به مقدار ذخیره‌شده توسط \fBYYBACKUP\fP بازگرداند. .TP .B \fBYYBACKUPCTX\fP یک عنصر پایه در API عمومی که باید موقعیت ورودی فعلی را به عنوان موقعیت بافت پس‌آیند ذخیره کند (تا بعداً با \fBYYRESTORECTX\fP بازیابی شود). .TP .B \fBYYRESTORECTX\fP یک عنصر پایه در API عمومی که باید موقعیت بافت پس‌آیند ذخیره‌شده با \fBYYBACKUPCTX\fP را بازیابی کند. .TP .B \fBYYRESTORETAG\fP یک عنصر پایه در API عمومی با یک متغیر \fBtag\fP که باید موقعیت بافت پس‌آیند را به مقدار \fBtag\fP بازگرداند. .TP .B \fBYYSTAGP\fP یک عنصر پایه در API عمومی با یک متغیر \fBtag\fP، که در آن \fBtag\fP می‌تواند یک اشاره‌گر یا یک آفست در \fBYYINPUT\fP باشد (برای جزئیات به بخش استخراج زیرتطابق مراجعه کنید). \fBYYSTAGP\fP باید \fBtag\fP را روی موقعیت ورودی فعلی تنظیم کند..TP .B \fBYYSTAGN\fP یک دستور پایه عمومی API با یک متغیر \fBtag\fP، که در آن \fBtag\fP می‌تواند یک اشاره‌گر یا آفست در \fBYYINPUT\fP باشد (برای جزئیات به بخش استخراج تطابق‌های فرعی مراجعه کنید). \fBYYSTAGN\fP باید \fBtag\fP را روی مقداری تنظیم کند که بیانگر یک موقعیت ورودی ناموجود باشد. .TP .B \fBYYMTAGP\fP یک دستور پایه عمومی API با یک متغیر \fBtag\fP\&. \fBYYMTAGP\fP باید موقعیت فعلی را به تاریخچه تطابق‌های فرعیِ \fBtag\fP اضافه کند (برای جزئیات به بخش استخراج تطابق‌های فرعی مراجعه کنید). .TP .B \fBYYMTAGN\fP یک دستور پایه عمومی API با یک متغیر \fBtag\fP\&. \fBYYMTAGN\fP باید مقداری را که بیانگر یک موقعیت ورودی ناموجود است به تاریخچه تطابق‌های فرعیِ \fBtag\fP اضافه کند (برای جزئیات به بخش استخراج تطابق‌های فرعی مراجعه کنید). .TP .B \fBYYSHIFT\fP یک دستور پایه عمومی API با یک متغیر \fBshift\fP که باید موقعیت ورودی فعلی را به اندازه \fBshift\fP نویسه تغییر دهد (مقدار تغییر می‌تواند منفی باشد). .TP .B \fBYYCOPYSTAG\fP یک دستور پایه عمومی API با دو متغیر، \fBlhs\fP و \fBrhs\fP، که باید متغیر سمت راستِ s\-tag یعنی \fBrhs\fP را در متغیر سمت چپِ s\-tag یعنی \fBlhs\fP کپی کند. برای بیشتر زبان‌ها این دستور پایه تعریفی پیش‌فرض دارد که \fBlhs\fP را برابر با \fBrhs\fP قرار می‌دهد. .TP .B \fBYYCOPYMTAG\fP یک دستور پایه عمومی API با دو متغیر، \fBlhs\fP و \fBrhs\fP، که باید متغیر سمت راستِ m\-tag یعنی \fBrhs\fP را در متغیر سمت چپِ m\-tag یعنی \fBlhs\fP کپی کند. برای بیشتر زبان‌ها این دستور پایه تعریفی پیش‌فرض دارد که \fBlhs\fP را برابر با \fBrhs\fP قرار می‌دهد. .TP .B \fBYYSHIFTSTAG\fP یک دستور پایه عمومی API با دو متغیر، \fBtag\fP و \fBshift\fP، که باید \fBtag\fP را به اندازه \fBshift\fP واحد کد (code unit) انتقال دهد (مقدار انتقال می‌تواند منفی باشد). .TP .B \fBYYSHIFTMTAG\fP یک دستور پایه عمومی API با دو متغیر، \fBtag\fP و \fBshift\fP، که باید آخرین مقدار در تاریخچه \fBtag\fP را به اندازه \fBshift\fP واحد کد انتقال دهد (مقدار انتقال می‌تواند منفی باشد). .TP .B \fBYYMAXNMATCH\fP یک ثابت عددی صحیح برابر با حداکثر تعداد گروه‌های تسخیر (capturing groups) استاندارد POSIX در یک قاعده. این مقدار با یک بلوک \fBmaxnmatch\fP تولید می‌شود. .TP .B \fBYYCONDTYPE\fP نوع شمارش (enum) شرط. این مقدار می‌تواند با بلوک \fBconditions\fP یا گزینه \fB\-\-header\fP تولید شود. .TP .B \fBYYGETACCEPT\fP یک دستور پایه با یک متغیر \fBvar\fP که انتخاب‌گر عددی قاعده پذیرفته‌شده را ذخیره می‌کند. برای بیشتر زبان‌ها این دستور پایه تعریفی پیش‌فرض دارد که از \fBvar\fP می‌خواند. .TP .B \fBYYSETACCEPT\fP یک دستور پایه با دو متغیر: \fBvar\fP (یک l\-value که انتخاب‌گر عددی قاعده پذیرفته‌شده را ذخیره می‌کند)، و \fBval\fP (مقدار انتخاب‌گر). برای بیشتر زبان‌ها این دستور پایه تعریفی پیش‌فرض دارد که \fBval\fP را به \fBvar\fP انتساب می‌دهد. .TP .B \fBYYGETCOND\fP یک r\-value از نوع \fBYYCONDTYPE\fP که برابر با شناسه شرط فعلی است. .TP .B \fBYYSETCOND\fP یک دستور پایه با یک متغیر \fBcond\fP که باید شناسه شرط فعلی را به \fBcond\fP تنظیم کند. .TP .B \fBYYGETSTATE\fP یک r\-value از نوع عدد صحیح که برابر با وضعیت فعلی تحلیل‌گر لغوی (lexer) است. این متغیر باید با \fB\-1\fP مقداردهی اولیه شود. .TP .B \fBYYSETSTATE\fP یک دستور پایه با یک متغیر \fBstate\fP که باید وضعیت فعلی تحلیل‌گر لغوی را به \fBstate\fP تنظیم کند. .TP .B \fBYYDEBUG\fP این دستور پایه تنها با گزینه \fB\-d\fP، \fB\-\-debug\-output\fP تولید می‌شود. هدف آن افزودن ثبت وقایع (لاگین) به کد تولید شده است (تعریف مرسوم \fBYYDEBUG\fP یک دستور چاپ است). عبارت‌های \fBYYDEBUG\fP در هر وضعیت تولید می‌شوند و دارای دو متغیر هستند: \fBstate\fP (نمایه وضعیت DFA یا \fB\-1\fP) و \fBsymbol\fP (نماد ورودی فعلی). .TP .B \fByyaccept\fP یک l\-value از نوع عددی صحیح بدون علامت که شماره آخرین قاعده تطبیق‌یافته را ذخیره می‌کند. تعریف توسط کاربر تنها با گزینه \fB\-\-storable\-state\fP ضروری است. .TP .B \fByybm\fP جدولی شامل نگاشت‌های بیتی فشرده‌شده برای حداکثر ۸ گذار (همراه با گزینه \fB\-\-bitmaps\fP استفاده می‌شود). این جدول شامل ۲۵۶ عنصر است و با واحدهای کد ۱ بایتی اندیس‌گذاری می‌شود. هر عنصر ۸ بیتی مقادیر بولی را برای حداکثر ۸ گذار ترکیب می‌کند. بیت k\-ام از عنصر n\-ام درست (true) است اگر و تنها اگر n\-امین واحد کد در بازه k\-امین گذار قرار داشته باشد. ایده این نگاشت بیتی جایگزینی چندین شاخه \fIif\fP یا گزینه‌های \fIswitch\fP با بررسی یک تک‌بیت در جدول است. .TP .B \fByych\fP یک l\-value از نوع \fBYYCTYPE\fP که نویسه ورودی فعلی را ذخیره می‌کند. تعریف توسط کاربر تنها با گزینه \fB\-f\fP \fB\-\-storable\-state\fP الزامی است. .TP .B \fByyctable\fP جدول پرش تولیدشده برای ارجاع شرط اولیه (فعال‌شده با ترکیب گزینه‌های \fB\-\-conditions\fP و \fB\-\-computed\-gotos\fP). .TP .B \fByyfill\fP یک l\-value که نتیجه فراخوانی \fBYYFILL\fP را ذخیره می‌کند (این مورد ممکن است برای زبان‌های کاملاً تابعی، که در آن‌ها \fBYYFILL\fP تابعی مونادیک با مقدار بازگشتی پیچیده است، ضروری باشد). .TP .B \fByynmatch\fP یک l\-value از نوع عددی صحیح بدون علامت که تعداد گروه‌های تسخیر POSIX را در قاعده تطبیق‌یافته ذخیره می‌کند. تنها با گزینه \fB\-P\fP \fB\-\-posix\-captures\fP استفاده می‌شود. .TP .B \fByypmatch\fP آرایه‌ای از l\-valueها که برای نگهداری مقادیر برچسب متناظر با پرانتزهای تسخیر در قاعده تطبیق‌یافته استفاده می‌شوند. طول آرایه باید حداقل \fByynmatch * 2\fP باشد (معمولاً \fBYYMAXNMATCH * 2\fP گزینه مناسبی است). تنها با گزینه \fB\-P\fP \fB\-\-posix\-captures\fP استفاده می‌شود. .TP .B \fByystable\fP منسوخ‌شده. .TP .B \fByystate\fP یک l\-value که همراه با گزینه \fB\-\-loop\-switch\fP برای ذخیره وضعیت فعلی DFA استفاده می‌شود. .TP .B \fByytarget\fP جدول پرش شامل مقاصد پرش (نشانی‌های برچسب) برای تمامی گذارها از یک وضعیت. این جدول برای هر وضعیت محلی است. تولید جدول‌های \fByytarget\fP با گزینه \fB\-\-computed\-gotos\fP فعال می‌شود. .UNINDENT.SS "گزینه‌ها (Options)" .sp برخی از گزینه‌ها دارای \fI\%پیکربندی‌های\fP متناظر هستند، برخی دیگر سراسری بوده و پس از شروع خواندن فایل ورودی توسط re2c قابل تغییر نیستند. گزینه‌های اشکال‌زدایی معمولاً نیازمند ساخت re2c در پیکربندی اشکال‌زدایی (debug) هستند. گزینه‌های داخلی برای آزمایش الگوریتم‌های به‌کاررفته در re2c مفید می‌باشند. .INDENT 0.0 .TP .B \fB\-? \-\-help \-h\fP نمایش پیام راهنما. .TP .B \fB\-\-api \fP تعیین API مورد استفاده توسط کد تولیدشده برای ارتباط با کد تعریف‌شده توسط کاربر. گزینهٔ \fBsimple\fP باید در موارد ساده‌ای استفاده شود که نیازی به پر کردن مجدد بافر و ذخیره وضعیت تحلیل‌گر لغوی نیست. گزینهٔ \fBrecord\fP باید زمانی استفاده شود که وضعیت تحلیل‌گر لغوی نیاز به ذخیره در یک رکورد (struct، class و غیره) دارد. گزینهٔ \fBgeneric\fP باید در موارد پیچیده‌ای استفاده شود که دو API دیگر به اندازه کافی انعطاف‌پذیر نیستند. .TP .B \fB\-\-bit\-vectors \-b\fP بهینه‌سازی پرش‌های شرطی با استفاده از ماسک‌های بیتی. این گزینه مستلزم \fB\-\-nested\-ifs\fP\& است. .TP .B \fB\-\-captures\fP, \fB\-\-leftmost\-captures\fP فعال‌سازی استخراج زیرتطبیق با گروه‌های ضبط حریصانهٔ چپ‌ترین (leftmost greedy). نتیجه در آرایهٔ \fByybmatch\fP با ظرفیت \fB2 * YYMAXNMATCH\fP جمع‌آوری شده، و \fByynmatch\fP روی تعداد گروه‌های قاعدهٔ منطبق تنظیم می‌شود. .TP .B \fB\-\-captvars\fP, \fB\-\-leftmost\-captvars\fP فعال‌سازی استخراج زیرتطبیق با گروه‌های ضبط حریصانهٔ چپ‌ترین. نتیجه در متغیرهای \fByytl\fP و \fByytr\fP برای \fBk\fP\-امین گروه ضبط جمع‌آوری می‌شود. .TP .B \fB\-\-case\-insensitive\fP غیرحساس به بزرگی و کوچکی حروف در نظر گرفتن رشته‌های درون نقل‌قول تکی و دوتایی. .TP .B \fB\-\-case\-inverted\fP معکوس کردن معنای رشته‌های درون نقل‌قول تکی و دوتایی: حساس به بزرگی و کوچکی حروف در نظر گرفتن رشته‌های نقل‌قول تکی و غیرحساس در نظر گرفتن رشته‌های نقل‌قول دوتایی. .TP .B \fB\-\-case\-ranges\fP ادغام caseهای متوالی در دستورهای switch به یک بازه به فرم \fBlow ... high\fP\&. این نحو یک افزونهٔ زبان C/C++ است که توسط کامپایلرهایی مانند GCC، Clang و Tcc پشتیبانی می‌شود. مزیت اصلی نسبت به استفاده از caseهای تکی، تولید کد کوچک‌تر و سرعت تولید بیشتر است، هرچند برای برخی کامپایلرها مانند Tcc منجر به اندازه باینری کوچک‌تر نیز می‌شود. .TP .B \fB\-\-computed\-gotos \-g\fP بهینه‌سازی پرش‌های شرطی با استفاده از افزونهٔ غیراستاندارد \(dqcomputed goto\(dq (که باید توسط کامپایلر پشتیبانی شود). برنامهٔ re2hs جداول پرش را تنها در موارد پیچیده با شاخه‌های شرطی فراوان تولید می‌کند. آستانهٔ پیچیدگی را می‌توان با پیکربندی \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: چندین تحلیل‌گر لغوی به‌هم‌پیوسته درون یک بلوک. این یک جایگزین برای مشخص کردن دستی بلوک‌های مختلف re2hs متصل‌شده با \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 می‌خواند. re2hs فرض می‌کند که بازهٔ نویسه‌ها 0 \-\- 0xFF و اندازهٔ نویسه ۱ بایت است. .TP .B \fB\-\-empty\-class \fP تعریف نحوهٔ برخورد re2hs با کلاس‌های نویسهٔ خالی. با \fBmatch\-empty\fP (پیش‌فرض) کلاس خالی با ورودی خالی تطبیق می‌یابد (که غیرمنطقی است، اما سازگار با گذشته است). با \fBmatch\-none\fP کلاس خالی همواره در تطبیق ناموفق است. با \fBerror\fP کلاس خالی خطای کامپایل ایجاد می‌کند. .TP .B \fB\-\-encoding\-policy \fP تعریف نحوهٔ برخورد re2hs با جانشین‌های یونیکد (Unicode surrogates). با \fBfail\fP در هنگام مواجهه با جانشین، re2hs با یک خطا متوقف می‌شود. با \fBsubstitute\fP برنامهٔ re2hs بدون هشدار جانشین‌ها را با نقطهٔ کد خطای 0xFFFD جایگزین می‌کند. با \fBignore\fP (پیش‌فرض) re2hs با جانشین‌ها مانند نقاط کد معمولی رفتار می‌کند. استاندارد یونیکد بیان می‌کند که جانشین‌های مستقل نامعتبر هستند، اما کتابخانه‌ها و برنامه‌های دنیای واقعی رفتارهای متفاوتی دارند. .TP .B \fB\-\-flex\-syntax \-F\fP پشتیبانی جزئی از نحو Flex: در این حالت تعاریف نام‌گذاری‌شده نیازی به علامت مساوی و نقطه ویرگول پایانی ندارند، و در صورت استفاده باید درون آکولاد قرار گیرند. نام‌های بدون آکولاد به عنوان رشته‌های درون نقل‌قول دوتایی در نظر گرفته می‌شوند. .TP .B \fB\-\-goto\-label\fP استفاده از مدل کد \(dqgoto/label\(dq: کدگذاری DFA در قالب بلوک‌های کد برچسب‌دار متصل با پرش‌های \fBgoto\fP در بین بلوک‌ها. این ویژگی تنها برای زبان‌هایی پشتیبانی می‌شود که دارای دستور \fBgoto\fP هستند. .TP .B \fB\-\-header \-\-type\-header \-t HEADER\fP تولید یک فایل \fBHEADER\fP. محتوای فایل را می‌توان با استفاده از بلوک‌های ویژهٔ \fBheader:on\fP و \fBheader:off\fP\& مشخص کرد. در صورت استفاده از شرایط، به هدر تولیدشده به طور خودکار یک enum وضعیت الحاق خواهد شد (مگر اینکه یک بلوک صریح \fBconditions\fP وجود داشته باشد). .TP .B \fB\-I PATH\fP افزودن \fBPATH\fP به فهرست مکان‌هایی که هنگام جستجوی فایل‌های include استفاده می‌شوند. این گزینه در ترکیب با بلوک یا دستور \fBinclude\fP مفید است. re2hs به دنبال \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 تعیین نحوهٔ تجزیه عبارات منظم توسط re2hs. با \fBascii\fP (پیش‌فرض) re2hs ورودی را به صورت کدگذاری‌شده با ASCII پردازش می‌کند: هر دنباله‌ای از واحدهای کد، دنباله‌ای از نویسه‌های ۱ بایتی مستقل است. با \fButf8\fP برنامهٔ re2hs ورودی را به صورت کدگذاری‌شده با UTF8 پردازش کرده و نویسه‌های چندبایتی را شناسایی می‌کند. .TP .B \fB\-\-invert\-captures\fP معکوس کردن معنای گروه‌های ضبط‌کننده و غیرضبط‌کننده. به طور پیش‌فرض \fB(...)\fP ضبط‌کننده و \fB(! ...)\fP غیرضبط‌کننده است. با این گزینه \fB(! ...)\fP ضبط‌کننده و \fB(...)\fP غیرضبط‌کننده خواهد بود. .TP .B \fB\-\-lang \fP تعیین زبان مقصد. زبان‌های پشتیبانی‌شده عبارتند از C، D، Go، Haskell، Java، JS، OCaml، Python، Rust، Swift، V، Zig (زبان‌های بیشتری را می‌توان از طریق فایل‌های نحو تعریف‌شده توسط کاربر اضافه کرد، گزینهٔ \fB\-\-syntax\fP را ببینید). گزینهٔ \fBnone\fP پیکربندی‌های نحوی پیش‌فرض را غیرفعال می‌کند تا زبان مقصد تعریف‌نشده باقی بماند. .TP .B \fB\-\-location\-format \fP تعیین قالب مکان در پیام‌ها. با \fBgnu\fP مکان‌ها به صورت \(aqfilename:line:column: ...\(aq چاپ می‌شوند. با \fBmsvc\fP مکان‌ها به صورت \(aqfilename(line,column) ...\(aq چاپ می‌شوند. پیش‌فرض \fBgnu\fP\& است. .TP .B \fB\-\-loop\-switch\fP استفاده از مدل کد \(dqloop/switch\(dq: کدگذاری DFA در قالب یک حلقه روی دستور switch، که در آن هر وضعیت یک case از switch است. وضعیت در یک متغیر \fByystate\fP\& ذخیره می‌شود. گذارها بین وضعیت‌ها، \fByystate\fP را به برچسب case وضعیت مقصد به‌روزرسانی کرده و اجرا را به ابتدای حلقه ادامه می‌دهند. .TP .B \fB\-\-nested\-ifs \-s\fP استفاده از دستورهای شرطی \fBif\fP تودرتو به جای دستورهای \fBswitch\fP در پرش‌های شرطی. این معمولاً در کامپایلرهای غیربهینه‌ساز منجر به کد کارآمدتری می‌شود. .TP .B \fB\-\-no\-debug\-info \-i\fP عدم تولید دستورهای خط (line directives). این گزینه زمانی مفید است که کد تولیدشده در یک سامانه کنترل نسخه ذخیره می‌شود (برای جلوگیری از تغییرات بزرگ (diff) خودکار ناشی از تغییرات کوچک). .TP .B \fB\-\-no\-generation\-date\fP جلوگیری از درج تاریخ در فایل تولیدشده. .TP .B \fB\-\-no\-version\fP جلوگیری از درج نسخه در فایل تولیدشده. .TP .B \fB\-\-no\-unsafe\fP عدم تولید پوشش \fBunsafe\fP روی \fBYYPEEK\fP (این گزینه مختص Rust است). به دلایل عملکردی، \fBYYPEEK\fP باید از بررسی حدود (bounds-checking) خودداری کند، زیرا تحلیل‌گر لغوی بررسی‌های پایان ورودی را به روش کارآمدتری انجام می‌دهد. کاربر ممکن است بخواهد یک تعریف امن برای \fBYYPEEK\fP ارائه دهد، یا تعریفی که فقط در ساخت‌های انتشار (release) به صورت unsafe باشد؛ در چنین مواردی گزینهٔ \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 استفاده از مدل کدی مبتنی بر توابع هم‌بازگشتی (co\-recursive)، که در آن هر حالت 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 تولید یک تحلیل‌گر لغوی (lexer) که می‌تواند وضعیت درونی خود را ذخیره کند. این قابلیت در لکسرهای مدل فشاری (push\-model) مفید است که در هنگام ناکافی بودن ورودی توسط یک برنامه بیرونی متوقف شده و سپس با در دسترس قرار گرفتن ورودی بیشتر کار خود را از سر می‌گیرند. در این حالت، کاربران باید علاوه بر این، سازه‌های پایه \fBYYGETSTATE\fP و \fBYYSETSTATE\fP را تعریف کنند، و متغیرهای \fByych\fP، \fByyaccept\fP و \fBstate\fP باید بخشی از وضعیت ذخیره‌شده لکسر باشند. .TP .B \fB\-\-syntax FILE\fP بارگذاری پیکربندی‌ها از \fBFILE\fP مشخص‌شده و اعمال آن‌ها بر روی فایل نحو (syntax) پیش‌فرض. توجه داشته باشید که \fBFILE\fP می‌تواند تنها چند پیکربندی را تعریف کند (اگر برای اصلاح فایل نحو پیش‌فرض استفاده شود)، یا می‌تواند یک بک‌اند زبان کاملاً جدید را تعریف کند (در حالت دوم توصیه می‌شود از گزینه \fB\-\-lang none\fP استفاده شود). .TP .B \fB\-\-tags \-T\fP فعال‌سازی استخراج زیرتطابق با برچسب‌ها (tags). .TP .B \fB\-\-ucs2 \-\-wide\-chars \-w\fP تولید لکسری که ورودی کدگذاری‌شده با UCS2 را می‌خواند. re2hs فرض می‌کند که محدوده نویسه‌ها بین 0 \-\- 0xFFFF و اندازه نویسه 2 بایت است. این گزینه مستلزم \fB\-\-nested\-ifs\fP است. .TP .B \fB\-\-utf8 \-\-utf\-8 \-8\fP تولید لکسری که ورودی را با کدگذاری UTF\-8 می‌خواند. re2hs فرض می‌کند که محدوده نویسه‌ها بین 0 \-\- 0x10FFFF و اندازه نویسه 1 بایت است. .TP .B \fB\-\-utf16 \-\-utf\-16 \-x\fP تولید لکسری که ورودی کدگذاری‌شده با UTF16 را می‌خواند. re2hs فرض می‌کند که محدوده نویسه‌ها بین 0 \-\- 0x10FFFF و اندازه نویسه 2 بایت است. این گزینه مستلزم \fB\-\-nested\-ifs\fP است. .TP .B \fB\-\-utf32 \-\-unicode \-u\fP تولید لکسری که ورودی کدگذاری‌شده با UTF32 را می‌خواند. re2hs فرض می‌کند که محدوده نویسه‌ها بین 0 \-\- 0x10FFFF و اندازه نویسه 4 بایت است. این گزینه مستلزم \fB\-\-nested\-ifs\fP است. .TP .B \fB\-\-verbose\fP نمایش یک پیام کوتاه در صورت موفقیت. .TP .B \fB\-\-vernum \-V\fP نمایش اطلاعات نسخه در قالب \fBMMmmpp\fP (اصلی، فرعی، وصله). .TP .B \fB\-\-version \-v\fP نمایش اطلاعات نسخه. .TP .B \fB\-\-single\-pass \-1\fP منسوخ شده است. هیچ کاری انجام نمی‌دهد (تک‌گذره بودن اکنون پیش‌فرض است). .UNINDENT .INDENT 0.0 .TP .B \fB\-\-debug\-output \-d\fP درج فراخوانی‌های \fBYYDEBUG\fP در کد تولیدشده. این گزینه برای ردیابی اجرای لکسر مفید است. .TP .B \fB\-\-dump\-adfa\fP گزینه اشکال‌زدایی: خروجی DFA پس از تونل‌زنی (tunneling) (در قالب .dot). .TP .B \fB\-\-dump\-cfg\fP گزینه اشکال‌زدایی: خروجی گراف جریان کنترل (CFG) متغیرهای برچسب (در قالب .dot). .TP .B \fB\-\-dump\-closure\-stats\fP گزینه اشکال‌زدایی: خروجی آمار تعداد حالت‌ها در بستار (closure). .TP .B \fB\-\-dump\-dfa\-det\fP گزینه اشکال‌زدایی: خروجی DFA بلافاصله پس از قطعی‌سازی (determinization) (در قالب .dot). .TP .B \fB\-\-dump\-dfa\-min\fP گزینه اشکال‌زدایی: خروجی DFA پس از کمینه‌سازی (minimization) (در قالب .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 گزینه اشکال‌زدایی: خروجی جدول تداخل حاصل از تحلیل زنده‌بودن (liveness analysis) متغیرهای برچسب. .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 مورداستفاده توسط re2hs\&. گزینه \fBmoore\fP همان الگوریتم مور (Moore) است (که پیش‌فرض می‌باشد). گزینه \fBtable\fP الگوریتم «پر کردن جدول» (\(dqtable filling\(dq) است. هر دو الگوریتم باید به جز برچسب‌گذاری مجدد حالت‌ها، DFA یکسانی تولید کنند؛ پر کردن جدول ساده‌تر و بسیار کندتر است و به عنوان یک پیاده‌سازی مرجع عمل می‌کند. .TP .B \fB\-\-eager\-skip\fP گزینه داخلی: وادار کردن لکسر تولیدشده به جلو بردن مشتاقانه (eagerly) موقعیت ورودی \-\- بلافاصله پس از خواندن نماد ورودی. این گزینه رفتار پیش‌فرض را که در آن موقعیت ورودی به صورت تنبلانه (lazily) \-\- پس از گذار به حالت بعدی \-\- جلو برده می‌شود، تغییر می‌دهد. .TP .B \fB\-\-no\-lookahead\fP گزینه داخلی، منسوخ شده است. در گذشته برای فعال‌سازی الگوریتم TDFA(0) استفاده می‌شد. بر خلاف TDFA(1)، الگوریتم TDFA(0) از پیش‌نگری یک‌نمادی استفاده نمی‌کند. این الگوریتم عملیات ثبات‌ها را به جای گذارهای خروجی روی گذارهای ورودی اعمال می‌کند. ارزیابی‌ها نشان دادند که الگوریتم TDFA(0) کارایی کمتری نسبت به TDFA(1) دارد. .TP .B \fB\-\-no\-optimize\-tags\fP گزینه داخلی: جلوگیری از بهینه‌سازی متغیرهای برچسب (مفید برای اشکال‌زدایی). .TP .B \fB\-\-posix\-closure \fP گزینه داخلی: مشخص کردن الگوریتم کوتاه‌ترین مسیر برای ساخت بستار اپسیلون با معناشناسی ابهام‌زدایی POSIX: مقدار \fBgor1\fP (پیش‌فرض) نشان‌دهنده الگوریتم گلدبرگ\-رادزیک (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 است. برچسب‌های «ثابت» برچسب‌هایی هستند که در فاصله ثابتی نسبت به یک برچسب دیگر (موسوم به برچسب «پایه» یا \(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 هشدار در صورتی که یک عبارت باقاعده شامل یک کلاس نویسهٔ خالی باشد. تلاش برای تطبیق یک کلاس نویسهٔ خالی بی‌معنی است: این کار باید همیشه با شکست مواجه شود. با این حال، به دلایل سازگاری با نسخه‌های پیشین، re2hs کلاس‌های نویسهٔ خالی را مجاز دانسته و با آن‌ها مانند رشته‌های خالی رفتار می‌کند. برای تغییر رفتار پیش‌فرض از گزینهٔ \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 برطرف کرد که کمترین اولویت را دارد، با هر واحد کد (code unit) تطبیق می‌یابد، و همیشه یک واحد کد را مصرف می‌کند. .TP .B \fB\-Wunreachable\-rules\fP هشدار دربارهٔ قواعدی که توسط قواعد دیگر پوشانده شده‌اند (shadowed) و هرگز تطبیق نخواهند یافت. .TP .B \fB\-Wdeprecated\-eof_rule\fP هشدار دربارهٔ قواعد مستقل پایان ورودی \fB$\fP که با تغییرات آینده از کار خواهند افتاد و نیاز به اصلاح دارند. در حال حاضر این قواعد هنگام تداخل با سایر قواعد اولویت دارند، اما پس از معرفی نماد تعمیم‌یافتهٔ پایان ورودی \fB$\fP ترتیب اولویت تغییر خواهد کرد و این قواعد توسط سایر قواعد پوشانده خواهند شد. .TP .B \fB\-Wuseless\-escape\fP هشدار در صورتی که یک نماد گریز داده شده باشد (escaped) در حالی که نیازی به آن نبوده است. به‌طور پیش‌فرض، re2hs چنین نویسه‌های گریزی را نادیده می‌گیرد، اما این موضوع ممکن است نشان‌دهندهٔ یک غلط املایی یا خطا در توالی گریز (escape sequence) باشد. .TP .B \fB\-Wnondeterministic\-tags\fP هشدار در صورتی که یک برچسب دارای درجهٔ \fBn\fP\-ام از عدم قطعیت باشد، به‌طوری که \fBn\fP بزرگ‌تر از ۱ است. .TP .B \fB\-Wsentinel\-in\-midrule\fP هشدار در صورتی که نماد نگهبان (sentinel) در میانهٔ یک قاعده رخ دهد \-\-\- این امر ممکن است باعث خواندن فراتر از انتهای بافر، خرابی برنامه (crash) یا فساد حافظه در تحلیل‌گر لغوی تولیدشده شود. این هشدار تنها در صورتی کاربرد دارد که از روش نگهبان برای بررسی پایان ورودی استفاده شود. در صورت استفاده از پیکربندی \fBre2c:sentinel\fP، این هشدار به خطا تبدیل می‌شود. .TP .B \fB\-Wundefined\-syntax\-config\fP هشدار در صورتی که فایل نحو مشخص‌شده با گزینهٔ \fB\-\-syntax\fP فاقد تعاریف برخی از پیکربندی‌ها باشد. این ویژگی به نگهداری فایل‌های نحو تعریف‌شده توسط کاربر کمک می‌کند: اگر نسخهٔ جدیدی پیکربندی‌هایی را اضافه کند، فایل نحو قدیمی هشداری صادر کرده و کاربر مطلع خواهد شد. اگر برخی از پیکربندی‌ها بی‌استفاده هستند و نیازی به تعریف ندارند، باید به‌طور صریح روی \fB\fP\& تنظیم شوند. .UNINDENT.SS فایل‌های نحو (Syntax files) .sp پشتیبانی از زبان‌های مختلف در re2c بر پایه ایده \fIفایل‌های نحو\fP (syntax files) استوار است. یک فایل نحو، یک فایل پیکربندی است که نحو زبان مقصد را تعریف می‌کند \-\- نه کل زبان، بلکه بخش کوچکی از آن را که توسط کد تولیدشده استفاده می‌شود. فایل‌های نحو re2c را بسیار منعطف می‌سازند، اما نباید به عنوان جایگزینی برای پیکربندی‌های \fBre2c:\fP به کار روند: هدف آن‌ها تعریف نحو زبان مقصد است، نه سفارشی‌سازی یک تحلیل‌گر لغوی خاص. همه زبان‌های پشتیبانی‌شده دارای فایل‌های نحو پیش‌فرضی هستند که بخشی از توزیع برنامه می‌باشند (زیرپوشه \fBinclude/syntax\fP را ببینید)؛ آن‌ها همچنین در باینری re2hs تعبیه شده‌اند. کاربران می‌توانند یک فایل نحو سفارشی فراهم کنند که چند پیکربندی را برای یکی از زبان‌های پشتیبانی‌شده بازنویسی کند، یا می‌توانند همه پیکربندی‌ها را از نو تعریف نمایند (در این صورت باید گزینه \fB\-\-lang none\fP استفاده شود). فایل‌های نحو شامل پیکربندی‌هایی از چهار نوع مختلف هستند: فهرست ویژگی‌ها، پیکربندی‌های زبان، پیکربندی‌های درجا و الگوهای کد. .sp \fBفهرست ویژگی‌ها (Feature lists)\fP .INDENT 0.0 .INDENT 3.5 چند پیکربندی فهرستی، ویژگی‌های مختلف پشتیبانی‌شده توسط یک بک‌اند مشخص را تعریف می‌کنند تا در صورتی که کاربر تلاش کند ویژگی پشتیبانی‌نشده‌ای را فعال سازد، re2hs بتواند خطای واضحی نشان دهد: .INDENT 0.0 .TP .B \fBsupported_apis\fP فهرستی از APIهای پشتیبانی‌شده با مقادیر ممکن \fBsimple\fP، \fBrecord\fP، \fBgeneric\fP\&. .TP .B \fBsupported_api_styles\fP فهرستی از سبک‌های API پشتیبانی‌شده با مقادیر ممکن \fBfunctions\fP، \fBfree\-form\fP\&. .TP .B \fBsupported_code_models\fP فهرستی از مدل‌های کد پشتیبانی‌شده با مقادیر ممکن \fBgoto\-label\fP، \fBloop\-switch\fP، \fBrecursive\-functions\fP\&. .TP .B \fBsupported_targets\fP فهرستی از هدف‌های تولید کد (codegen) پشتیبانی‌شده با مقادیر ممکن \fBcode\fP، \fBdot\fP، \fBskeleton\fP\&. .TP .B \fBsupported_features\fP فهرستی از ویژگی‌های پشتیبانی‌شده با مقادیر ممکن \fBnested\-ifs\fP، \fBbitmaps\fP، \fBcomputed\-gotos\fP، \fBcase\-ranges\fP، \fBmonadic\fP، \fBunsafe\fP، \fBtags\fP، \fBcaptures\fP، \fBcaptvars\fP\&. .UNINDENT .UNINDENT .UNINDENT .sp \fBپیکربندی‌های زبان (Language configurations)\fP .INDENT 0.0 .INDENT 3.5 چند پیکربندی بولی ویژگی‌های زبان مقصد را که بر تجزیه‌گر و تولیدکننده کد re2hs اثر می‌گذارند توصیف می‌کنند: .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 است. متغیرها جانگهدارنده‌هایی هستند که در مرحله تولید کد جایگزین می‌شوند. متغیرهای فهرستی ویژه هستند: هنگام بسط الگوهای فهرست، re2hs عبارات سمت راست دونقطه را چند بار تکرار می‌کند و هر بار رخدادهای متغیر فهرست را با مقداری مخصوص به این تکرار جایگزین می‌سازد. فهرست‌ها دارای کران‌های اختیاری هستند (مقادیر منفی از انتها شمرده می‌شوند، برای نمونه \fB\-1\fP به معنای آخرین عنصر است). نام‌های شرطی با یک نقطه آغاز می‌شوند. هر دو مورد شرط‌ها و متغیرها می‌توانند محلی (مخصوص همان الگوی کد) یا عمومی (مجاز در تمام الگوهای کد) باشند. هنگامی که re2hs یک فایل نحو را می‌خواند، بررسی می‌کند که هر الگوی کد تنها از متغیرها و شرط‌هایی استفاده کند که در آن مجاز هستند. .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 در اینجا فهرستی از تمام الگوهای کد پشتیبانی‌شده توسط re2hs به همراه متغیرها و شرط‌های محلی آن‌ها آورده شده است. توجه داشته باشید که یک تعریف خاص می‌تواند از متغیرها و شرط‌های محلی استفاده کند، اما الزامی به آن ندارد. هر الگوی کد استفاده‌نشده باید روی \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 تعریف یک شمارش یا enum (ممکن است با ساختار زبانی ویژه‌ای برای شمارش‌ها تعریف شود، یا صرفاً به‌صورت چند ثابت مستقل). متغیرهای پشتیبانی‌شده عبارتند از \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). .TP .B \fBcode:type_uint\fP نوع عدد صحیح بدون علامت (unsigned). .TP .B \fBcode:type_yybm\fP نوع عناصر در جدول \fByybm\fP. .TP .B \fBcode:type_yytarget\fP نوع عناصر در جدول \fByytarget\fP. .TP .B \fBcode:type_yyctable\fP نوع عناصر در جدول \fByyctable\fP. .TP .B \fBcode:cmp_eq\fP عملگر \(dqمساوی\(dq. .TP .B \fBcode:cmp_ne\fP عملگر \(dqنامساوی\(dq. .TP .B \fBcode:cmp_lt\fP عملگر \(dqکوچک‌تر از\(dq. .TP .B \fBcode:cmp_gt\fP عملگر \(dqبزرگ‌تر از\(dq. .TP .B \fBcode:cmp_le\fP عملگر \(dqکوچک‌تر یا مساوی\(dq. .TP .B \fBcode:cmp_ge\fP عملگر \(dqبزرگ‌تر یا مساوی\(dq. .TP .B \fBcode:if_then_else\fP دستور If\-then\-else با یک یا چند شاخه. متغیرهای پشتیبانی‌شده: \fBbranch\fP (متغیر فهرستی که به خودی خود کدی تولید نمی‌کند، اما عبارت فهرستی را به تعداد شاخه‌ها بسط می‌دهد)، \fBcond\fP (شرط شاخه جاری) و \fBstmt\fP (متغیر فهرستی که به تمام دستورهای شاخه جاری بسط می‌یابد). شرط‌ها: \fB\&.cond\fP (اگر شاخه جاری دارای شرط باشد درست است)، \fB\&.many\fP (اگر بیش از یک شاخه وجود داشته باشد درست است). .TP .B \fBcode:if_then_else_oneline\fP حالت خاصی از \fBcode:if_then_else\fP برای حالتی که تمام شاخه‌ها دستورهای تک‌خطی دارند. اگر این مقدار \fB\fP باشد، در عوض \fBcode:if_then_else\fP استفاده می‌شود. .TP .B \fBcode:switch\fP یک دستور switch با یک یا چند مورد (case). متغیرهای پشتیبانی‌شده: \fBexpr\fP (عبارتی که روی آن switch می‌شود) و \fBcase\fP (متغیر فهرستی که به تمام گروه‌های case همراه با بلوک‌های کدشان بسط می‌یابد). .TP .B \fBcode:switch_cases\fP گروهی از موارد switch که به یک بلوک کد واحد نگاشت می‌شوند. متغیرهای پشتیبانی‌شده عبارتند از \fBcase\fP (متغیر فهرستی که به تمام 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 یک مورد 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). متغیرهای پشتیبانی‌شده: \fBarray\fP (جدول حاوی اطلاعات \fBgoto\fP محاسباتی)، \fBindex\fP (اندیس عنصر در جدول) و \fBbase\fP (برچسب پایه، تنها در صورتی استفاده می‌شود که \fB\&.cgoto.relative\fP درست باشد). .TP .B \fBcode:cgoto:data\fP عبارت مقداردهی اولیه برای یک عنصر منفرد در جدول \fBgoto\fP محاسباتی. متغیرهای پشتیبانی‌شده: \fBlabel\fP (برچسبی که برای مقداردهی اولیه عنصر جاری استفاده می‌شود)، \fBtype\fP (نوع زیربنایی عناصر در جدول) و \fBbase\fP (برچسب پایه \- تنها در صورتی استفاده می‌شود که \fB\&.cgoto.relative\fP درست باشد). .TP .B \fBcode:fndecl\fP اعلان تابع. متغیرهای پشتیبانی‌شده: \fBname\fP (نام تابع)، \fBtype\fP (نوع بازگشتی)، \fBthrow\fP (استثناهای پرتاب‌شده توسط این تابع، که به پیکربندی \fBre2c:yyfn:throw\fP نگاشت می‌شود)، \fBarg\fP (متغیر فهرستی که خود کدی تولید نمی‌کند، اما عبارت فهرستی را به تعداد آرگومان‌های تابع بسط می‌دهد)، \fBargname\fP (نام آرگومان جاری)، \fBargtype\fP (نوع آرگومان جاری). شرط: \fB\&.type\fP (اگر تابع غیر void باشد، درست است). .TP .B \fBcode:fndef\fP مشابه \fBcode:fndecl\fP، اما برای تعریف تابع به کار می‌رود؛ بنابراین یک متغیر فهرستی اضافی به نام \fBstmt\fP دارد که به تمام دستورهای درون بدنه تابع بسط می‌یابد. .TP .B \fBcode:fncall\fP دستور فراخوانی تابع. متغیرهای پشتیبانی‌شده: \fBname\fP (نام تابع)، \fBretval\fP (یک l\-value که مقدار بازگشتی، در صورت وجود، در آن ذخیره می‌شود) و \fBarg\fP (متغیر فهرستی که به تمام آرگومان‌های تابع بسط می‌یابد). شرط‌ها: \fB\&.args\fP (اگر تابع دارای آرگومان باشد، درست است) و \fB\&.retval\fP (اگر نیاز به ذخیره مقدار بازگشتی باشد، درست است). .TP .B \fBcode:tailcall\fP دستور فراخوانی انتهایی (tail call). متغیرهای پشتیبانی‌شده: \fBname\fP (نام تابع)، و \fBarg\fP (متغیر فهرستی که به تمام آرگومان‌های تابع بسط می‌یابد). شرط‌ها: \fB\&.args\fP (اگر تابع دارای آرگومان باشد، درست است) و \fB\&.retval\fP (اگر تابع غیر void باشد، درست است). .TP .B \fBcode:recursive_functions\fP بدنه برنامه با مدل کد \fB\-\-recursive\-functions\fP. متغیرهای پشتیبانی‌شده: \fBfn\fP (متغیر فهرستی که به خودی خود کدی تولید نمی‌کند، اما عبارت فهرستی را به تعداد توابع بسط می‌دهد)، \fBfndecl\fP (اعلان تابع جاری) و \fBfndef\fP (تعریف تابع جاری)..TP .B \fBcode:fingerprint\fP اثر انگشت (fingerprint) در بالای فایل خروجی تولیدشده. متغیرهای پشتیبانی‌شده: \fBver\fP (نسخهٔ re2hs که برای تولید این فایل به کار رفته است) و \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 در اینجا فهرستی از تمام متغیرهای سراسری که در فایل‌های نحو (syntax) مجاز هستند، آمده است: .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 درست است اگر API عمومی (generic) استفاده شده باشد (\fB\-\-api generic\fP یا \fBre2c:api = generic\fP). .TP .B \fB\&.api.record\fP درست است اگر API رکوردی استفاده شده باشد (\fB\-\-api record\fP یا \fBre2c:api = record\fP). .TP .B \fB\&.api_style.functions\fP درست است اگر سبک API تابع‌گونه استفاده شده باشد (\fBre2c:api\-style = functions\fP). .TP .B \fB\&.api_style.freeform\fP درست است اگر سبک API آزاد‌شکل استفاده شده باشد (\fBre2c:api\-style = free\-form\fP). .TP .B \fB\&.case_ranges\fP درست است اگر قابلیت بازه‌های case فعال باشد (\fB\-\-case\-ranges\fP یا \fBre2c:case\-ranges = 1\fP). .TP .B \fB\&.cgoto.relative\fP درست است اگر شکل نسبی دستور \fBgoto\fP محاسبه‌شده استفاده شود (\fB\-\-computed\-gotos\-relative\fP یا \fBre2c:cgoto:relative = 1\fP). .TP .B \fB\&.code_model.goto_label\fP درست است اگر مدل کد مبتنی بر goto/label استفاده شده باشد (\fB\-\-goto\-label\fP). .TP .B \fB\&.code_model.loop_switch\fP درست است اگر مدل کد مبتنی بر loop/switch استفاده شده باشد (\fB\-\-loop\-switch\fP). .TP .B \fB\&.code_model.recursive_functions\fP درست است اگر مدل کد مبتنی بر توابع بازگشتی استفاده شده باشد (\fB\-\-recursive\-function\fP). .TP .B \fB\&.date\fP درست است اگر اثرانگشت (fingerprint) تولیدشده باید حاوی تاریخ تولید باشد. .TP .B \fB\&.loop_label\fP درست است اگر حلقه‌های تولیدشده توسط re2hs باید دارای برچسب باشند (\fBre2c:label:yyloop\fP روی یک رشتهٔ غیرخالی تنظیم شده باشد). .TP .B \fB\&.monadic\fP درست است اگر کد تولیدشده باید مونادیک (monadic) باشد (\fBre2c:monadic = 1\fP). این گزینه فقط برای زبان‌های تابعی محض کاربرد دارد. .TP .B \fB\&.start_conditions\fP درست است اگر شرایط شروع فعال باشند (\fB\-\-start\-conditions\fP). .TP .B \fB\&.storable_state\fP درست است اگر وضعیت قابل ذخیره‌سازی فعال باشد (\fB\-\-storable\-state\fP). .TP .B \fB\&.unsafe\fP درست است اگر re2hs باید به‌منظور تولید کد سریع‌تر از بلوک‌های \(dqunsafe\(dq استفاده کند (\fB\-\-unsafe\fP، \fBre2c:unsafe = 1\fP). این گزینه فقط برای زبان‌هایی که دارای قابلیت \(dqunsafe\(dq هستند کاربرد دارد. .TP .B \fB\&.version\fP درست است اگر اثرانگشت تولیدشده باید شامل نسخهٔ re2hs باشد. .TP .B \fB\&.yyfill.enable\fP درست است اگر \fBYYFILL\fP فعال باشد (\fBre2c:yyfill:enable = 1\fP). .TP .B \fB\&.yyfn.throw\fP درست است اگر پیکربندی \fBre2c:yyfn:throw\fP روی یک رشتهٔ غیرخالی تعریف شده باشد. .UNINDENT .UNINDENT .UNINDENT.SH "مدیریت پایان ورودی (HANDLING THE END OF INPUT)" .sp یکی از مسائل اصلی برای تحلیل‌گر لغوی (lexer)، تشخیص زمان توقف است. چند شرط برای پایان کار وجود دارد: .INDENT 0.0 .IP \(bu 2 تحلیل‌گر لغوی ممکن است با قاعده‌ای تطابق یابد (از جمله قاعدهٔ پیش‌فرض \fB*\fP) و به یک حالت نهایی (final state) برسد .IP \(bu 2 تحلیل‌گر لغوی ممکن است در تطبیق با هر قاعده‌ای ناکام بماند و به یک حالت پیش‌فرض (default state) برسد .IP \(bu 2 تحلیل‌گر لغوی ممکن است به پایان ورودی برسد .UNINDENT .sp دو شرط نخست، تحلیل‌گر لغوی را به روشی «طبیعی» خاتمه می‌دهند: تحلیل‌گر به حالتی بدون انتقال‌های خروجی می‌رسد و فرآیند تطبیق به‌طور خودکار متوقف می‌شود. شرط سوم، یعنی پایان ورودی، متفاوت است: این حالت می‌تواند در هر وضعیتی رخ دهد و تحلیل‌گر لغوی باید بتواند آن را مدیریت کند. بررسی پایان ورودی، جریان کار عادی تحلیل‌گر را قطع کرده و انشعاب‌های شرطی را به برنامهٔ تولیدشده اضافه می‌کند؛ بنابراین به حداقل رساندن تعداد این بررسی‌ها ضروری است. ابزار re2hs از چندین روش مختلف برای مدیریت پایان ورودی پشتیبانی می‌کند. انتخاب روش مناسب به پیچیدگی عبارات باقاعده، نیاز به بافرسازی، ملاحظات کارایی و عوامل دیگر بستگی دارد. در ادامه فهرستی از این روش‌ها آمده است: .INDENT 0.0 .IP \(bu 2 \fBسنتینل (Sentinel).\fP این روش نیاز به بررسی‌های پایان ورودی را به‌کلی برطرف می‌کند. این روش ساده و کارآمد است، اما محدود به مواردی است که یک نویسهٔ «سنتینل» طبیعی وجود داشته باشد که هرگز نتواند در ورودی معتبر رخ دهد. این نویسه ممکن است همچنان در ورودی‌های نامعتبر ظاهر شود، اما نباید توسط عبارات باقاعده مجاز دانسته شود، مگر شاید به عنوان آخرین نویسهٔ یک قاعده. نویسهٔ سنتینل به انتهای ورودی ضمیمه می‌شود و به عنوان سیگنال توقف عمل می‌کند: هنگامی که تحلیل‌گر لغوی این نویسه را می‌خواند، یا خطای نحوی رخ داده و یا پایان ورودی است. در هر دو حالت، تحلیل‌گر لغوی باید متوقف شود. این روش در صورتی استفاده می‌شود که \fBYYFILL\fP با دستور \fBre2c:yyfill:enable = 0;\fP غیرفعال شده باشد و \fBre2c:eof\fP مقدار پیش‌فرض \fB\-1\fP را داشته باشد\&. .nf .fi .sp .IP \(bu 2 \fBسنتینل با بررسی‌های مرزی (Sentinel with bounds checks).\fP این روش عمومی است: اجازه می‌دهد هر ورودی بدون محدودیت روی عبارات باقاعده مدیریت شود. ایدهٔ کار، کاهش تعداد بررسی‌های پایان ورودی از طریق انجام آن‌ها فقط بر روی نویسه‌های خاصی است. مشابه روش «سنتینل»، یکی از نویسه‌ها به عنوان «سنتینل» انتخاب شده و به انتهای ورودی ضمیمه می‌شود. با این حال، هیچ محدودیتی در محل وقوع سنتینل وجود ندارد (در واقع هر نویسه‌ای می‌تواند به عنوان سنتینل انتخاب شود). هنگامی که تحلیل‌گر لغوی این نویسه را می‌خواند، علاوه بر آن یک بررسی مرزها (bounds check) را نیز انجام می‌دهد. اگر موقعیت فعلی در محدودهٔ مجاز باشد، تحلیل‌گر تطبیق را از سر گرفته و با سنتینل مانند یک نویسهٔ عادی رفتار می‌کند. در غیر این صورت، \fBYYFILL\fP را فراخوانی می‌کند (مگر اینکه غیرفعال شده باشد). اگر ورودی بیشتری فراهم شود، تحلیل‌گر لغوی آخرین نویسه را مجدداً تطبیق داده و طوری ادامه می‌دهد که گویی سنتینل وجود نداشته است. در غیر این صورت، باید پایان واقعی ورودی باشد و تحلیل‌گر متوقف می‌شود. این روش زمانی استفاده می‌شود که \fBre2c:eof\fP مقداری غیرمنفی داشته باشد (باید روی مقدار عددی سنتینل تنظیم شود). استفاده از \fBYYFILL\fP اختیاری است. .nf .fi .sp .IP \(bu 2 \fBبررسی‌های مرزی با لایه‌گذاری (Bounds checks with padding).\fP این روش عمومی است و ممکن است سریع‌تر از روش «سنتینل با بررسی‌های مرزی» باشد، اما پیچیده‌تر نیز هست. ایده این است که حالت‌های DFA به مؤلفه‌های قویاً همبند (SCCها) افراز شوند و برای هر SCC یک بررسی منفرد برای تعداد نویسهٔ کافی جهت پوشش طولانی‌ترین مسیر بدون حلقه در آن SCC ایجاد گردد. این کار تعداد بررسی‌ها را کاهش می‌دهد، اما با لکسم‌های کوتاه در انتهای ورودی مشکلی ایجاد می‌کند، زیرا بررسی مذکور به نویسه‌های کافی برای پوشش طولانی‌ترین لکسم نیاز دارد. این مشکل را می‌توان با لایه‌گذاری (padding) ورودی با چند نویسهٔ ساختگی که پسوند لکسم معتبری را تشکیل نمی‌دهند (به‌طوری که تحلیل‌گر لغوی نتواند آن‌ها را تطبیق دهد) برطرف کرد. طول لایه‌گذاری باید \fBYYMAXFILL\fP باشد که با یک بلوک \fBmax\fP تولید می‌شود. اگر ورودی کافی نباشد، تحلیل‌گر لغوی \fBYYFILL\fP را فراخوانی می‌کند که باید حداقل تعداد نویسه‌های مورد نیاز را تأمین کند یا بازنگردد. این روش زمانی استفاده می‌شود که \fBYYFILL\fP فعال باشد و \fBre2c:eof\fP برابر با \fB\-1\fP باشد (این پیکربندی پیش‌فرض است). .nf .fi .sp .IP \(bu 2 \fBبررسی‌های سفارشی (Custom checks).\fP رابط برنامه‌نویسی عمومی (Generic API) امکان بازنویسی عملیات پایه مانند خواندن نویسه را فراهم می‌کند، که این امر گنجاندن بررسی‌های پایان ورودی را به عنوان بخشی از آن‌ها ممکن می‌سازد. این رویکرد مستعد خطا است و باید با احتیاط استفاده شود. برای استفاده از یک روش سفارشی، API عمومی را با \fB\-\-api custom\fP یا \fBre2c:api = custom;\fP فعال کرده و بررسی‌های مرزی پیش‌فرض را با \fBre2c:yyfill:enable = 0;\fP یا \fBre2c:yyfill:check = 0;\fP غیرفعال کنید\&. .UNINDENT .sp زیربخش‌های بعدی شامل مثالی از هر روش هستند..SS نگهبان (Sentinel) .sp این مثال از یک کاراکتر نگهبان برای مدیریت پایان ورودی استفاده می‌کند. این برنامه کلمات جداشده با فاصله را در یک رشتهٔ خاتمه‌یافته با null شمارش می‌کند. نگهبان همان null است: آخرین کاراکتر هر رشتهٔ ورودی است و طبق هیچ‌یک از قواعد در میانهٔ یک لکسم (lexeme) مجاز نیست (به‌ویژه، در بازه‌های کاراکتری که نادیده‌گرفتن آن آسان است گنجانده نشده است). اگر یک null در میانهٔ یک رشته رخ دهد، یک خطای نحوی است و تحلیل‌گر لغوی (lexer) با قاعدهٔ پیش‌فرض \fB*\fP تطبیق می‌یابد، اما فراتر از انتهای ورودی را نخواهد خواند و از کار نخواهد افتاد (برای تأیید این موضوع، از هشدار \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 \-\- re2hs $INPUT \-o $OUTPUT {\-# OPTIONS_GHC \-Wno\-unused\-record\-wildcards #\-} {\-# LANGUAGE OverloadedStrings #\-} import Control.Monad (when) import Data.ByteString (ByteString, index) data State = State { _yyinput :: ByteString, _yycursor :: Int, _count :: Int } \-\- expect a null\-terminated string %{ re2c:YYFN = [\(dqlexer;Int\(dq, \(dqState{..};State\(dq]; re2c:yyfill:enable = 0; * { (\-1) } [\ex00] { _count } [a\-z]+ { lexer State{_count = _count + 1, ..} } [ ]+ { lexer State{..} } %} main :: IO () main = do let test s n = when (lexer st /= n) $ error \(dqfailed\(dq where st = State{_yyinput = s, _yycursor = 0, _count = 0} test \(dq\e0\(dq 0 test \(dqone two three\e0\(dq 3 test \(dqf0ur\e0\(dq (\-1) .ft P .fi .UNINDENT .UNINDENT .SS نگهبان همراه با بررسی‌های مرز (Sentinel with bounds checks) .sp این مثال از نگهبان به همراه بررسی‌های مرز برای مدیریت پایان ورودی استفاده می‌کند (این روش در نسخهٔ 1.2 اضافه شد). این برنامه رشته‌های محصور در علامت نقل‌قول تکی که با فاصله جدا شده‌اند را شمارش می‌کند. کاراکتر نگهبان 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 \-\- re2hs $INPUT \-o $OUTPUT {\-# OPTIONS_GHC \-Wno\-unused\-record\-wildcards #\-} {\-# LANGUAGE OverloadedStrings #\-} import Control.Monad (when) import qualified Data.ByteString as BS import Data.Word data State = State { _yyinput :: BS.ByteString, _yycursor :: Int, _yymarker :: Int, _yylimit :: Int, _count :: Int } \-\- expect a null\-terminated string %{ re2c:YYFN = [\(dqlexer;Int\(dq, \(dqState{..};State\(dq]; re2c:YYCTYPE = \(dqWord8\(dq; re2c:YYPEEK = \(dqBS.index\(dq; re2c:eof = 0; re2c:yyfill:enable = 0; str = [\(aq] ([^\(aq\e\e] | [\e\e][^])* [\(aq]; * { (\-1) } $ { _count } str { lexer State{_count = _count + 1, ..} } [ ]+ { lexer State{..} } %} main :: IO () main = do let test s n = do let st = State { _yyinput = s, _yycursor = 0, _yymarker = 0, _yylimit = BS.length s \- 1, \-\- terminating null not included _count = 0} when (lexer st /= n) $ error \(dqfailed\(dq test \(dq\e0\(dq 0 test \(dq\(aqqu\e0tes\(aq \(aqare\(aq \(aqfine: \e\e\(aq\(aq \e0\(dq 3 test \(dq\(aqunterminated\e\e\(aq\e0\(dq (\-1) .ft P .fi .UNINDENT .UNINDENT.SS بررسی‌های محدوده با فاصله‌گذاری (Bounds checks with padding) .sp این مثال برای مدیریت پایان ورودی از بررسی‌های محدوده با فاصله‌گذاری (padding) استفاده می‌کند (این روش به‌طور پیش‌فرض فعال است). این برنامه رشته‌های محصور در نقل‌قول تکی را که با فاصله از یکدیگر جدا شده‌اند شمارش می‌کند. فاصله‌گذاری‌ای شامل \fBYYMAXFILL\fP نویسهٔ null به انتهای ورودی پیوست شده است، که مقدار \fBYYMAXFILL\fP در آن به‌طور خودکار توسط یک بلوک \fBmax\fP تولید می‌شود. الزامی به استفاده از null برای فاصله‌گذاری وجود ندارد \-\-\- تا زمانی که نویسه‌ها پسوند معتبری برای یک نشانه (lexeme) تشکیل ندهند، می‌توان از هر نویسه‌ای استفاده کرد (در این مثال فاصله‌گذاری نباید حاوی نقل‌قول تکی باشد، زیرا ممکن است با پسوند یک رشتهٔ محصور در نقل‌قول تکی اشتباه گرفته شود). یک قاعدهٔ \(dqstop\(dq وجود دارد که با نخستین نویسهٔ فاصله‌گذاری (null) تطابق می‌یابد و تحلیل‌گر لغوی را متوقف می‌کند (توجه داشته باشید که این قاعده بررسی می‌کند آیا null در ابتدای فاصله‌گذاری قرار دارد یا خیر، در غیر این صورت یک خطای نحوی است). بررسی‌های محدوده تنها در برخی از حالت‌ها که توسط مؤلفه‌های قویاً همبند (strongly connected components) در اتوماتون زیربنایی تعیین می‌شوند، تولید می‌گردند. بررسی‌ها به صورت \fB(YYLIMIT \- YYCURSOR) < n\fP یا در API عمومی به صورت \fBYYLESSTHAN(n)\fP هستند، که در آن‌ها \fBn\fP حداقل تعداد نویسه‌های مورد نیاز برای ادامهٔ کار تحلیل‌گر لغوی است (همچنین بدین معناست که بررسی محدودهٔ بعدی حداکثر تا \fBn\fP نویسهٔ دیگر رخ خواهد داد). اگر شرط بررسی درست باشد، تحلیل‌گر لغوی به انتهای ورودی رسیده است و \fBYYFILL(n)\fP را فراخوانی می‌کند که باید یا حداقل \fBn\fP نویسهٔ ورودی را تأمین کند یا بازگشتی نداشته باشد. در این مثال \fBYYFILL\fP همواره با شکست مواجه شده و تحلیل‌گر لغوی را با یک خطا متوقف می‌کند (که مشکلی ایجاد نمی‌کند زیرا تمام ورودی درون یک بافر جا می‌شود). برای مثالی که بافر ورودی را با استفاده از \fBYYFILL\fP دوباره پر می‌کند، بخش \fI\%YYFILL with padding\fP را ببینید\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C \-\- re2hs $INPUT \-o $OUTPUT {\-# OPTIONS_GHC \-Wno\-unused\-record\-wildcards #\-} {\-# LANGUAGE OverloadedStrings #\-} import Control.Exception import Control.Monad (when) import qualified Data.ByteString as BS data State = State { _yyinput :: BS.ByteString, _yycursor :: Int, _yylimit :: Int, _count :: Int } data FillException = UnexpectedFill deriving (Show) instance Exception FillException yymaxfill :: Int %{max %} %{ re2c:YYFN = [\(dqlexer;IO Int\(dq, \(dqState{..};State\(dq]; re2c:YYPEEK = \(dqBS.index\(dq; re2c:YYFILL = \(dqthrow UnexpectedFill\(dq; re2c:monadic = 1; // YYFILL requires monadic do\-notation for \(gawhen\(ga conditions str = [\(aq] ([^\(aq\e\e] | [\e\e][^])* [\(aq]; [\ex00] { \-\- check that it is the sentinel, not some unexpected null return $ if _yycursor == BS.length _yyinput \- yymaxfill + 1 then _count else (\-1) } str { lexer State{_count = _count + 1, ..} } [ ]+ { lexer State{..} } * { return (\-1) } %} main :: IO () main = do let test s n = do let buf = BS.concat [s, BS.replicate yymaxfill 0] let st = State { _yyinput = buf, _yycursor = 0, _yylimit = BS.length buf, _count = 0} m <\- catch (lexer st) (\e(_ :: FillException) \-> return (\-2)) when (m /= n) $ error \(dqfailed\(dq test \(dq\(dq 0 test \(dq\(aqunterminated\e\e\(aq\(dq (\-2) test \(dq\(aqqu\e0tes\(aq \(aqare\(aq \(aqfine: \e\e\(aq\(aq \(dq 3 test \(dq\(aqunexpected\(aq \e0 \(aqnull\(aq\(dq (\-1) .ft P .fi .UNINDENT .UNINDENT.SS "بررسی‌های سفارشی (Custom checks)" .sp این مثال از یک روش سفارشی مدیریت پایان ورودی بر پایه‌ی generic API استفاده می‌کند. این برنامه رشته‌های تک‌کوتیشن‌دار جداشده با فاصله را شمارش می‌کند. این مثال همانند مثال \fI\%sentinel\fP است، با این تفاوت که ورودی با null خاتمه نمی‌یابد. برای جبران نبود نویسه نگه‌بان در انتهای ورودی، \fBYYPEEK\fP بازتعریف شده است تا پیش از خواندن نویسه بعدی ورودی، یک بررسی محدوده انجام دهد. این کار ناکارآمد است زیرا بررسی‌ها بسیار مکرر انجام می‌شوند. اگر شرط بررسی رد شود، \fBYYPEEK\fP نویسه واقعی را بازمی‌گرداند، در غیر این صورت یک نویسه نگه‌بان ساختگی بازمی‌گرداند. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C \-\- re2hs $INPUT \-o $OUTPUT {\-# OPTIONS_GHC \-Wno\-unused\-record\-wildcards #\-} {\-# LANGUAGE OverloadedStrings #\-} import Control.Monad (when) import qualified Data.ByteString as BS data State = State { _str :: BS.ByteString, _cur :: Int, _lim :: Int, _cnt :: Int } \-\- Expect a string without terminating null. %{ re2c:api = generic; re2c:YYFN = [\(dqlexer;Int\(dq, \(dqState{..};State\(dq]; re2c:YYPEEK = \(dqif _cur < _lim then BS.index _str _cur else 0\(dq; re2c:YYSKIP = \(dqlet cur = _cur + 1 in let _cur = cur in\(dq; re2c:yyfill:enable = 0; * { (\-1) } [\ex00] { _cnt } [a\-z]+ { lexer State{_cnt = _cnt + 1, ..} } [ ]+ { lexer State{..} } %} main :: IO () main = do let test s n = let st = State {_str = s, _cur = 0, _lim = BS.length s, _cnt = 0} in when (lexer st /= n) $ error \(dqfailed\(dq test \(dq\(dq 0 test \(dqone two three \(dq 3 test \(dqf0ur\(dq (\-1) .ft P .fi .UNINDENT .UNINDENT .SH "پر کردن مجدد بافر (BUFFER REFILLING)" .sp نیاز به بافرسازی زمانی پیش می‌آید که ورودی نتواند به‌یک‌باره در حافظه نگاشت شود: یا به دلیل اینکه بسیار حجیم است، یا اینکه به‌صورت جریانی (مانند خواندن از یک سوکت) وارد می‌شود. تکنیک معمول در چنین مواردی، تخصیص یک بافر حافظه با اندازه ثابت و پردازش ورودی در تکه‌هایی است که در بافر جا می‌شوند. هنگامی که تکه فعلی پردازش شد، به بیرون منتقل شده و داده‌های جدید وارد می‌شوند. در عمل این کار تا حدودی پیچیده‌تر است، زیرا وضعیت لکسر تنها از یک موقعیت ورودی تشکیل نشده، بلکه شامل مجموعه‌ای از موقعیت‌های مرتبط با یکدیگر است: .INDENT 0.0 .IP \(bu 2 مکان‌نما (cursor): نویسه ورودی بعدی که باید خوانده شود (\fBYYCURSOR\fP در C pointer API یا \fBYYSKIP\fP/\fBYYPEEK\fP در generic API) .IP \(bu 2 حد (limit): موقعیت پس از آخرین نویسه در دسترس ورودی (\fBYYLIMIT\fP در C pointer API، که به‌طور ضمنی توسط \fBYYLESSTHAN\fP در generic API مدیریت می‌شود) .IP \(bu 2 نشانه‌گذار (marker): موقعیت تازه‌ترین تطابق، در صورت وجود (\fBYYMARKER\fP در default API یا \fBYYBACKUP\fP/\fBYYRESTORE\fP در generic API) .IP \(bu 2 توکن (token): آغاز نشانه (lexeme) فعلی (در re2hs API ضمنی است، زیرا برای عملکرد عادی لکسر نیازی به آن نیست و می‌تواند توسط کاربر تعریف و به‌روزرسانی شود) .IP \(bu 2 نشانه‌گذار بافتار (context marker): موقعیت بافتار پس‌رو (\fBYYCTXMARKER\fP در C pointer API یا \fBYYBACKUPCTX\fP/\fBYYRESTORECTX\fP در generic API) .IP \(bu 2 متغیرهای تگ (tag variables): موقعیت‌های زیرتطابق (تعریف‌شده با بلوک‌های \fBstags\fP و \fBmtags\fP و توابع پایه‌ای generic API شامل \fBYYSTAGP\fP/\fBYYSTAGN\fP/\fBYYMTAGP\fP/\fBYYMTAGN\fP) .UNINDENT .sp همه‌ی این موارد در هر حالتی استفاده نمی‌شوند، اما در صورت استفاده، باید توسط \fBYYFILL\fP\& به‌روزرسانی شوند. تمام موقعیت‌های فعال در بخشی بین token و cursor قرار دارند، بنابراین هر چیزی بین آغاز بافر و token را می‌توان دور انداخت، بخش بین token تا limit باید به ابتدای بافر منتقل شود، و فضای خالی در انتهای بافر باید با داده‌های جدید پر گردد. برای جلوگیری از فراخوانی‌های مکرر \fBYYFILL\fP\&، بهتر است تا حد امکان نویسه‌های ورودی بیشتری پر شوند (حتی اگر نویسه‌های کمتری برای ازسرگیری لکسر کافی باشد). جزئیات پیاده‌سازی \fBYYFILL\fP بسته به روش مدیریت EOF استفاده‌شده کمی متفاوت است: حالت قاعده EOF تا حدودی ساده‌تر از حالت بررسی محدوده با لایه‌گذاری (padding) است. همچنین توجه داشته باشید که اگر گزینه \fB\-f \-\-storable\-state\fP استفاده شود، \fBYYFILL\fP معناشناسی اندکی متفاوت خواهد داشت (که در بخش مربوط به وضعیت ذخیره‌پذیر توضیح داده شده است)..SS "YYFILL همراه با نگه‌بان (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 \-\- re2hs $INPUT \-o $OUTPUT {\-# OPTIONS_GHC \-Wno\-unused\-record\-wildcards #\-} {\-# LANGUAGE OverloadedStrings #\-} import Control.Monad import Data.ByteString as BS import Data.Word import GHC.IO.Handle import System.Directory import System.IO chunk_size :: Int chunk_size = 4096 data State = State { _file :: !Handle, _yyinput :: !BS.ByteString, _yycursor :: !Int, _yymarker :: !Int, _yylimit :: !Int, _token :: !Int, _eof :: !Bool, _count :: !Int } %{ re2c:YYFN = [\(dqlexer;IO Int\(dq, \(dqState{..};State;!State{..}\(dq]; re2c:YYCTYPE = \(dqWord8\(dq; re2c:YYPEEK = \(dqBS.index\(dq; re2c:YYFILL = \(dq(State{..}, yyfill) <\- fill State{..}\(dq; re2c:eof = 0; re2c:monadic = 1; str = [\(aq] ([^\(aq\e\e] | [\e\e][^])* [\(aq]; * { return (\-1) } $ { return _count } str { lexer State{_token = _yycursor, _count = _count + 1, ..} } [ ]+ { lexer State{_token = _yycursor, ..} } %} fill :: State \-> IO (State, Bool) fill State{..} = do case _eof of True \-> return (State{..}, False) False \-> do \-\- Discard everything up to the current token, cut off terminating null, \-\- read new chunk from file and reappend terminating null at the end. chunk <\- BS.hGet _file chunk_size return (State { _yyinput = BS.concat [(BS.init . BS.drop _token) _yyinput, chunk, \(dq\e0\(dq], _yycursor = _yycursor \- _token, _yymarker = _yymarker \- _token, _yylimit = _yylimit \- _token + BS.length chunk, \-\- exclude terminating null _token = 0, _eof = BS.null chunk, \-\- end of file? ..}, True) main :: IO () main = do let fname = \(dqinput\(dq \-\- Prepare input file. BS.writeFile fname $ BS.concat [\(dq\(aqqu\e0tes\(aq \(aqare\(aq \(aqfine: \e\e\(aq\(aq \(dq | _ <\- [1..chunk_size]] let expect = 3 * chunk_size \-\- the total number of strings in file \-\- Run lexer on the prepared file. fh <\- openFile fname ReadMode let st = State { _file = fh, _yyinput = BS.singleton 0, _yycursor = 0, _yymarker = 0, _token = 0, _yylimit = 0, _eof = False, _count = 0 } result <\- lexer st hClose fh \-\- Cleanup. removeFile fname \-\- Check result. when (result /= expect) $ error $ \(dqexpected \(dq ++ show expect ++ \(dq, got \(dq ++ show result return () .ft P .fi .UNINDENT .UNINDENT.SS "YYFILL به همراه پدینگ" .sp در حالت پیش‌فرض (زمانی که قاعدهٔ EOF به کار نمی‌رود)، \fBYYFILL\fP یک سازوکار پایه‌ایِ شبه‌تابع است که یک تک‌آرگومان را می‌پذیرد و هیچ مقداری را برنمی‌گرداند. فراخوانی \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 \-\- re2hs $INPUT \-o $OUTPUT {\-# OPTIONS_GHC \-Wno\-unused\-record\-wildcards #\-} {\-# LANGUAGE OverloadedStrings #\-} import Control.Monad import qualified Data.ByteString as BS import GHC.IO.Handle import System.Directory import System.IO chunk_size :: Int chunk_size = 4096 data State = State { _file :: !Handle, _yyinput :: !BS.ByteString, _yycursor :: !Int, _yylimit :: !Int, _token :: !Int, _eof :: !Bool, _count :: !Int } %{ re2c:YYFN = [\(dqlexer;IO Int\(dq, \(dqState{..};State;!State{..}\(dq]; re2c:YYPEEK = \(dqBS.index\(dq; // We have to turn off autogenerated YFILL check and write it manually as part of YYFILL // implementation, so that we can propagate the updated state out of it. re2c:yyfill:check = 0; re2c:YYFILL = \(dqState{..} <\- fill State{..} @@\(dq; re2c:monadic = 1; str = [\(aq] ([^\(aq\e\e] | [\e\e][^])* [\(aq]; * { return (\-1) } [\ex00] { return $ if _yycursor == _yylimit \- yymaxfill + 1 then _count else (\-1) } str { lexer State{_token = _yycursor, _count = _count + 1, ..} } [ ]+ { lexer State{_token = _yycursor, ..} } %} yymaxfill :: Int %{max %} fill :: State \-> Int \-> IO State fill !st@State{..} !need = if _yylimit \- _yycursor >= need then return st else case _eof of True \-> error \(dqfill failed\(dq False \-> do \-\- Discard everything up to the current token, cut off terminating null, \-\- read new chunk from file and reappend terminating null at the end. chunk <\- BS.hGet _file chunk_size let !eof = BS.length chunk < need \-\- end of file ? let !buf = BS.concat [ BS.drop _token _yyinput, chunk, if eof then (BS.replicate yymaxfill 0) else BS.empty] return State { _yyinput = buf, _yycursor = _yycursor \- _token, _yylimit = BS.length buf, _token = 0, _eof = eof, ..} main :: IO () main = do let fname = \(dqinput\(dq \-\- Prepare input file. BS.writeFile fname $ BS.concat [\(dq\(aqqu\e0tes\(aq \(aqare\(aq \(aqfine: \e\e\(aq\(aq \(dq | _ <\- [1..chunk_size]] let expect = 3 * chunk_size \-\- the total number of strings in file \-\- Run lexer on the prepared file. fh <\- openFile fname ReadMode let st = State { _file = fh, _yyinput = BS.empty, _yycursor = 0, _token = 0, _yylimit = 0, _eof = False, _count = 0 } result <\- lexer st hClose fh \-\- Cleanup. removeFile fname \-\- Check result. when (result /= expect) $ error $ \(dqexpected \(dq ++ show expect ++ \(dq, got \(dq ++ show result return () .ft P .fi .UNINDENT .UNINDENT.SH "ویژگی‌ها (FEATURES)" .SS "چندین بلوک (Multiple blocks)" .sp گاهی اوقات لازم است چندین تحلیل‌گر لغوی (lexer) مرتبط با یکدیگر داشته باشیم (برای مثال، اگر یک ماشین وضعیت سطح بالا وجود داشته باشد که بین حالت‌های مختلف تحلیل‌گر جابجا می‌شود). این قابلیت می‌تواند با استفاده از چندین بلوک متصل re2hs پیاده‌سازی شود. گزینه دیگر، استفاده از \fI\%start conditions\fP است. .sp پیاده‌سازی اتصالات میان بلوک‌ها به زبان مقصد بستگی دارد. در زبان‌هایی که دستور \fBgoto\fP دارند (مانند C/C++ و Go) می‌توان همه بلوک‌ها را در یک تابع قرار داد، به طوری که ابتدای هر کدام یک برچسب (label) قرار گیرد. گذار از یک بلوک به بلوک دیگر یک \fBgoto\fP ساده است. در زبان‌هایی که دستور \fBgoto\fP ندارند (مانند Rust) استفاده از یک حلقه به همراه switch روی یک متغیر وضعیت ضروری است، مشابه با حلقه/switch تولید شده برای \fByystate\fP توسط re2hs، یا اینکه هر بلوک درون یک تابع قرار گرفته و از فراخوانی توابع استفاده شود. .sp مثال زیر از چندین بلوک برای تجزیه اعداد دودویی (binary)، هشت‌هشتی (octal)، ده‌دهی (decimal) و شانزده‌شانزدهی (hexadecimal) استفاده می‌کند. هر مبنا بلوک مختص به خود را دارد. بلوک اولیه مبنا را تعیین کرده و به بلوک‌های دیگر هدایت می‌کند. پیکربندی‌های مشترک در یک بلوک مجزا در ابتدای برنامه تعریف شده‌اند؛ این تنظیمات توسط سایر بلوک‌ها به ارث برده می‌شوند. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C \-\- re2hs $INPUT \-o $OUTPUT \-i {\-# OPTIONS_GHC \-Wno\-unused\-record\-wildcards #\-} {\-# LANGUAGE OverloadedStrings #\-} import Control.Monad (when) import Data.ByteString (ByteString, index) data State = State { _yyinput :: !ByteString, _yycursor :: !Int, _yymarker :: !Int } peek_digit :: ByteString \-> Int \-> Int \-> Int peek_digit str idx offs = fromIntegral (index str (idx \- 1)) \- offs %{ re2c:yyfill:enable = 0; %} %{local re2c:YYFN = [\(dqparse_bin;Int\(dq, \(dqState{..};State\(dq, \(dqnum;Int\(dq]; [01] { parse_bin State{..} $ num * 2 + (peek_digit _yyinput _yycursor 48) } * { num } %} %{local re2c:YYFN = [\(dqparse_oct;Int\(dq, \(dqState{..};State\(dq, \(dqnum;Int\(dq]; [0\-7] { parse_oct State{..} $ num * 8 + (peek_digit _yyinput _yycursor 48) } * { num } %} %{local re2c:YYFN = [\(dqparse_dec;Int\(dq, \(dqState{..};State\(dq, \(dqnum;Int\(dq]; [0\-9] { parse_dec State{..} $ num * 10 + (peek_digit _yyinput _yycursor 48) } * { num } %} %{local re2c:YYFN = [\(dqparse_hex;Int\(dq, \(dqState{..};State\(dq, \(dqnum;Int\(dq]; [0\-9] { parse_hex State{..} $ num * 16 + (peek_digit _yyinput _yycursor 48) } [a\-f] { parse_hex State{..} $ num * 16 + (peek_digit _yyinput _yycursor 87) } [A\-F] { parse_hex State{..} $ num * 16 + (peek_digit _yyinput _yycursor 55) } * { num } %} %{local re2c:YYFN = [\(dqparse;Maybe Int\(dq, \(dqState{..};State\(dq]; \(aq0b\(aq / [01] { Just $ parse_bin State{..} 0 } \(dq0\(dq { Just $ parse_oct State{..} 0 } \(dq\(dq / [1\-9] { Just $ parse_dec State{..} 0 } \(aq0x\(aq / [0\-9a\-fA\-F] { Just $ parse_hex State{..} 0 } * { Nothing } %} test :: ByteString \-> Maybe Int \-> IO () test str expect = do let s = State {_yyinput = str, _yycursor = 0, _yymarker = 0} when (parse s /= expect) $ error \(dqfailed!\(dq main :: IO () main = do test \(dq\e0\(dq Nothing test \(dq1234567890\e0\(dq (Just 1234567890) test \(dq0b1101\e0\(dq (Just 13) test \(dq0x7Fe\e0\(dq (Just 2046) test \(dq0644\e0\(dq (Just 420) test \(dq9223372036854775807\e0\(dq (Just 9223372036854775807) .ft P .fi .UNINDENT .UNINDENT.SS "شرایط شروع (Start conditions)" .sp شرایط شروع با گزینهٔ \fB\-\-start\-conditions\fP فعال می‌شوند. آن‌ها روشی را برای کدگذاری چندین اتوماتون مرتبط با یکدیگر درون همان بلوک re2hs فراهم می‌کنند. .sp هر شرط متناظر با یک اتوماتون منفرد است و یک نام یکتای مشخص‌شده توسط کاربر و یک شمارهٔ داخلی یکتای تعریف‌شده توسط re2hs\& دارد. این شماره‌ها برای جابه‌جایی میان شرط‌ها استفاده می‌شوند: کد تولیدشده از پیش‌ساخته‌های \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 کدی که re2hs برای شرط‌ها تولید می‌کند به این بستگی دارد که آیا re2hs از رویکرد goto/label استفاده می‌کند یا از رویکرد loop/switch برای کدگذاری اتوماتا\&. .sp در زبان‌هایی که دارای دستور \fBgoto\fP هستند (مانند C/C++ و Go)، شرط‌ها به‌طور طبیعی به صورت بلوک‌هایی از کد با برچسب‌هایی به شکل \fByyc_\fP پیاده‌سازی می‌شوند، که در آن \fBcond\fP نام شرط است (پیشوند برچسب را می‌توان با \fBre2c:cond:prefix\fP تغییر داد). گذارها میان شرط‌ها با استفاده از \fBgoto\fP و برچسب‌های شرط پیاده‌سازی می‌شوند. پیش از تمام شرط‌ها، re2hs یک switch اولیه بر روی \fBYYGETSTATE\fP تولید می‌کند که به وضعیت شروع شرط فعلی پرش می‌کند. قواعد میان‌بر \fB:=>\fP این switch اولیه را دور می‌زنند و مستقیماً به شرط مشخص‌شده پرش می‌کنند (از \fBre2c:cond:goto\fP می‌توان برای تغییر رفتار پیش‌فرض استفاده کرد). قواعد دارای اعمال معنایی به‌طور خودکار به شرط بعدی پرش نمی‌کنند؛ این کار باید توسط کد عمل تعریف‌شده توسط کاربر انجام گیرد. .sp در زبان‌هایی که فاقد \fBgoto\fP هستند (مانند Rust)، re2hs از متغیر \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 \-\- re2hs $INPUT \-o $OUTPUT \-ci {\-# OPTIONS_GHC \-Wno\-unused\-record\-wildcards #\-} {\-# LANGUAGE OverloadedStrings #\-} import Control.Monad (when) import Data.ByteString (ByteString, index) %{conditions %} data State = State { _yyinput :: !ByteString, _yycursor :: !Int, _yymarker :: !Int, _yycond :: !YYCONDTYPE } peek_digit :: ByteString \-> Int \-> Int \-> Int peek_digit str idx offs = fromIntegral (index str (idx \- 1)) \- offs %{ re2c:YYFN = [\(dqparse;Maybe Int\(dq, \(dqState{..};State\(dq, \(dq_num;Int\(dq]; re2c:yyfill:enable = 0; \(aq0b\(aq / [01] :=> bin \(dq0\(dq :=> oct \(dq\(dq / [1\-9] :=> dec \(aq0x\(aq / [0\-9a\-fA\-F] :=> hex * { Nothing } [01] { yyfnbin State{..} $ _num * 2 + (peek_digit _yyinput _yycursor 48) } [0\-7] { yyfnoct State{..} $ _num * 8 + (peek_digit _yyinput _yycursor 48) } [0\-9] { yyfndec State{..} $ _num * 10 + (peek_digit _yyinput _yycursor 48) } [0\-9] { yyfnhex State{..} $ _num * 16 + (peek_digit _yyinput _yycursor 48) } [a\-f] { yyfnhex State{..} $ _num * 16 + (peek_digit _yyinput _yycursor 87) } [A\-F] { yyfnhex State{..} $ _num * 16 + (peek_digit _yyinput _yycursor 55) } * { Just _num } %} test :: ByteString \-> Maybe Int \-> IO () test str expect = do let s = State { _yyinput = str, _yycursor = 0, _yymarker = 0, _yycond = YYC_init} when (parse s 0 /= expect) $ error \(dqfailed!\(dq main :: IO () main = do test \(dq\e0\(dq Nothing test \(dq1234567890\e0\(dq (Just 1234567890) test \(dq0b1101\e0\(dq (Just 13) test \(dq0x7Fe\e0\(dq (Just 2046) test \(dq0644\e0\(dq (Just 420) test \(dq9223372036854775807\e0\(dq (Just 9223372036854775807) .ft P .fi .UNINDENT .UNINDENT.SS وضعیت قابل ذخیره‌سازی (Storable state) .sp با گزینهٔ \fB\-\-storable\-state\fP، برنامهٔ re2hs یک تحلیل‌گر لغوی تولید می‌کند که می‌تواند وضعیت کنونی خود را ذخیره کند، به فراخواننده بازگردد، و بعداً عملیات را دقیقاً از همان‌جایی که رها کرده بود از سر بگیرد. حالت پیش‌فرض عملکرد در re2hs یک مدل «کِششی» (\(dqpull\(dq) است که در آن تحلیل‌گر لغوی هر زمان که به ورودی بیشتری نیاز داشته باشد آن را «می‌کشد». این حالت ممکن است در مواردی که ورودی به صورت تکه‌تکه در دسترس قرار می‌گیرد غیرقابل قبول باشد (برای مثال، اگر تحلیل‌گر لغوی توسط تجزیه‌کننده فراخوانی شود، یا اگر برنامهٔ تحلیل‌گر لغوی از طریق پروتکل سوکت با برنامهٔ دیگری ارتباط برقرار کند که باید پیش از ارسال پیام بعدی، منتظر پاسخ از تحلیل‌گر لغوی بماند). قابلیت وضعیت قابل ذخیره‌سازی دقیقاً برای چنین مواردی در نظر گرفته شده است: این ویژگی امکان می‌دهد تحلیل‌گرهای لغوی تولید شوند که در یک مدل «رانشی» (\(dqpush\(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) ممکن است کار نکند زیرا مشخص نیست چه زمانی باید پدینگ اضافه شود: پایان فعلی ورودی ممکن است پایان نهایی ورودی نباشد، و افزودن زودهنگام پدینگ ممکن است یک لکسم طماع را که به طور جزئی خوانده شده است ناقص قطع کند. علاوه بر این، به دلیل منطق سطح بالای برنامه، دریافت ورودی بیشتر ممکن است به پردازش لکسم در انتهای بافر وابسته باشد (که خود به دلیل شرط پایان ورودی مسدود شده است). .UNINDENT .sp در اینجا مثالی از یک تحلیل‌گر لغوی با مدل «رانشی» (\(dqpush\(dq) آورده شده است که خواندن بسته‌ها از یک سوکت را شبیه‌سازی می‌کند. تحلیل‌گر لغوی تا زمانی که با پایان ورودی مواجه شود در حلقه اجرا می‌شود و به تابع فراخواننده بازمی‌گردد. تابع فراخواننده با «ارسال» بستهٔ بعدی ورودی بیشتری را فراهم می‌کند و تحلیل لغوی را از سر می‌گیرد. این فرآیند زمانی متوقف می‌شود که همهٔ بسته‌ها ارسال شده باشند، یا خطایی رخ دهد. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C \-\- re2hs $INPUT \-o $OUTPUT \-fi {\-# OPTIONS_GHC \-Wno\-unused\-record\-wildcards #\-} {\-# LANGUAGE OverloadedStrings #\-} import Control.Concurrent.Chan import Control.Monad import Data.ByteString as BS import Text.Printf debug :: IO () \-> IO () debug = when False data State = State { _pipe :: !(Chan BS.ByteString), _yyinput :: !BS.ByteString, _yycursor :: !Int, _yymarker :: !Int, _yylimit :: !Int, _token :: !Int, _eof :: !Bool, _yystate :: !Int, _recv :: !Int } data Status = End | Ready | Waiting | BadPacket deriving (Eq) %{ re2c:YYFN = [\(dqlexer;IO (State, Status)\(dq, \(dqState{..};State;!State{..}\(dq]; re2c:YYPEEK = \(dqBS.index\(dq; re2c:YYFILL = \(dqreturn (State{..}, Waiting)\(dq; re2c:eof = 0; re2c:monadic = 1; packet = [a\-z]+[;]; * { return (State{..}, BadPacket) } $ { return (State{..}, End) } packet { lexer State{_token = _yycursor, _recv = _recv + 1, ..} } %} fill :: State \-> IO (State, Status) fill st@State{..} = do case _eof of True \-> return (st, End) False \-> do \-\- Discard everything up to the current token, cut off terminating null, \-\- read new chunk from file and reappend terminating null at the end. chunk <\- readChan _pipe return (State { _yyinput = BS.concat [(BS.init . BS.drop _token) _yyinput, chunk, \(dq\e0\(dq], _yycursor = _yycursor \- _token, _yymarker = _yymarker \- _token, _yylimit = _yylimit \- _token + BS.length chunk, \-\- exclude terminating null _token = 0, _eof = BS.null chunk, \-\- end of file? ..}, Ready) loop :: State \-> [BS.ByteString] \-> IO Status loop State{..} packets = do (State{..}, status) <\- lexer State{..} case status of End \-> do debug $ printf \(dqdone: got %d packets\en\(dq _recv return End Waiting \-> do debug $ printf \(dqwaiting...\en\(dq packets\(aq <\- case packets of [] \-> do writeChan _pipe BS.empty return [] p:ps \-> do debug $ printf \(dqsent packet \(aq%s\(aq\en\(dq (show p) writeChan _pipe p return ps (State{..}, status\(aq) <\- fill State{..} case status\(aq of Ready \-> loop State{..} packets\(aq _ \-> error \(dqunexpected status after fill\(dq BadPacket \-> do debug $ printf \(dqerror: ill\-formed packet\en\(dq return BadPacket _ \-> error \(dqunexpected status\(dq test :: [BS.ByteString] \-> Status \-> IO () test packets expect = do pipe <\- newChan \-\- emulate pipe using a chan of bytestrings let st = State { _pipe = pipe, _yyinput = BS.singleton 0, \-\- null sentinel triggers YYFILL _yycursor = 0, _yymarker = 0, _token = 0, _yylimit = 0, _eof = False, _yystate = \-1, _recv = 0 } status <\- loop st packets when (status /= expect) $ error \(dqfailed\(dq return () main :: IO () main = do test [] End test [\(dqze\(dq, \(dqro;o\(dq, \(dqne\(dq, \(dq;t\(dq, \(dqwo;thr\(dq, \(dqe\(dq, \(dqe\(dq, \(dq;\(dq, \(dqfour;\(dq] End test [\(dqzer0;\(dq] BadPacket .ft P .fi .UNINDENT .UNINDENT.SS بلوک‌های قابل استفاده مجدد .sp بلوک‌های قابل استفاده مجدد به شکل \fB/*!rules:re2c[:] ... */\fP یا \fB%{rules[:] ... %}\fP می‌توانند به هر تعداد دفعات دوباره استفاده شوند و با دیگر بلوک‌های re2hs ترکیب گردند. مقدار \fB\fP اختیاری است. یک بلوک rules می‌تواند در یک بلوک یا دستورالعمل \fBuse\fP به کار رود. کد مربوط به یک بلوک rules در هر نقطه از استفاده تولید می‌شود. .sp بلوک‌های use با \fB/*!use:re2c[:] ... */\fP یا \fB%{use[:] ... %}\fP\& تعریف می‌شوند. مقدار \fB\fP اختیاری است: اگر مشخص نشده باشد، بلوک rules مرتبط، نزدیک‌ترین (جدیدترین) بلوک خواهد بود (خواه نام‌گذاری‌شده باشد یا بدون نام). یک بلوک use می‌تواند تعاریف نام‌گذاری‌شده، پیکربندی‌ها و قوانین مختص به خود را اضافه کند. یک مورد کاربرد مهم برای بلوک‌های use، تحلیل‌گر واژگانی (lexer) با پشتیبانی از چندین کدگذاری ورودی است: همان بلوک rules چندین بار با پیکربندی‌های مختص هر کدگذاری مجدداً استفاده می‌شود (مثال زیر را ببینید). .sp دستورالعمل درون‌بلوکی \fB!use:;\fP می‌تواند از درون یک بلوک re2hs استفاده شود. این دستور، بلوک ارجاع‌داده‌شده‌ی \fB\fP را در بلوک جاری ادغام می‌کند. اگر برخی از قوانین و پیکربندی‌های ادغام‌شده با موارد تعریف‌شده پیشین هم‌پوشانی داشته باشند، تداخل‌ها به شیوه معمول حل می‌شوند: نخستین قانون اولویت دارد، و آخرین پیکربندی جایگزین موارد پیشین می‌شود. یک استثنا، قوانین ویژه \fB*\fP، \fB$\fP و (در حالت شرطی) \fB\fP هستند که در آن‌ها تعریف محلیِ بلوک بر تعاریف به ارث رسیده برتری دارد. دستورالعمل use امکان ترکیب بلوک‌های مختلف re2hs را در یک بلوک واحد فراهم می‌کند (مثال زیر را ببینید). .sp بلوک‌های نام‌گذاری‌شده و دستورالعمل درون‌بلوکی use در نگارش 2.2 از re2hs اضافه شدند. از آن نگارش به بعد، بلوک‌های قابل استفاده مجدد به‌طور پیش‌فرض مجاز هستند (نیازی به گزینه خاصی نیست). پیش از نگارش 2.2، حالت استفاده مجدد با گزینه \fB\-r \-\-reusable\fP فعال می‌شد. پیش از نگارش 1.2، امکان ترکیب بلوک‌های قابل استفاده مجدد با بلوک‌های معمولی وجود نداشت. .SS مثالی از دستورالعمل \fB!use\fP .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C \-\- re2hs $INPUT \-o $OUTPUT {\-# OPTIONS_GHC \-Wno\-unused\-record\-wildcards #\-} {\-# LANGUAGE OverloadedStrings #\-} \-\- 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. import Control.Monad (when) import Data.ByteString (ByteString, index) data Answer = Color | Fish | Dunno deriving (Eq) data State = State { _yyinput :: ByteString, _yycursor :: Int, _yymarker :: Int } %{rules:colors * { error \(dqah\(dq } \(dqred\(dq | \(dqsalmon\(dq | \(dqmagenta\(dq { Color } %} %{rules:fish * { error \(dqoh\(dq } \(dqhaddock\(dq | \(dqsalmon\(dq | \(dqeel\(dq { Fish } %} %{ re2c:YYFN = [\(dqlexer;Answer\(dq, \(dqState{..};State\(dq]; re2c:yyfill:enable = 0; !use:fish; !use:colors; * { Dunno } // overrides inherited \(aq*\(aq rules %} main :: IO () main = do let test str ans = do let st = State {_yyinput = str, _yycursor = 0, _yymarker = 0} when (lexer st /= ans) $ error \(dqfailed\(dq test \(dqsalmon\(dq Fish test \(dqwhat?\(dq Dunno .ft P .fi .UNINDENT .UNINDENT.SS مثالی از یک بلوک \fB/*!use:re2c ... */\fP .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C \-\- re2hs $INPUT \-o $OUTPUT \-\-input\-encoding utf8 {\-# OPTIONS_GHC \-Wno\-unused\-record\-wildcards #\-} {\-# LANGUAGE OverloadedStrings #\-} \-\- 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. import Control.Monad (when) import Data.Array import Data.Word data State a = State { _yyinput :: a, _yycursor :: Int, _yymarker :: Int } %{rules re2c:yyfill:enable = 0; re2c:YYPEEK = \(dq(!)\(dq; \(dq∀x ∃y\(dq { Just _yycursor } * { Nothing } %} %{use re2c:YYFN = [\(dqlex8;Maybe Int\(dq, \(dqState{..};State (Array Int Word8)\(dq]; re2c:encoding:utf8 = 1; re2c:YYCTYPE = Word8; %} %{use re2c:YYFN = [\(dqlex32;Maybe Int\(dq, \(dqState{..};State (Array Int Word)\(dq]; re2c:encoding:utf32 = 1; re2c:YYCTYPE = Word; %} main :: IO () main = do let make_st l = State { _yyinput = listArray (0, length l \- 1) l, _yycursor = 0, _yymarker = 0} let s8 = [0xe2, 0x88, 0x80, 0x78, 0x20, 0xe2, 0x88, 0x83, 0x79] when (lex8 (make_st s8) /= Just (length s8)) $ error \(dqlex8 failed\(dq let s32 = [0x2200, 0x78, 0x20, 0x2203, 0x79] when (lex32 (make_st s32) /= Just (length s32)) $ error \(dqlex32 failed\(dq .ft P .fi .UNINDENT .UNINDENT .SS استخراج تطابق فرعی (Submatch extraction) .sp ابزار re2hs دو گزینه برای استخراج تطابق فرعی دارد. .INDENT 0.0 .TP .B \fBTags\fP گزینهٔ نخست استفاده از \fIبرچسب‌های (tags)\fP مستقل به فرم \fB@stag\fP یا \fB#mtag\fP است، که در آن \fBstag\fP و \fBmtag\fP نام‌های دلخواه تعریف‌شده توسط کاربر هستند. برچسب‌ها با گزینهٔ \fB\-T \-\-tags\fP یا پیکربندی \fBre2c:tags = 1\fP فعال می‌شوند. از نظر معنایی، برچسب‌ها نشانگرهای موقعیت هستند: می‌توان آن‌ها را در هر کجای یک عبارت منظم درج کرد و آن‌ها به موقعیت متناظر (یا چندین موقعیت) در رشتهٔ ورودی متصل می‌شوند. \fIS\-tagها\fP به آخرین موقعیت تطابق متصل می‌شوند و \fIm\-tagها\fP به فهرستی از موقعیت‌ها متصل می‌شوند (ممکن است در زیرعبارت‌های تکرار استفاده شوند، جایی که یک موقعیت واحد در یک عبارت منظم با چندین موقعیت در رشتهٔ ورودی مطابقت دارد). تمام برچسب‌ها باید توسط کاربر تعریف شوند، خواه به صورت دستی یا با کمک بلوک‌های \fBsvars\fP و \fBmvars\fP. اگر بیش از یک روش برای تطابق برچسب‌ها با ورودی وجود داشته باشد، ابهام با استفاده از راهبرد رفع ابهام حریصانهٔ چپ‌ترین (leftmost greedy) برطرف می‌شود. .TP .B \fBCaptures\fP گزینهٔ دوم استفاده از \fIگروه‌های گیرانداز (capturing groups)\fP است\&. آن‌ها با گزینهٔ \fB\-\-captures\fP یا پیکربندی \fBre2c:captures = 1\fP فعال می‌شوند. دو حالت برای سیاست‌های رفع ابهام مختلف وجود دارد؛ \fB\-\-leftmost\-captures\fP (پیش‌فرض) برای سیاست حریصانهٔ چپ‌ترین، و \fB\-\-posix\-captures\fP برای سیاست طولانی‌ترین تطابق POSIX است. در این حالت تمام زیرعبارت‌های داخل پرانتز به عنوان گروه‌های گیرانداز در نظر گرفته می‌شوند و از علامت تعجب می‌توان برای مشخص کردن گروه‌های غیرگیرانداز استفاده کرد: \fB(! ... )\fP\&. با گزینهٔ \fB\-\-invert\-captures\fP یا پیکربندی \fBre2c:invert\-captures = 1\fP معنای علامت تعجب معکوس می‌شود. تعداد گروه‌ها برای قاعدهٔ تطابق‌یافته در متغیر \fByynmatch\fP ذخیره می‌شود (کل عبارت منظم گروه شماره صفر است)، و نتایج تطابق فرعی در آرایهٔ \fByypmatch\fP ذخیره می‌شوند. هر دوی \fByynmatch\fP و \fByypmatch\fP باید توسط کاربر تعریف شوند، و اندازهٔ \fByypmatch\fP باید حداقل \fB[yynmatch * 2]\fP باشد\&. از بلوک \fBmaxnmatch\fP برای تعریف \fBYYMAXNMATCH\fP استفاده کنید؛ ثابتی که برابر با بیشینه مقدار \fByynmatch\fP در میان تمام قواعد است. .TP .B \fBCaptvars\fP روش دیگر برای استفاده از گروه‌های گیرانداز، گزینهٔ \fB\-\-captvars\fP یا پیکربندی \fBre2c:captvars = 1\fP است. تنها تفاوت آن با \fB\-\-captures\fP در شیوهٔ ذخیره‌سازی نتایج تطابق فرعی توسط کد تولیدشده است: به جای \fByynmatch\fP و \fByypmatch\fP، ابزار re2hs متغیرهای \fByytl\fP و \fByytr\fP را برای \fIk\fP\-اُمین گروه گیرانداز تولید می‌کند (کاربر باید این متغیرها را با استفاده از یک بلوک \fBsvars\fP اعلان کند). گیراندازی با متغیرها از دو سیاست رفع ابهام پشتیبانی می‌کند: \fB\-\-leftmost\-captvars\fP یا \fBre2c:leftmost\-captvars = 1\fP برای سیاست حریصانهٔ چپ‌ترین (پیش‌فرض) و \fB\-\-posix\-captvars\fP یا \fBre2c:posix\-captvars\fP برای سیاست طولانی‌ترین تطابق POSIX. .UNINDENT .sp در پشت صحنه، تمام این گزینه‌ها به برچسب‌ها و \fI\%اتوماتای متناهی معین برچسب‌دار با نگاه به جلو (Tagged Deterministic Finite Automata with Lookahead)\fP ترجمه می‌شوند\&. ایدهٔ اصلی TDFA به حداقل رساندن بار اضافی (overhead) بر روی استخراج تطابق فرعی است. در حالت نهایی، اگر هیچ برچسب یا گیراندازی در یک عبارت منظم وجود نداشته باشد، TDFA دقیقاً همانند یک DFA معمولی خواهد بود. اگر تعداد برچسب‌ها معتدل باشد، سربار به‌سختی قابل توجه است. اتوماتای TDFA تولیدشده از تعدادی \fIمتغیر برچسب (tag variables)\fP استفاده می‌کند که مستقیماً به برچسب‌ها نگاشت نمی‌شوند: یک متغیر واحد ممکن است برای برچسب‌های متفاوتی استفاده شود، و یک برچسب ممکن است برای نگهداری تمام مقادیر ممکن خود به چندین متغیر نیاز داشته باشد. سرانجام ابهام برطرف می‌شود و تنها یک متغیر نهایی به ازای هر برچسب باقی می‌ماند. متغیرهای برچسب باید با استفاده از بلوک‌های \fBstags\fP یا \fBmtags\fP تعریف شوند. اگر وضعیت تحلیل‌گر لغوی ذخیره شود، متغیرهای برچسب باید بخشی از آن باشند. آن‌ها همچنین باید توسط \fBYYFILL\fP به‌روزرسانی شوند\&. .sp برچسب‌های S\-tag از عملیات‌های زیر پشتیبانی می‌کنند: .INDENT 0.0 .IP \(bu 2 ذخیرهٔ موقعیت ورودی در یک s\-tag: به صورت \fBt = YYCURSOR\fP با API اشاره‌گر C یا یک عملیات تعریف‌شده توسط کاربر \fBYYSTAGP(t)\fP با API عمومی (generic) .IP \(bu 2 ذخیرهٔ مقدار پیش‌فرض در یک s\-tag: به صورت \fBt = NULL\fP با API اشاره‌گر C یا یک عملیات تعریف‌شده توسط کاربر \fBYYSTAGN(t)\fP با API عمومی .IP \(bu 2 رونوشت از یک s\-tag به دیگری: \fBt1 = t2\fP .UNINDENT .sp برچسب‌های M\-tag از عملیات‌های زیر پشتیبانی می‌کنند: .INDENT 0.0 .IP \(bu 2 الحاق موقعیت ورودی به یک m\-tag: عملیات تعریف‌شده توسط کاربر \fBYYMTAGP(t)\fP با هر دو API پیش‌فرض و عمومی .IP \(bu 2 الحاق مقدار پیش‌فرض به یک m\-tag: عملیات تعریف‌شده توسط کاربر \fBYYMTAGN(t)\fP با هر دو API پیش‌فرض و عمومی .IP \(bu 2 رونوشت از یک m\-tag به دیگری: \fBt1 = t2\fP .UNINDENT .sp برچسب‌های S\-tag را می‌توان به عنوان مقادیر اسکالر (اشاره‌گرها یا آفست‌ها) پیاده‌سازی کرد. برچسب‌های M\-tag به نمایش پیچیده‌تری نیاز دارند، چرا که باید توالی‌ای از مقادیر برچسب را ذخیره کنند. ساده‌ترین و ناکارآمدترین نمایش از یک m\-tag، یک لیست (آرایه، بردار) از مقادیر برچسب است؛ نمایشی کارآمدتر، ذخیرهٔ تمام m\-tagها در یک درخت پیشوندی (prefix\-tree) است که به صورت آرایه‌ای از گره‌های \fB(v, p)\fP نمایش داده می‌شود، که در آن \fBv\fP مقدار برچسب و \fBp\fP اشاره‌گری به گره والد است. .sp در اینجا مثال ساده‌ای از استفاده از s\-tagها برای تجزیهٔ نسخه‌بندی معنایی متشکل از سه جزء عددی آمده است: major، minor، patch (مورد آخر اختیاری است). برای یک مثال پیچیده‌تر که از \fBYYFILL\fP استفاده می‌کند، بخش‌های زیر را ببینید\&. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C \-\- re2hs $INPUT \-o $OUTPUT {\-# OPTIONS_GHC \-Wno\-unused\-record\-wildcards #\-} {\-# LANGUAGE OverloadedStrings #\-} import Control.Monad (when) import Data.ByteString (ByteString, index) data State = State { \-\- Final tag bindings available in semantic action. %{svars format = \(dq\en@@ :: !Int,\(dq; %} \-\- Intermediate tag bindings used by the lexer (must be autogenerated). %{stags format = \(dq\en@@ :: !Int,\(dq; %} _yyinput :: !ByteString, _yycursor :: !Int, _yymarker :: !Int } data SemVer = SemVer { major :: !Int, minor :: !Int, patch :: !Int } deriving (Eq) s2n :: ByteString \-> Int \-> Int \-> Int s2n s i j = f i 0 where f k n = if k >= j then n else f (k + 1) (n * 10 + (fromIntegral (index s k) \- 48)) %{ re2c:YYFN = [\(dqparse;Maybe SemVer\(dq, \(dqState{..};State\(dq]; re2c:tags = 1; re2c:yyfill:enable = 0; num = [0\-9]+; @_1 num @_2 \(dq.\(dq @_3 num @_4 (\(dq.\(dq @_5 num)? [\ex00] { Just SemVer { major = s2n _yyinput _1 _2, minor = s2n _yyinput _3 _4, patch = if _5 == (\-1) then 0 else s2n _yyinput _5 (_yycursor \- 1) } } * { Nothing } %} test :: ByteString \-> Maybe SemVer \-> IO () test str expect = do let s = State { %{svars format = \(dq\en@@ = (\-1),\(dq; %} %{stags format = \(dq\en@@ = (\-1),\(dq; %} _yyinput = str, _yycursor = 0, _yymarker = 0 } when (parse s /= expect) $ error \(dqfailed!\(dq main :: IO () main = do test \(dq23.34\e0\(dq (Just SemVer {major = 23, minor = 34, patch = 0}) test \(dq1.2.99999\e0\(dq (Just SemVer {major = 1, minor = 2, patch = 99999}) test \(dq1.a\e0\(dq Nothing .ft P .fi .UNINDENT .UNINDENT.sp در اینجا مثال پیچیده‌تری از به‌کارگیری s\-tagها با \fBYYFILL\fP برای تجزیهٔ یک فایل با نسخه‌بندی‌های معنایی جداشده با خط جدید آمده است. متغیرهای برچسب بخشی از وضعیت تحلیل‌گر لغوی (lexer) هستند و مانند دیگر موقعیت‌های ورودی در \fBYYFILL\fP تنظیم می‌شوند. توجه داشته باشید که این کار برای s\-tagها ضروری است، چرا که مقادیر آن‌ها پس از جابه‌جایی محتویات بافر، نامعتبر می‌شوند. این موضوع ممکن است در یک پیاده‌سازی سفارشی که در آن متغیرهای برچسب به جای بافر، آفست‌ها را نسبت به ابتدای رشتهٔ ورودی ذخیره می‌کنند (که می‌تواند در مورد m\-tagها این‌گونه باشد)، ضروری نباشد. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C \-\- re2hs $INPUT \-o $OUTPUT {\-# OPTIONS_GHC \-Wno\-unused\-record\-wildcards #\-} {\-# LANGUAGE OverloadedStrings #\-} import Control.Monad import Data.ByteString as BS import GHC.IO.Handle import System.Directory import System.IO chunk_size :: Int chunk_size = 4096 data State = State { _file :: !Handle, _yyinput :: !BS.ByteString, _yycursor :: !Int, _yymarker :: !Int, _yylimit :: !Int, _token :: !Int, \-\- Final tag bindings available in semantic action. %{svars format = \(dq\en@@ :: !Int,\(dq; %} \-\- Intermediate tag bindings used by the lexer (must be autogenerated). %{stags format = \(dq\en@@ :: !Int,\(dq; %} _eof :: !Bool } data SemVer = SemVer { major :: !Int, minor :: !Int, patch :: !Int } deriving (Eq, Show) s2n :: BS.ByteString \-> Int \-> Int \-> Int s2n s i j = f i 0 where f k n = if k >= j then n else f (k + 1) (n * 10 + (fromIntegral (BS.index s k) \- 48)) %{ re2c:YYFN = [\(dqlexer;IO [SemVer]\(dq, \(dqState{..};State\(dq, \(dq_vers;[SemVer]\(dq]; re2c:YYPEEK = \(dqBS.index\(dq; re2c:YYFILL = \(dq(State{..}, yyfill) <\- fill State{..}\(dq; re2c:eof = 0; re2c:monadic = 1; re2c:tags = 1; num = [0\-9]+; @_1 num @_2 \(dq.\(dq @_3 num @_4 (\(dq.\(dq @_5 num)? [\en] { let ver = SemVer { major = s2n _yyinput _1 _2, minor = s2n _yyinput _3 _4, patch = if _5 == (\-1) then 0 else s2n _yyinput _5 (_yycursor \- 1) } lexer State{..} (ver: _vers) } $ { return _vers } * { error \(dqlexer failed\(dq } %} fill :: State \-> IO (State, Bool) fill State{..} = do case _eof of True \-> return (State{..}, False) False \-> do \-\- Discard everything up to the current token, cut off terminating null, \-\- read new chunk from file and reappend terminating null at the end. chunk <\- BS.hGet _file chunk_size return (State{ _yyinput = BS.concat [(BS.init . BS.drop _token) _yyinput, chunk, \(dq\e0\(dq], _yycursor = _yycursor \- _token, _yymarker = _yymarker \- _token, _yylimit = _yylimit \- _token + BS.length chunk, \-\- exclude terminating null _token = 0, _eof = BS.null chunk, \-\- end of file? ..}, True) main :: IO () main = do let fname = \(dqinput\(dq \-\- Prepare input file. BS.writeFile fname $ BS.concat [\(dq1.22.333\en\(dq | _ <\- [1..chunk_size]] let expect = [SemVer {major = 1, minor = 22, patch = 333} | _ <\- [1..chunk_size]] \-\- Run lexer on the prepared file. fh <\- openFile fname ReadMode let st = State { _file = fh, _yyinput = BS.singleton 0, _yycursor = 0, _yymarker = 0, _yylimit = 0, _token = 0, %{svars format = \(dq\en@@ = (\-1),\(dq; %} %{stags format = \(dq\en@@ = (\-1),\(dq; %} _eof = False } result <\- lexer st [] hClose fh \-\- Cleanup. removeFile fname \-\- Check result. when (result /= expect) $ error $ \(dqexpected \(dq ++ show expect ++ \(dq, got \(dq ++ show result return () .ft P .fi .UNINDENT .UNINDENT .sp در اینجا مثالی از به‌کارگیری گروه‌های گیرنده (capturing groups) برای تجزیهٔ نسخه‌بندی معنایی آورده شده است. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C \-\- re2hs $INPUT \-o $OUTPUT {\-# OPTIONS_GHC \-Wno\-unused\-record\-wildcards #\-} {\-# LANGUAGE OverloadedStrings #\-} import Control.Monad (when) import Data.ByteString (ByteString, index) import Data.Word (Word8) none :: Int none = \-1 data State = State { \-\- Final tag bindings available in semantic action. %{svars format = \(dq\en@@ :: !Int,\(dq; %} \-\- Intermediate tag bindings used by the lexer (must be autogenerated). %{stags format = \(dq\en@@ :: !Int,\(dq; %} _yyinput :: !ByteString, _yycursor :: !Int, _yymarker :: !Int } data SemVer = SemVer { major :: !Int, minor :: !Int, patch :: !Int } deriving (Eq) s2n :: ByteString \-> Int \-> Int \-> Int s2n s i j = f i 0 where f k n = if k >= j then n else f (k + 1) (n * 10 + (fromIntegral (index s k) \- 48)) %{ re2c:YYFN = [\(dqparse;Maybe SemVer\(dq, \(dqState{..};State\(dq]; re2c:YYCTYPE = \(dqWord8\(dq; re2c:captvars = 1; re2c:yypmatch = _; re2c:yyfill:enable = 0; num = [0\-9]+; (num) \(dq.\(dq (num) (\(dq.\(dq num)? [\ex00] { Just SemVer { major = s2n _yyinput _yytl1 _yytr1, minor = s2n _yyinput _yytl2 _yytr2, patch = if _yytl3 == none then 0 else s2n _yyinput (_yytl3 + 1) _yytr3 } } * { Nothing } %} test :: ByteString \-> Maybe SemVer \-> IO () test str expect = do let s = State { %{svars format = \(dq\en@@ = none,\(dq; %} %{stags format = \(dq\en@@ = none,\(dq; %} _yyinput = str, _yycursor = 0, _yymarker = 0 } when (parse s /= expect) $ error \(dqfailed!\(dq main :: IO () main = do test \(dq23.34\e0\(dq (Just SemVer {major = 23, minor = 34, patch = 0}) test \(dq1.2.99999\e0\(dq (Just SemVer {major = 1, minor = 2, patch = 99999}) test \(dq1.a\e0\(dq Nothing .ft P .fi .UNINDENT .UNINDENT.sp در اینجا مثالی از استفاده از m\-tagها برای تجزیهٔ یک نسخه با تعداد متغیری از مؤلفه‌ها آورده شده است. متغیرهای برچسب در یک درخت پیشوندی (trie) ذخیره می‌شوند. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C \-\- re2hs $INPUT \-o $OUTPUT {\-# OPTIONS_GHC \-Wno\-unused\-record\-wildcards #\-} {\-# LANGUAGE OverloadedStrings #\-} import Control.Monad (when) import Data.ByteString (ByteString, index) data State = State { \-\- Final tag bindings available in semantic action. %{svars format = \(dq\en@@ :: !Int,\(dq; %} %{mvars format = \(dq\en@@ :: ![Int],\(dq; %} \-\- Intermediate tag bindings used by the lexer (must be autogenerated). %{stags format = \(dq\en@@ :: !Int,\(dq; %} %{mtags format = \(dq\en@@ :: ![Int],\(dq; %} _yyinput :: !ByteString, _yycursor :: !Int, _yymarker :: !Int } s2n :: ByteString \-> Int \-> Int \-> Int s2n s i j = f i 0 where f k n = if k >= j then n else f (k + 1) (n * 10 + (fromIntegral (index s k) \- 48)) %{ re2c:YYFN = [\(dqparse;Maybe [Int]\(dq, \(dqState{..};State\(dq]; re2c:YYMTAGP = \(dqlet tag = _yycursor : @@{tag} in let @@{tag} = tag in\(dq; re2c:YYMTAGN = \(dq\(dq; // alternatively could add \-1 to the list re2c:tags = 1; re2c:yyfill:enable = 0; num = [0\-9]+; @_1 num @_2 (\(dq.\(dq #_3 num #_4)* [\ex00] { Just $ (s2n _yyinput _1 _2) : (reverse $ zipWith (\ei j \-> s2n _yyinput i j) _3 _4) } * { Nothing } %} test :: ByteString \-> Maybe [Int] \-> IO () test str expect = do let st = State { %{svars format = \(dq\en@@ = (\-1),\(dq; %} %{stags format = \(dq\en@@ = (\-1),\(dq; %} %{mvars format = \(dq\en@@ = [],\(dq; %} %{mtags format = \(dq\en@@ = [],\(dq; %} _yyinput = str, _yycursor = 0, _yymarker = 0 } when (parse st /= expect) $ error \(dqfailed!\(dq main :: IO () main = do test \(dq1\e0\(dq (Just [1]) test \(dq1.2.3.4.5.6.7\e0\(dq (Just [1, 2, 3, 4, 5, 6, 7]) test \(dq1.2.\e0\(dq Nothing .ft P .fi .UNINDENT .UNINDENT .SS "پشتیبانی از کدگذاری (Encoding support)" .sp درک تفاوت بین \fBcode points\fP (نقطه‌کدها) و \fBcode units\fP (واحدهای کد) ضروری است\&. یک نقطه‌کد، یک شناسهٔ عددی برای یک نماد است. یک واحد کد، کوچک‌ترین واحد ذخیره‌سازی در متن کدگذاری‌شده است. یک نقطه‌کد منفرد ممکن است با یک یا چند واحد کد نمایش داده شود. در یک کدگذاری با طول ثابت، همهٔ نقطه‌کدها با تعداد یکسانی از واحدهای کد نمایش می‌یابند. در یک کدگذاری با طول متغیر، نقطه‌کدها ممکن است با تعداد متفاوتی از واحدهای کد نمایش داده شوند. توجه داشته باشید که قاعدهٔ \(dqany\(dq یعنی \fB[^]\fP با هر نقطه‌کدی مطابقت دارد، اما لزوماً با هر واحد کد مطابقت ندارد (تنها روش برای تطبیق با هر واحد کد فارغ از نوع کدگذاری، قاعدهٔ پیش‌فرض \fB*\fP است). تحلیل‌گر لغوی تولیدشده با جریانی از واحدهای کد کار می‌کند: \fByych\fP یک واحد کد را ذخیره می‌کند و \fBYYCTYPE\fP نوع واحد کد است. از سوی دیگر، عبارت‌های منظم برحسب نقطه‌کدها مشخص می‌شوند. هنگامی که re2hs عبارت‌های منظم را به اتوماتا کامپایل می‌کند، نقطه‌کدها را به واحدهای کد ترجمه می‌نماید. این تبدیل عموماً یک نگاشت ساده نیست: در کدگذاری‌های با طول متغیر، یک محدودهٔ نقطه‌کد منفرد ممکن است به یک گراف پیچیده از واحدهای کد ترجمه شود. کدگذاری‌های زیر پشتیبانی می‌شوند: .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 تعاریف re2hs را برای بلوک‌ها، دسته‌ها و ویژگی‌های توصیف‌شده در استاندارد یونیکد فراهم می‌کنند. .sp گزینهٔ \fB\-\-input\-encoding\fP کدگذاری فایل مبدأ را مشخص می‌کند که می‌تواند برای فعال‌سازی لیترال‌های یونیکد در عبارت‌های منظم استفاده شود. برای مثال، \fB\-\-input\-encoding utf8\fP به re2hs اعلام می‌کند که فایل مبدأ با UTF8 کدگذاری شده است (این گزینه با \fB\-\-utf8\fP که کدگذاری متن ورودی را تعیین می‌کند، متفاوت است). گزینهٔ \fB\-\-encoding\-policy\fP نحوهٔ رفتار re2hs با جانشین‌های یونیکد (Unicode surrogates، نقطه‌کدها در محدودهٔ \fB[0xD800\-0xDFFF]\fP) را تعیین می‌کند. .sp در ادامه مثالی از یک تحلیل‌گر لغوی برای شناسه‌های یونیکد با کدگذاری UTF8 آورده شده است. .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C \-\- re2hs $INPUT \-o $OUTPUT \-\-utf8 \-i {\-# OPTIONS_GHC \-Wno\-unused\-record\-wildcards #\-} {\-# LANGUAGE OverloadedStrings #\-} import Control.Monad (when) import Data.ByteString (ByteString, index) %{include \(dqunicode_categories.re\(dq %} data State = State { _yyinput :: ByteString, _yycursor :: Int, _yymarker :: Int, _yyaccept :: Int } %{ re2c:YYFN = [\(dqlexer;Bool\(dq, \(dqState{..};State\(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 id_continue*; identifier { True } * { False } %} main :: IO () main = do let st = State { _yyinput = \(dq_Ыдентификатор\ex00\(dq, _yycursor = 0, _yymarker = 0, _yyaccept = 0} when (not $ lexer st) $ error \(dqfailed\(dq .ft P .fi .UNINDENT .UNINDENT.SS فایل‌های ضمیمه (Include files) .sp ابزار re2hs امکان ضمیمه کردن فایل‌های دیگر را با استفاده از بلوکی به قالب \fB/*!include:re2c FILE */\fP یا \fB%{include FILE %}\fP، یا دستور درون‌بلوکیِ \fB!include FILE ;\fP فراهم می‌کند، که در آن \fBFILE\fP مسیر فایل مورد نظر برای ضمیمه شدن است. re2hs فایل‌های include را در دایرکتوریِ فایل فراخواننده و در مسیرهای include که با گزینهٔ \fB\-I\fP مشخص می‌شوند، جستجو می‌کند. بلوک‌ها/دستورهای include در re2hs همانند \fB#include\fP در C/C++ عمل می‌کنند: محتوای \fBFILE\fP عیناً در محل بلوک/دستور جای‌گذاری می‌شود. فایل‌های include می‌توانند خود حاوی includeهای دیگری باشند. از گزینهٔ \fB\-\-depfile\fP برای ردیابی وابستگی‌های ساختِ فایل خروجی به فایل‌های include استفاده کنید. ابزار re2hs تعدادی فایل include از پیش تعریف‌شده ارائه می‌دهد که در زیردایرکتوری \fBinclude/\fP پروژه یافت می‌شوند. این فایل‌ها حاوی تعاریفی هستند که ممکن است برای پروژه‌های دیگر نیز مفید باشند (مانند دسته‌بندی‌های Unicode) و چیزی شبیه به یک کتابخانهٔ استاندارد برای re2hs تشکیل می‌دهند\&. در ادامه مثالی از نحوهٔ استفاده از فایل‌های include آورده شده است. .SS فایل ضمیمه ۱ (definitions.hs) .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C data Number = INum | FNum | NNaN deriving (Eq) %{ 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 { FNum } .ft P .fi .UNINDENT .UNINDENT .SS فایل ورودی (Input file) .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C \-\- re2hs $INPUT \-o $OUTPUT \-i {\-# OPTIONS_GHC \-Wno\-unused\-record\-wildcards #\-} {\-# LANGUAGE OverloadedStrings #\-} import Control.Monad (when) import Data.ByteString (ByteString, index) %{include \(dqdefinitions.hs\(dq %} data State = State { _yyinput :: ByteString, _yycursor :: Int, _yymarker :: Int, _yyaccept :: Int } %{ re2c:YYFN = [\(dqlexer;Number\(dq, \(dqState{..};State\(dq]; re2c:yyfill:enable = 0; * { NNaN } number { INum } !include \(dqextra_rules.re.inc\(dq; %} main :: IO () main = do let test s n = do let st = State { _yyinput = s, _yycursor = 0, _yymarker = 0, _yyaccept = 0} when (lexer st /= n) $ error \(dqfailed\(dq test \(dq123\e0\(dq INum test \(dq123.4567\e0\(dq FNum .ft P .fi .UNINDENT .UNINDENT.SS "فایل‌های سرآیند (Header files)" .sp ابزار re2hs امکان تولید فایل سرآیند از فایل ورودی \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 فراهم می‌کند\&. بلوک نخست آغاز فایل سرآیند و بلوک دوم پایان آن را مشخص می‌کند. تمام موارد میان این بلوک‌ها توسط re2hs پردازش شده و کد تولیدشده در فایلی که با گزینهٔ \fB\-\-header\fP یا پیکربندی \fBre2c:header\fP مشخص شده (یا در \fBstdout\fP اگر هیچ‌کدام مشخص نشده باشند) نوشته می‌شود. تولید خودکار فایل سرآیند ممکن است در مواردی نیاز باشد که از re2hs برای تولید تعاریفی استفاده می‌شود که باید از سایر واحدهای ترجمه (translation units) قابل دسترسی و مشاهده باشند. .sp در ادامه مثالی از تولید یک فایل سرآیند آورده شده است که شامل تعریف وضعیت تحلیل‌گر لغوی (lexer state) همراه با متغیرهای برچسب است (تعداد متغیرها به گرامر منظم بستگی دارد و برای برنامه‌نویس نامشخص است). .SS "فایل ورودی (Input file)" .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C \-\- re2hs $INPUT \-o $OUTPUT \-\-header lexer/state.hs \-i {\-# OPTIONS_GHC \-Wno\-unused\-record\-wildcards #\-} {\-# LANGUAGE OverloadedStrings #\-} import Control.Monad (when) import Data.ByteString (index) import State %{header:on %} module State where import Data.ByteString (ByteString) data State = State { _yyinput :: !ByteString, _yycursor :: !Int, %{stags format = \(dq\en@@{tag} :: !Int,\(dq; %} _tag :: !Int } %{header:off %} %{ re2c:YYFN = [\(dqlexer;Int\(dq, \(dqState{..};State\(dq]; re2c:tags = 1; re2c:yyfill:enable = 0; re2c:header = \(dqlexer/state.hs\(dq; [a]* @_tag [b]* { _tag } %} main :: IO () main = do let s = State { _yyinput = \(dqab\e0\(dq, _yycursor = 0, %{stags format = \(dq\en@@{tag} = \-1,\(dq; %} _tag = 0} when (lexer s /= 1) $ error \(dqfailed!\(dq .ft P .fi .UNINDENT .UNINDENT .SS "فایل سرآیند (Header file)" .INDENT 0.0 .INDENT 3.5 .sp .nf .ft C \-\- Generated by re2c {\-# LANGUAGE RecordWildCards #\-} module State where import Data.ByteString (ByteString) data State = State { _yyinput :: !ByteString, _yycursor :: !Int, _yyt1 :: !Int, _tag :: !Int } .ft P .fi .UNINDENT .UNINDENT.SS "برنامه‌های اسکلتی (Skeleton programs)" .sp با گزینهٔ \fB\-S, \-\-skeleton\fP، دستور re2hs تمام کدهای غیر re2hs را نادیده می‌گیرد و یک برنامهٔ C مستقل تولید می‌کند که می‌تواند در ادامه کامپایل و اجرا شود. این برنامه از کد تحلیل‌گر لغوی و داده‌های ورودی تشکیل شده است. برای هر DFA ساخته‌شده (بلوک یا شرط)، re2hs یک تحلیل‌گر لغوی مستقل و دو فایل تولید می‌کند: یک فایل \fB\&.input\fP با رشته‌های مشتق‌شده از DFA، و یک فایل \fB\&.keys\fP با نتایج تطابق مورد انتظار. برنامه هر تحلیل‌گر لغوی را روی فایل \fB\&.input\fP متناظر اجرا کرده و نتایج را با موارد مورد انتظار مقایسه می‌کند. برنامه‌های اسکلتی به دلایل متعددی بسیار مفید هستند: .INDENT 0.0 .IP \(bu 2 آن‌ها می‌توانند صحت بهینه‌سازی‌های مختلف re2hs را بررسی کنند (داده‌ها در مراحل اولیهٔ فرایند، پیش از اعمال هرگونه تبدیل روی DFA، تولید می‌شوند). .IP \(bu 2 تولید مجموعه‌ای از داده‌های ورودی با پوشش مناسب می‌تواند هم برای آزمودن و هم برای محک‌زدن (benchmarking) مفید باشد. .IP \(bu 2 تولید برنامه‌های اجرایی مستقل امکان دسترسی به موارد آزمون کمینه‌شده را فراهم می‌کند (کد اصلی ممکن است بزرگ باشد یا وابستگی‌های فراوانی داشته باشد). .UNINDENT .sp دشواری تولید داده‌های ورودی در این است که به جز در ساده‌ترین موارد، تعداد رشته‌های ورودی ممکن بیش از حد زیاد است (حتی اگر طول رشته محدود باشد). re2hs این مشکل را با تولید رشته‌های کافی جهت پوشش تقریباً تمام انتقال‌های DFA برطرف می‌کند. این ابزار از الگوریتم زیر استفاده می‌کند: ابتدا اسکلتی از DFA را می‌سازد. برای کدگذاری‌هایی با اندازهٔ واحد کد ۱ بایتی (مانند ASCII، UTF\-8 و EBCDIC)، اسکلت صرفاً یک رونوشت دقیق از DFA اصلی است. برای کدگذاری‌هایی با واحدهای کد چندبایتی، اسکلت رونوشتی از DFA با حذف برخی از انتقال‌ها است: به طور مشخص، re2hs برای هر بازهٔ پیوسته و مجزا که متناظر با یک انتقال DFA باشد، حداکثر ۲۵۶ واحد کد در نظر می‌گیرد. مقادیر انتخاب‌شده به طور یکنواخت توزیع می‌شوند و شامل کران‌های بازه نیز هستند. re2hs به جای تلاش برای پوشش تمام مسیرهای ممکن در اسکلت (که کاری نشدنی است)، مسیرهای کافی برای پوشش تمامی انتقال‌های اسکلت تولید می‌کند و از این رو پرش‌های شرطی متناظر را در تحلیل‌گر لغوی فعال می‌سازد. پیاده‌سازی این الگوریتم به حدود ~1Gb از انتقال‌ها محدود شده و میزان ثابتی از حافظه را مصرف می‌کند (re2hs داده‌ها را بلافاصله پس از تولید در فایل می‌نویسد). .SS "تجسم و اشکال‌زدایی (Visualization and debug)" .sp با گزینهٔ \fB\-D, \-\-emit\-dot\fP، دستور re2hs کدی تولید نمی‌کند. در عوض، DFA تولیدشده را در قالب DOT ذخیره می‌کند. می‌توان این خروجی را با استفاده از Graphviz یا کتابخانه‌ای دیگر به تصویری از DFA تبدیل کرد. توجه داشته باشید که این گزینه، DFA نهایی را پس از گذر از چندین مرحله بهینه‌سازی و تبدیل نشان می‌دهد. مراحل اولیه را می‌توان با گزینه‌های گوناگون اشکال‌زدایی مانند \fB\-\-dump\-nfa\fP، \fB\-\-dump\-dfa\-raw\fP و غیره استخراج کرد (فهرست کامل گزینه‌ها را ببینید). .SH "همچنین ببینید (SEE ALSO)" .sp می‌توانید اطلاعات بیشتری دربارهٔ re2c در وبگاه رسمی بیابید: \fI\%http://re2c.org\fP\&. برنامه‌های مشابه عبارتند از flex(1)، lex(1)، quex(\fI\%http://quex.sourceforge.net\fP). .SH "نویسندگان (AUTHORS)" .sp برنامهٔ re2hs در ابتدا توسط 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. .