Eksami põhiosaks harjutamine
Eksami põhiosaks harjutamiseks lahendame 7. praktimumis tehtud KalaParser ülesande kasutades ANTLRi. Eksamil on peamine rõhk AST loomiseks, aga täispunktide saamiseks peab oskama ka ASTi abil avaldist väärtustada.
KalaParser
Me tahame esmalt kirjutada ANTLRi grammatika (faili Kala.g4) ning seejärel koostada ASTi (faili KalaAst.java) kasutades 7. praktikumis defineeritud KalaNode klasse.
Meeldetuletuseks: grammatika koosneb sulgudega ümbritsetud elementide listist, list võib olla ka tühi. Listi elemendid on omavahel eraldatud komaga, elementideks võivad olla väiketähtedest koosnev muutuja nimi, võtmesõna "null" või sulgudega ümbritsetud list. Lekseemide vahel ja ümber võib olla suvaline arv tühikuid ja tabulaatoreid.
Korrektne sisend on näiteks (kala, (x,y , null, (), (kala,()) ))
.
Soovitatav on mõelda grammatika kirjelduse järgi ise välja, aga võib kasutada ka käsitsi parsimisel toodud grammatikat:
Peale grammatika loomist tuleb siis lasta ANTLR-l genereerida lekser ja parser ning seejärel täiendada KalaAst.java faili, et koostada AST. ASTi elemente saab luua staatiliste meetoditega mkNull, mkIdent ja mkList (failis KalaNode.java).
Väärtustamise näide (iseseisvalt)
Eksamiks ettevalmistamisel võiksid ise proovida lisada variatsioonid avaldiste väärtustamisel. Eksamiülesande eesmärk on eelkõige arendada arusaamist programmide täitmisest ja seetõttu tuleb eksamil pigem selline ülesanne, mida saab mingis mõttes väärtustada.
Proovi näitena lahendada selline ülesanne, et lisame aritmeetilistele avaldistele juurde üks operaator |
, mis toob sisse mittedeterministlikut valikut kahe avaldise vahel. Siin saab implementeerida järjest raskemad ülesanded. Grammatika ja AST klassid on ette antud ja asuvad paketis choice. Ise peab implementeerima kolm meetodit klassis ChoiceAst:
- evaluate. Vaata kõigepealt AST klassid üle. Nad koosnevad ainult väärtustest (ValueNode) ja otsustustipudest (DecisionNode). Nendes enam liitmist ei ole, aga väärtustamisel antakse kaasa juhuarvugeneraator ja see teeb valikuid nextBoolean meetodi kaudu. Võttes inspiratsiooni eval meetodist, defineeri staatiline evaluate meetod, mis otse ANTLRi parsepuu põhjal väärtustab avaldist: liitmise juures liidad arvud kokku ja valiku juures kasutad samamoodi argumendina ette antud juhuarvu generaator.
- computeAllPossibleValues. See arvutab samamoodi nagu eelmine ülesanne, aga annab tulemuseks kõik võimalikud väärtused, näiteks
(1|2)+(30|40)
tulemuseks on kõik kombinatsioonid 31, 32, 41 ja 42. - createAst. See on nüüd paras pähkel. Avaldise põhjal tuleb siis luua selline AST, kus on lahti saadud liitmisest. Arvestada tuleb sellega, et liitmisel tehakse kõigepealt vasakpoolse liidetava valikuid ja siis parempoolse liidatava omad! Kuidas pead seal puud kombineerima? (Näidislahenduses lisame abimeetodid AST klassidele.)
Selle jaoks on üksikud testid, et ülesandest arusaamist kontrollida. Näidislahendus asub jällegi sols kataloogis ja see on ühtlasi ka ANTLRi visitorite kasutamise näide. Nendega hoiab natuke aega kokku, kuna IDE abil saab automaatselt meetodid genereerida (override methods).