Parser
V zadnjem sklopu vaj bomo implementirali zbirnik (angl. assembler) za zbirni jezik SIC/XE. Pri implementaciji zbirnika si lahko pomagate z vnaprej pripravljeno zasnovo. Seveda se ga lahko lotite tudi povsem po svoje. Za dodatne točke zbirnik spišite v jeziku, ki ga asistent ne zna, za čast in slavo pa v jeziku, ki ga asistent ne pozna.
Za začetek bomo tokrat izdelali program, ki prebere izvorno kodo v zbirniku SIC/XE, jo pretvori v interno obliko (angl. abstract syntax tree oziroma AST), nato pa izpiše zgrajeno. Dobili boste lep izpis (angl. pretty print) programa.
Predstavitev kode
Jezik SIC/XE poleg nekaj različnih sintaktičnih oblik (angl. syntax forms): direktive, kometarje in nekaj oblik ukazov. pozna več različnih ukazov. Za vsako vrsto ukazov naredite svoj razred, ki naj bo izpeljan iz osnovnega razreda Node
. Potrebovali boste torej še naslednje razrede:
Comment
- komentarji;InstructionF1
- ukazi formata 1;InstructionF2
- ukazi formata 2;InstructionF3
- ukazi formata 3;InstructionF4
- ukazi formata 4;Directive
- direktiveSTART
,END
, …; inStorage
- pomnilniške direktiveBYTE
,WORD
,RESB
,RESW
.
Za vsako obliko (torej razred) razmislite, katere parametre (registri, naslovi, konstante ipd.) potrebuje. Za Comment
je to lahko kar niz znakov z vsebino komentarja. Razrede boste kasneje dopolnili z metodami za razreševanje simbolov in generiranje kode.
Potrebovali boste še razred Code
, ki bo predstavljal celoten zbirniški program. Hrani naj ime programa, seznam ukazov, lokacijski števec itd. V ta razred boste kasneje dodali metode za razreševanje simbolov, generiranje objekte kode itd.
Predstavitev mnemonikov
»Mnemonik« je simbolično ime za ukaz, torej npr. LDA
, RESB
in START
. Razdelimo jih v več skupin - glede na formate, vrsto operandov ipd. Zopet bomo izhajali iz abstraktnega razreda Mnemonic
, ki vsebuje ime mnemonika, morebitno operacijsko kodo in opis mnemonika (potrebno za izpis pomoči).
Za vsak tip mnemonika (glede na operande in način naslavljanja) bomo naredili svoj razred, npr.:
MnemonicD
- direktiva brez operandov (NOBASE
,LTORG
);MnemonicDn
- direktiva z enim številskim operandom (lahko tudi simbol) (START
,END
, …);MnemonicF1
- ukaza formata 1 (brez operandov) (FIX
,FLOAT
, …);MnemonicF2n
- F1 z enim številskim operandom (SVC
);MnemonicF2r
- F1 z enim registrskim operandom (CLEAR
,TIXR
);MnemonicF2rn
- F1 z enim registrskim in enim številskim operandom (SHIFTL
,SHIFTR
);MnemonicF2rr
- F1 z dva registrskima operandoma (ADDR
, …);MnemonicF3
- F3 brez operandov (RSUB
);MnemonicF3m
- F3 z enim operandom (LDA
, …);MnemonicF4m
- F4 z enim operandom (+LDA
, …);MnemonicSd
- pomnilniška direktiva s podatki (BYTE
,WORD
);MnemonicSn
- pomnilniška direktiva za rezervacijo (RESB
,RESW
).
Vsakemu izpeljanemu razredu dodamo ustrezne atribute, ki bodo hranili operande. Prav tako moramo za vsak izpeljan razred povoziti metodo
Node parse(Parser parser)
ki za vsak tip mnemonika prebere in razpozna operande, ki mu sledijo, nato pa vrne predstavitev ukaza kot objekt enega izmed razredov iz zgornje naloge.
Sintaksna analiza
Za sintaksno analizo izvorne kode lahko uporabite razreda Lexer
in Parser
, dana v okviru vaj. Vaša naloga je predvsem, da napište razpoznavanje operandov (glej prejšnjo nalogo). Naloge se lotite po sklopih, npr. najprej ukazi formata 1, formata 2 itd.