Atributová gramatika

Atributové gramatiky je formalismus v matematické informatice poskytující rozšíření formálních gramatik o přenos informací v rámci přepisovacího pravidla, což umožňuje přenos (např. sémantických) informací z libovolného místa v abstraktním syntaktickém stromě kamkoli jinam, řízeným a formálním způsobem.[1] Ke každému terminálnímu nebo neterminálnímu symbolu gramatiky je možné připojit jeden nebo více atributů, a ke každému přepisovacímu pravidlu jsou přiřazeny tak zvané sémantické funkce, pomocí kterých se při použití tohoto pravidla počítají z některých atributů symbolů použitých v pravidle hodnoty dalších atributů symbolů použitých v pravidle.

Atributové gramatiky umožňují při konstrukci překladačů rozšířit syntaktický analyzátor o možnost přenášet různé doplňující informace během analýzy vstupního řetězce. Atributy mohou být použity pro přiřazení sémantických hodnot syntaktickým konstrukcím (například rozlišit, zda operátor + znamená sčítání celých čísel, sčítání reálných čísel, zřetězení nebo sjednocení množin nebo má jiný význam). Atributy také umožňují validovat podmínky, které nejsou přímo vyjádřeny pomocí syntaxe, ale jako doplňující sémantická pravidla přiřazená k jednotlivým pravidlům gramatiky (například kontrolovat typová omezení nebo kontrolovat, zda jsou použité identifikátory deklarovány). Atributové gramatiky lze použít pro převod syntaktického stromu přímo na kód pro určitý stroj nebo do nějaké formy mezijazyka.

Podle toho, zda sémantická funkce slouží pro vyčíslení hodnoty atributu symbolu z levé nebo z pravé strany přepisovacího pravidla, se atributy dělí na syntetizované (funkce vyčísluje atributy symbolu na levé straně pravidla) a zděděné (příp. dědičné). Zatímco syntetizované atributy umožňují přenos sémantické informace derivačním stromem vzhůru, zděděné atributy umožňují předávání hodnot z rodičovských uzlů dolů a napříč syntaktickým stromem.

Historie

Za autora atributových gramatik je považován Donald Ervin Knuth, jehož první článek o tomto tématu vyšel v roce 1968.[2] Knuth zmiňuje, že zárodky konceptu atributových gramatik lze dohledat již u Edgara T. „Neda“ Ironse,[3] autora programovacího jazyka IMP, a uvádí, že koncept zděděných atributů navrhl během konverzace s Knuthem Peter Wegner.[4]

Příklad

Následující příklad je jednoduchá bezkontextová gramatika, která popisuje jazyk výrazů obsahujících násobení a sčítání celých čísel.

 ExprExpr + Term
 ExprTerm
 TermTerm * Factor
 TermFactor
 Factor → "(" Expr ")"
 Factorinteger

Pro výpočet hodnot výrazů zapsaných podle této gramatiky lze použít následující atributovou gramatiku; tato gramatika používá pouze syntetizované atributy, takže jde o S-atributovanou gramatiku:

 Expr1Expr2 + Term [ Expr1.value = Expr2.value + Term.value ]
 ExprTerm [ Expr.value = Term.value ]
 Term1Term2 * Factor [ Term1.value = Term2.value * Factor.value ]
 TermFactor [ Term.value = Factor.value ]
 Factor → "(" Expr ")" [ Factor.value = Expr.value ]
 Factorinteger [ Factor.value = strToInt(integer.str) ]

Syntetizované atributy

Hodnoty syntetizovaných atributů se počítají pouze z hodnot atributů potomků daného uzlu v derivačním stromě. Protože se nejdříve musí vypočítat hodnoty potomků, jde o šíření hodnot zdola nahoru. Pro formální definici syntetizovaného atributu, nechť je formální gramatika, kde

  • je množina neterminálních symbolů
  • je množina terminálních symbolů
  • je množina přepisovacích pravidel
  • je počáteční symbol

Je-li dán řetězec neterminálních symbolů pak jeho atribut , je syntetizovaným atributem, pokud jsou splněny následující tři podmínky:

  • (tj. je jedním z pravidel v gramatice)
  • (tj. každý symbol v těle pravidla je buď neterminál anebo terminál)
  • , kde (tj. hodnota atributu závisí pouze na hodnotách atributů symbolů na pravé straně pravidla).

Zděděné atributy

Zděděný atribut uzlu v derivačním stromě je definován pomocí hodnot atributů rodičovských nebo sourozeneckých uzlů. Zděděné atributy jsou vhodné pro vyjádření závislosti konstruktu programovacího jazyka na kontextu, v němž se tento konstrukt objevuje. Zděděný atribut může například posloužit pro rozlišení, zda se identifikátor objevil na levé nebo pravé straně přiřazení, aby bylo možné určit, zda se má v generovaném kódu použít adresa nebo hodnota proměnné. Na rozdíl od syntetizovaných atributů se hodnoty zděděných atributů počítají z atributů rodičů nebo sourozenců. Například v přepisovacím pravidle

S → ABC

se hodnoty zděděných atributů symbolu A počítají z atributů symbolů S, B a C; hodnoty zděděných atributů symbolu B z atributů symbolů S, A a C; a hodnoty zděděných atributů symbolu C z S, A a B.

Speciální typy atributových gramatik

  • L-atributované gramatiky jsou atributové gramatiky v nichž lze zděděné atributy vyčíslit v jednom průchodu abstraktním syntaktickým stromem zleva doprava
  • LR-atributované gramatiky jsou L-atributované gramatiky, v niž lze zděděné atributy vyčíslit také při syntaktické analýze zdola nahoru
  • ECLR-atributované gramatiky jsou podmnožinou LR-atributovaných gramatik, u nichž lze kde lze optimalizovat vyhodnocování zděděných atributů pomocí tříd ekvivalence
  • S-atributované gramatiky jsou jednoduchým typem atributových gramatik, které používají pouze syntetizované atributy

Další informace

Článek Why Attribute Grammars Matter popisuje, jak formalismus atributových gramatik vnáší prvky aspektově orientovaného programování do funkcionálního programování tím, že pomáhá programovat katamorfismy kompozicionálně.[5] V příkladech používá Attribute Grammar System vytvořený na Univerzitě v Utrechtu.[6] Článek na webu věnovanému jazyku Haskel[7] popisuje atributové gramatiky ve vztahu k Haskellu a funkcionálnímu programování.

Odkazy

Poznámky

Reference

V tomto článku byl použit překlad textu z článku Attribute grammar na anglické Wikipedii.

Související články

Externí odkazy