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

فرم باکوس نائور توسعه یافته (به انگلیسی: 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 قرار دهد.

مثال

حتی 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 شامل مکانیزیم‌هایی برای پیشرفت بوده که تعریف تعدادی از تکرارها به استثنای جایگزین‌های کامنت و غیره را دارد.

توسعه پذیری

با توجه به استاندارد 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 } );