Extended Backus – Naur Form ( EBNF ) je formální systém definice syntaxe, ve kterém jsou některé syntaktické kategorie postupně definovány prostřednictvím jiných . Používá se k popisu bezkontextových formálních gramatik . Navrhl Niklaus Wirth . Jedná se o rozšířené zpracování forem Backus-Naur , od BNF se liší „prostornějšími“ konstrukcemi, které při stejné vyjadřovací schopnosti umožňují zjednodušit a zmenšit objem popisu.
Používá se však mnoho různých variant RBNF. Mezinárodní organizace pro normalizaci přijala normu RBNF: ISO/IEC 14977 [1] .
Stejně jako v BNF je popis gramatiky v RBNF soubor pravidel definujících vztahy mezi koncovými symboly (terminály) a neterminálními symboly (neterminály).
Pravidlo v RBNF je:
идентификатор = выражение.
kde identifikátor je název nekoncového symbolu a výraz je kombinací koncových a nekoncových symbolů a speciálních znaků, která je v souladu s pravidly RBNF. Tečka na konci je speciální znak, který označuje konec pravidla.
Sémantika pravidla RBNF spočívá v tom, že nekoncový znak určený identifikátorem nalevo od rovnítka je kombinací koncových a neterminálních znaků definovaných výrazem .
Úplný popis gramatiky je sada pravidel, která postupně definují všechny neterminální symboly gramatiky, takže každý neterminální symbol může být redukován na kombinaci koncových symbolů postupnou (rekurzivní) aplikací pravidel. V definici RBNF nejsou žádná zvláštní pravidla týkající se pořadí, ve kterém jsou pravidla napsána, i když takové předpisy mohou být zavedeny při používání RBNF softwarovými nástroji, které poskytují automatické generování analyzátorů z popisu gramatiky.
Sada možných konstrukcí RBNF je velmi malá. Jedná se o zřetězení, výběr, podmíněný výskyt a opakování.
Nebo vše výše uvedené ve zkratce:
V některých pracích existují upravené varianty syntaxe RBNF.
— pravidlo, které specifikuje gramatiku podmíněného operátoru jazyka Modula-2 , kde „Podmíněný operátor“ a „Skupina operátorů“ jsou neterminální symboly se složenými názvy.
Obecná forma popisné gramatiky EBNF může být popsána jako EBNF takto:
Syntaxe = { SynthOperator }. SynthOperator = Identifikátor "=" SynthExpression "." . SyntExpression = SynTerm { "|" SinTerm }. SynTerm = SyntFactor { SyntFactor }. SynthFactor = identifikátor | řetěz | "(" SynthExpression ")" | "[" SynthExpression "]" | "{" SynthExpression "}" .Tento popis předpokládá, že identifikátor a řetězec jsou předdefinované termíny. V případě potřeby není obtížné zapsat jejich definici do RBNF, k tomu stačí zadat určitou abecedu a v případě potřeby další omezení typu identifikátoru.
Následující gramatiky definují zápis obecného desetinného čísla (s počátečním znaménkem, případnou zlomkovou částí a exponentem) a typickým identifikátorem programovacího jazyka (posloupnost písmen, čísel a podtržítek začínající písmenem).
Číslo = [ "+" | "-" ] NatNumber [ "." [ NatNumber ]][( "e" | "E" )[ "+" | "-" ] NatNumber ]. NatNumber = číslice { číslice }. Číslice = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" . Ident = písmeno { písmeno | Číslice | "_" }.Definice nekoncového Písmena zde není uvedena z důvodu samozřejmosti a těžkopádnosti - představuje výběr z uznávané abecedy.
Podobnosti a rozdíly mezi BNF a RBNF jsou zřejmé z popisu. Rozdíl je celkově ve dvou hlavních bodech:
Na úspěch či neúspěch první změny mohou být různé názory, ale v žádném případě to nemá vliv na výrazové možnosti formy. Ale druhá inovace je velmi významná. Nepřidává také zásadně nové vyjadřovací možnosti (vše, co je napsáno v RBNF, lze adekvátně zapsat v běžném BNF), ale výrazně snižuje a zjednodušuje zápis.
Hlavní výhodou RBNF oproti BNF je schopnost popsat jednoduché opakující se konstrukce neurčité délky (seznamy, řetězce, sekvence atd.) bez rekurzivních pravidel. Absence konstrukce opakování v BNF vede k tomu, že každé opakování musí být definováno zavedením dalších přechodných neterminálních symbolů a rekurzivních pravidel, což činí definici příliš velkou a nejasnou. Popis opakování v EBNF se ukazuje jako kratší a vhodnější pro lidské vnímání.
Jako příklad zvažte pravidla, která definují neterminální „seznam“, což je sada od nuly do libovolného počtu identifikátorů oddělených čárkami (za předpokladu, že znaky „Pravá závorka“, „Levá závorka“, „Čárka“ a „Ident “ jsou již definovány).
Definice v RBNF obsahuje pouze jedno pravidlo:
Seznam = Levá závorka [ Ident { Ident čárky } ] Pravá závorka .Definice v BNF vypadá takto:
<Seznam> ::= <Levá závorka> <Pravá závorka> | <Levá závorka> <IdentList> <Pravá závorka> <IdentList> ::= <Ident> | <Ident> <Čárka> <IdentList>Již z tohoto příkladu jsou vidět rozdíly mezi formuláři:
Cenou za výhody RBNF oproti BNF je přirozeně větší složitost automatické interpretace popisů RBNF. Generátory formálního analyzátoru gramatiky, které používají BNF, jsou jednodušší než ty, které používají RBNF.
RBNF jsou ekvivalentní podtřídě syntaktických diagramů, které se široce používají k popisu gramatik. Jakákoli gramatika RBNF může být adekvátně reprezentována syntaktickým diagramem, ale obecně vám syntaktické diagramy umožňují vytvářet popisy, které nemohou být reprezentovány v RBNF (nebo v žádném případě nemohou být přeloženy do RBNF přímo bez předchozí konverze grafického popisu) .
RBNF, stejně jako jeho předchůdce, BNF, je extrémně široce používán jako prostředek k popisu umělých jazyků, především programovacích jazyků a souvisejících notačních systémů. Zejména vynálezce RBNF, Niklaus Wirth, použil tento formalismus ve svých knihách k popisu všech programovacích jazyků, o kterých se tam uvažovalo.
Vyšší komplexnost RBNF ve srovnání s BNF vede k tomu, že existuje podstatně méně generátorů analyzátorů založených na RBNF než generátorů založených na BNF. Nicméně existují a platí. RBNF je základem pro Spirit C++ Parser Framework, Coco/R, The SLK Parser Generator a některé další. Pro použití v takových systémech je syntaxe RBNF rozšířena stejným směrem jako syntaxe BNF při použití generátorů yacc nebo bison parser - kód, který ji zpracovává, je přímo vložen do popisu gramatiky a interakce s lexikálním analyzátorem je nějak organizována . Na strukturu pravidel mohou být také uložena další omezení – ne všechna pravidla, která lze v RBNF popsat, lze efektivně převést na kód.
Mezi absolutní přednosti RBNF patří jednoduchost (samotný jazyk RBNF obsahuje pouze 10 speciálních znaků - tři typy závorek, svislá čára, rovnítko a uvozovky, případně čárka; jeho syntaxe je určena pěti pravidly), dostatečný výkon a viditelnost, díky čemuž je vhodný pro vytváření popisů určených nejen pro automatický výklad, ale i pro čtení člověkem. Blízkost konstrukcí RBNF k syntaktickým diagramům umožňuje čerpat je přímo z popisu RBNF.
Nevýhody RBNF, stejně jako BNF, zahrnují skutečnost, že popisují gramatickou strukturu formálního jazyka bez zohlednění kontextových závislostí, což znamená, že v přítomnosti takových závislostí se popis RBNF ukáže jako neúplný. , a některá pravidla syntaxe popisovaného jazyka musí být uvedena v normální textové formě. To vede k tomu, že text, který přesně odpovídá gramatice RBNF, může být stále syntakticky nesprávný. Například v gramatice RBNF není možné přirozeně vyjádřit skutečnost, že operace vyžaduje operandy stejného typu. Tyto kontroly musí být prováděny ručně psaným kódem gramatického analyzátoru. Na druhou stranu systémy popisu gramatiky, které zahrnují definici kontextových závislostí, například van Wiingaardenova gramatika , se ukazují být mnohem komplikovanější a jejich použití pro automatické generování parserů se ukazuje jako obtížné.