Ciele
- Oboznámiť sa s anotáciami.
- Oboznámiť sa s generátorom jazykových procesorov YAJCo.
- Oboznámiť sa so spôsobom použitia anotácií potrebných pre definovanie konkrétnej syntaxe jazyka entít priamo v kóde metamodelu.
- Oboznámiť sa so spôsobom konfigurácie projektu pre použitie nástroja YAJCo.
Úvod
-
Tento modul bližšie opisuje
tento generátor jazykových procesorov a anotácie, ktoré sa používajú
na zadefinovanie konkrétnej syntaxe generovaného jazyka.
Postup
-
Generátor jazykových procesorov (angl. parser generator) je nástroj, ktorý generuje jazykový procesor na základe formálnej špecifikácie tohto procesora (resp. jazyka). Najznámejší príklad generátora jazykových procesorov je YACC. Vstupom generátora je zvyčajne bezkontextová gramatika zapísaná v požadovanom formáte a výstupom je zdrojový kód jazykového procesora. Pre generovania jazykového procesora je odporúčané použiť generátor YAJCo (Yet Another Java Compiler Compiler). Generátor YAJCo umožňuje generovať jazykový procesor priamo z modelu jazyka, ktorý je zapísaný vo forme anotovaných tried jazyka Java. Anotácie slúžia na označovanie jazykových elementov (balík, trieda, metóda, premenná) v programe v podobe štruktúrovaných poznámok. Anotácie nesú informácie, ktoré je možné interpretovať v kontexte anotovaných jazykových elementov. Okrem vstavaných anotačných typov je možné definovať vlastné anotačné typy. Viac informácii o anotáciách v jazyku Java je možné nájsť na nasledujúcich stránkach: Generátor YAJCo je detailnejšie opísaný v publikácii ako súčasť výskumu na Katedre počítačov a informatiky FEI TU Košice.
-
Konkrétna syntax jazyka je definovaná pre tento generátor prostredníctvom anotovaných konštruktorov tried. Nasledujúci text stručne opisuje anotácie a uvádza ich použitie na príkladoch.
- @Optional anotácia určuje, že sa pojem v konštrukcii nemusí vyskytnúť. Používa sa na označenie parametra konštruktora.
-
@Range anotácia sa používa pre definovanie
minimálneho alebo maximálneho počtu výskytov pojmov v konštrukcii.
Anotácia
@Range
je použiteľná len na označenie parametra konštruktora typu pole. V prípade, že anotácia nie je uvedená pri poli, generátor interpretuje rozsah ako 0 až nekonečno. - Anotácia @Before určuje lexikálne symboly, ktoré budú predchádzať označenej konštrukcii. Je ňou možné označiť parameter konštruktora alebo konštruktor.
- Anotácia @After vymenováva lexikálne symboly, ktoré budú nasledovať za označenou konštrukciou. Je ňou možné označiť parameter konštruktora alebo konštruktor.
- Anotácia @Separator sa používa na určenie oddeľovača postupnosti pojmov toho istého typu prostredníctvom lexikálneho symbolu. je použiteľná len na označenie parametra konštruktora typu pole.
- Anotácia @Token sa používa na špecifikáciu lexikálneho symbolu, ktorý je podstatný pre abstraktnú syntax a sémantiku z pohľadu jeho výskytu a zápisu (napr. číslo, identifikátor). Je ňou možné označiť parameter konštruktora.
- Anotácia @Exclude sa používa na vylúčenie triedy respektíve konštruktora zo spracovania generátorom. Anotáciu je možné použiť na označenie triedy respektíve konštruktora.
-
@Identifier anotácia je určená na označenie
jednoznačného identifikátora výskytu pojmu vo vete.
Zároveň umožňuje definovať kontext, v ktorom má byť
identifikátor jedinečný prostredníctvom hodnoty atribútu
unique
. Tento atribút je reťazec obsahujúci štandardný XPath výraz. Nasledujúce príklady sú ukážkami použitia anotácie@Identifier
. Ako identifikátor pojmu je v oboch prípadoch zvolená premennáname
. -
@References anotácia umožňuje špecifikovať
referencie na výskyty pojmov.
Generátor YAJCo na základe reflexie vyhľadáva
určené objekty prostredníctvom anotácie
@References
. Identifikátory vo vyhľadaných objektoch musia byť označené prostredníctvom anotácie@Identifier
. Nájdené referencie na výskyty špecifikovaných pojmov sú následne uložené prostredníctvom injektáže do objektu (set metóda). Povinný atribútvalue
anotácie@References
definuje cieľový pojem. Nasledujúce príklady sú ukážkami použitia anotácie@References
. Atribútfield
anotácie@References
, umožňuje odlíšiť premennú na uloženie referencie. Bez uvedenie mena premennej je uložená referencia na základe typu pojmu.
-
Uvedieme niekoľko príkladov použitia anotácií generátora YAJCo.
Vo vyjadrení prostredníctvom EBNF zápisupublic class Condition implements Statement { public Condition( Expression expression, Statement trueStatement, @Optional Statement falseStatement) { ... } ... }
Entity ::= 'entity' <NAME> '{' Property+ '}'
zodpovedá nasledujuci konštruktor:
Zápisupublic class Entity implements Named { @Identifier private final String name; @Before("entity") public Entity(String name, @Before("{") @After("}") @Range(minOccurs = 1) Property[] properties) { ... } }
Property ::= <NAME> ':' Type (Constraint (',' Constraint)*)?
zodpovedá:
Zápisupublic class Property implements Named { @Identifier(unique = "../sk.tuke.magsa.tools.metamodel.Property") private final String name; public Property(String name, @Before(":") Type type, @Separator(",") Constraint[] constraints) { ... } @Exclude public Property(String name, Type type) { ... } }
Length ::= 'length' <INT_VALUE> <INT_VALUE>
zodpovedá:
Zápispublic class Length extends Constraint { @Before("length") public Length(@Token("INT_VALUE") int minLength, @Token("INT_VALUE") int maxLength) { ... }
Reference ::= 'reference' <NAME> <NAME>
je vyjadrený nasledovne:@Before("reference") public Reference( @References(value = Entity.class, field = "from") @Token("NAME") String from, @References(value = Entity.class, field = "to") @Token("NAME") String to) { }
-
Okrem uvedených anotácii pre definovanie konkrétnej syntaxe je pre generátor nutné špecifikovať ďalšie údaje. Anotácia
@Parser
sa používa pre označenie balíka v jazyku Java s modelom jazyka a umiestňuje sa v zmysle špecifikácie jazyka Java do súborupackage-info.java
. Na základe tejto anotácie získava generátor hlavnú (koreňovú) triedu v doménovom modeli a následne spracováva celý model počnúc touto triedou. Táto anotácia taktiež určuje meno hlavnej triedy vygenerovaného jazykového procesora a definuje lexikálne symboly a biele znaky. Zapísanú anotáciu@Parser
pre model jazyka entít je možné nájsť v súbore parser1.zip.Poznámka: Generátor YAJCo generuje výstupné súbory pre JavaCC. Viac o JavaCC je možné zistiť na https://javacc.java.net/. Lexikálne jednotky pre YAJCo sa zapisujú vo forme regulárnych výrazov jazyka Java.Poznámka: Mimo vývojového prostredia je možné použiť procesor YAJCo nasledovne.
Uvedený príkaz príkazového riadku predpokladá existenciu adresárajavac -s src -proc:only -cp lib\yajco.jar;lib\javacc.jar;lib\velocity-1.6.1-dep.jar src\sk\tuke\magsa\metamodel\*.java src\sk\tuke\magsa\metamodel\constraints\*.java src\sk\tuke\magsa\metamodel\ui\*.java
lib
so súbormiyajco.jar
,javacc.jar
avelocity-1.6.1-dep.jar
a adresárasrc
so zdrojovými textami.
Zdroje
- Anotácie:
- Viac o generátoroch jazykových procesorov
-
Zdrojové kódy:
- parser1.zip - konfiguračný súbor pre balík jazykového procesora
-
Knižnice:
- yajco.jar - knižnica generátora jazykových procesororv YAJCo
- javacc.jar - knižnica generátora jazykových procesorov javacc
@Identifier
a@References
vyplývajú z kontextu použitia, nie zo samotnej syntaxe jazyka.