فرم باکوس نائور توسعه یافته

از ویکی‌پدیا، دانشنامهٔ آزاد

فرم باکوس نائور توسعه یافته (به انگلیسی: Extended Backus–Naur form)یا EBNF در علوم رایانه ای، یک خانواده از نمادهای متاسینتاکس است که هر کدام از آن‌ها می‌توانند برای بیان یک دستور زبان مستقل از متن استفاده شود. EBNF برای توصیف زبان صوری استفاده می‌شود که می‌تواند یک زبان برنامه‌نویسی کامپیوتری هم باشد. این‌ها شامل فرمت‌های بنتاکس (BNF) است. ابتدا EBNF توسط نیکلاوس ویرت توسعه داده شد و برخی از مفاهیم را به صورت نحوی به کار برد. با این حال بسیاری از انواع EBNF در استانداردسازی یک استاندارد) (ISO/IEC 14977 را برای EBNF مورد تصویب قرار داده‌است. این مقاله از EBNF که توسط استاندارد مشخص شده‌است را برای تمام مثال‌های EBNFها استفاده می‌کند. دیگر انواع EBNF از قوانین نحوی متفاوت استفاده می‌کنند).

مبانی[ویرایش]

EBNF یک کد است که دستور زبان رسمی را بیان می‌کند. یک EBNF شامل علائم ترمینال و قوانین تولید نامحدود است که محدودیت‌هایی را در مورد این که چگونه نمادهای ترمینال را می‌توان به یک ترتیب قانونی ترکیب کرد ارائه می‌کند. مثال‌هایی از نمادهای ترمینال عبارت اند از حروف الفبا، علائم نگارشی و نشانه‌های سجاوندی. EBNF قوانین تولید را تعریف می‌کند که در آن دنباله‌های نمادها به ترتیب به صورت غیرانتصابی اختصاص داده می‌شوند.

digit excluding zero = "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
digit                = "0" | digit excluding zero ;

این قوانین تولید به صورت عددی غیرمنتظره ای است که در سمت چپ قرار داشته و آن‌ها را تعریف می‌کند. نمودار عمودی امکان جایگزینی را نشان می‌دهد و نمادهای ترمینال علامت نقل قول همراه یا یک نقطه متوقف می‌شود. از این رو یک رقم بوده و می‌تواند ۱ یا ۲ یا ۳ … ۹ باشد. یک قانون تولیدی همچنین می‌تواند دنباله ای از پایانه‌ها یا غیر ترمینال‌ها می‌باشد که هر کدام با یک کاما جدا شده‌اند.

twelve                          = "1", "2" ;
two hundred one                 = "2", "0", "1" ;
three hundred twelve            = "3", twelve ;
twelve thousand two hundred one = twelve, two hundred one ;

ساختارهایی که می‌توانند حذف یا تکرار شوند درون آکولاد نشان داده می‌شوند.

natural number = digit excluding zero, { digit } ;
در این مورد، رشته‌های 1, 2,  , 10, 12345,   عبارت‌های صحیح هستند. برای نشان دادن این مورد، همه موارد را در داخل پارانتزهای مجاور قرار می‌گیرند. ممکن است اغلب به صورت خودسرانه تکرار شوند. از جمله این که در همه موارد وجود ندارد یک گزینه را می‌توان از طریق براکت مربعی نشان داد و این بدان معنی است که هر چیزی که درون مربع قرار دارد ممکن است فقط یک بار و نه در همه جا باشد.
integer = "0" | ["-"], natural number ;

بنابراین یک عدد صحیح صفر یا یک عدد طبیعی بیش از یک عدد اختیاری باشد. EBNF همچنین در میان موارد دیگر به نحوی برای توصیف تکرار ما اقدام می‌کند تا برخی از بخش‌های تولید را حذف کرده و نظرات را در دستور زیاد EBNF قرار دهد.

جدول نمادها[ویرایش]

در زیر استاندار ISO/IEC 14977 پیشنهاد شده توسط آر. اس اسکون است در صفحه ۷ و در جدول ۱ نشان داده شده‌است.

مورد استفاده علامت
تعریف =
تلفیق ,
خاتمه ;
تناوب |
اختیاری [...]
تکراری { …}
گروه‌بندی (...)
رشته ترمینابی " … "
رشته ترمینالی ' … '
کامنت (* … *)
دنباله خاص ? … ?
استثنا -

مثال[ویرایش]

حتی EBNF را می‌توان با استفاده از خود EBNF توصیف نمود. دستورالعمل زیر را در نظر بگیرید :

letter = "A" | "B" | "C" | "D" | "E" | "F" | "G"
       | "H" | "I" | "J" | "K" | "L" | "M" | "N"
       | "O" | "P" | "Q" | "R" | "S" | "T" | "U"
       | "V" | "W" | "X" | "Y" | "Z" | "a" | "b"
       | "c" | "d" | "e" | "f" | "g" | "h" | "i"
       | "j" | "k" | "l" | "m" | "n" | "o" | "p"
       | "q" | "r" | "s" | "t" | "u" | "v" | "w"
       | "x" | "y" | "z" ;
digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
symbol = "[" | "]" | "{" | "}" | "(" | ")" | "<" | ">"
       | "'" | '"' | "=" | "|" | "." | "," | ";" ;
character = letter | digit | symbol | "_" ;

identifier = letter , { letter | digit | "_" } ;
terminal = "'" , character , { character } , "'"
         | '"' , character , { character } , '"' ;

lhs = identifier ;
rhs = identifier
     | terminal
     | "[" , rhs , "]"
     | "{" , rhs , "}"
     | "(" , rhs , ")"
     | rhs , "|" , rhs
     | rhs , "," , rhs ;

rule = lhs , "=" , rhs , ";" ;
grammar = { rule } ;

یک زبان برنامه‌نویسی مانند پاسکال تعاریف را می‌تواند در EBNF به شرح زیر تعریف کند.

 (* a simple program syntax in EBNF − Wikipedia *)
 program = 'PROGRAM', white space, identifier, white space,
            'BEGIN', white space,
            { assignment, ";", white space },
            'END.' ;
 identifier = alphabetic character, { alphabetic character | digit } ;
 number = ["-"], digit, { digit } ;
 string = '"' , { all characters - '"' }, '"' ;
 assignment = identifier , ":=" , ( number | identifier | string ) ;
 alphabetic character = "A" | "B" | "C" | "D" | "E" | "F" | "G"
                      | "H" | "I" | "J" | "K" | "L" | "M" | "N"
                      | "O" | "P" | "Q" | "R" | "S" | "T" | "U"
                      | "V" | "W" | "X" | "Y" | "Z" ;
 digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
 white space = ? white space characters ? ;
 all characters = ? all visible characters ? ;

زبان به راحتی می‌تواند با جریان‌های کنترل، عبارات ریاضی و دستورالعمل‌های ورودی و خروجی گسترش یابد و سپس یک زبان برنامه‌نویسی کوچک قابل استفاده است.

مزایای BNF[ویرایش]

هر دستور زبان EBNF نیز می‌تواند در BNF نمایش داده شود. اگر چه نمایه‌های آن دارای عمر طولانی تری می‌باشند. به عنوان مثال گزینه‌ها و تکرارها نمی‌تواند به‌طور مستقیم در BNF بیان شود و نیازمند استفاده از یک قانون متوسط یا تولید جایگزین است که تعریف شده یا چیزی را به‌طور اختیاری و تکراری تولید کرده‌است. همان سازنده‌ها هنوز هم می‌توانند در EBNF استفاده شوند. BNF از نماد (<,>, |, ::=) برای خود استفاده می‌کند، اما نقل قول‌ها در اطراف رشته‌های ترمینال را شامل نمی‌شود. این مانع از این کاراکترها در زبان می‌شود و نیاز به یک نماد ویژه برای رشته خاصی دارد. EBNF پایانه‌ها به وضوح در داخل علامت “ “ یا ' ' محصور می‌شوند. براکت زاویه را برای غیرترمینال‌ها می‌توان حذف نمود. همچنین BNF تنها می‌تواند یک قاعده را در یک خط نشان دهد. در حالی که در EBNF دستورهای متناوب وجود داشته‌است. علاوه بر این، EBNF شامل مکانیزیم‌هایی برای پیشرفت بوده که تعریف تعدادی از تکرارها به استثنای جایگزین‌های کامنت و غیره را دارد.

معاهده عا[ویرایش]

معاهده‌های زیر استفاده می‌شوند.
۱- هر شناسه فرعی BNF به عنوان یک یا چند عبارت با هم ترکیب شده‌اند.
۲- یک فراشناسایی که با استفاده از علایم پایان می‌یابد. براساس نام نماد ترمینال BNF تمدید شده‌است. کاراکترهای نمادی که هر اپراتور BNF از آن تمدید شده و اولویت ضمنی آن را نشان می‌دهند.

  • repetition-symbol
- except-symbol
, concatenate-symbol
| definition-separator-symbol

= defining-symbol

; terminator-symbol

. terminator-symbol اولویت عادی توسط جفت‌های براکت زیر لغو می‌شود. ' first-quote-symbol first-quote-symbol '

" second-quote-symbol second-quote-symbol "
(* start-comment-symbol end-comment-symbol *)
(start-group-symbol end-group-symbol)
[start-option-symbol            end-option-symbol]
{ start-repeat-symbol end-repeat-symbol }
? special-sequence-symbol special-sequence-symbol ?

نماد اول آپستروف است که توسط ISO/IEC 646:1991 تعریف شده‌است. با این حال این استاندارد کاراکتر ISO هفت بیتی را برای تبادل اطلاعات را به عنوان یک مرجع قانونی و بدون هیچ نامی از سایر مجموعه کاراکترها را دارد؛ بنابراین به‌طور رسمی، هیچ گونه سردرگمی با کاراکترهای یونیکد خارج از محدوده هفت بیتی ASCTE را ندارد. به عنوان مثال قوانین زیر برای بیان تکرار نشان داده شده‌اند.

aa = "A";
bb = 3 * aa, "B";
cc = 3 * [aa], "C";
dd = {aa}, "D";
ee = aa, {aa}, "E";
ff = 3 * aa, 3 * [aa], "F";
gg = {3 * aa}, "G";

رشته‌های ترمینال تعریف شده توسط این قوانین به شرح زیر می‌باشند. aa: A

bb: AAAB
cc: C AC AAC AAAC
dd: D AD AAD AAAD AAAAD etc.
ee: AE AAE AAAE AAAAE AAAAAE etc.
ff: AAAF AAAAF AAAAAF AAAAAAF
gg: G AAAG AAAAAAG etc.

توسعه پذیری[ویرایش]

با توجه به استاندارد ISO 14977، EBNF به معنی توسعه پذیری بوده و دو امکان برای آن ذکر شده‌است. اولین قسمت بخشی از زبان EBNF بوده که دارای دنباله خاصی است و متن دلخواه در یک دنباله خاص فراتر از محدوده استاندارد EBNF می‌باشد. برای مثال کاراکتر فضای خالی می‌تواند توسط قوانین زیر بیان شود.

 space = ? US-ASCII character 32 ?;

دومین حالت برای توسعه با استفاده از این واقعیت است که پرانتز در EBNF نمی‌تواند در کنار شناسه قرار گیرد؛ لذا EBNF زیر معتبر است.

 something = foo, ( bar );

براساس شرایط مثال زیر EBNF معتبر نیست.

 something = foo ( bar );

بنابراین گسترش EBNF می‌تواند با استفاده از این علامت‌ها انجام شود. به عنوان مثال در گرامر Lisp، تابع کاربردی را می‌توان با قانون زیر بیان نمود.

 function application = list( symbol, { expression } );

جستارهای وابسته[ویرایش]

منابع[ویرایش]