Programiranje

Kako zgraditi tolmač v Javi, 1. del: OSNOVE

Ko sem prijatelju povedal, da sem na Javi napisal tolmača BASIC, se je tako zasmejal, da je soda, ki jo je držal, skoraj razlil po oblačilih. "Zakaj bi sploh ustvarili BASIC tolmač v Javi?" je bilo predvidljivo prvo vprašanje iz njegovih ust. Odgovor je tako preprost kot kompleksen. Preprost odgovor je, da je bilo zabavno pisati tolmača v Javi, in če bi pisal tolmača, bi lahko napisal tudi takšnega, na katerega imam lepe spomine iz zgodnjih dni osebnega računalništva. Na zapleteni strani sem opazil, da je veliko ljudi, ki danes uporabljajo Javo, prestopilo točko ustvarjanja klopajočih Duketovih programčkov in prehaja na resne programe. Pogosto bi pri sestavljanju aplikacije želeli, da jo je mogoče konfigurirati. Izbrani mehanizem za ponovno konfiguracijo je nekakšen mehanizem za dinamično izvajanje.

Dinamično izvajanje je znano kot makro jeziki ali konfiguracijski jezik in omogoča uporabniku, da program "programira". Prednost dinamičnega izvedbenega mehanizma je, da je mogoče orodja in aplikacije prilagoditi za izvajanje zapletenih nalog, ne da bi orodje zamenjali. Platforma Java ponuja široko paleto možnosti dinamičnega izvajanja.

HotJava in druge vroče možnosti

Oglejmo si na kratko nekatere razpoložljive možnosti dinamičnega izvedbenega mehanizma in nato poglobljeno preučimo izvajanje mojega tolmača. Stroj za dinamično izvajanje je vdelani tolmač. Tolmač za delovanje potrebuje tri naprave:

  1. Način za nalaganje navodil
  2. Format modula za shranjevanje navodil, ki jih je treba izvesti
  3. Model ali okolje za interakcijo z gostiteljskim programom

HotJava

Najbolj znan vgrajeni tolmač mora biti "aplet" okolje HotJava, ki je popolnoma preoblikovalo pogled ljudi na spletne brskalnike.

Model "apleta" HotJava je temeljil na ideji, da lahko aplikacija Java ustvari generični osnovni razred z znanim vmesnikom, nato pa dinamično naloži podrazrede tega razreda in jih izvede med izvajanjem. Ti apleti so ponujali nove zmogljivosti in v okviru osnovnega razreda dinamično izvajanje. Ta zmogljivost dinamičnega izvajanja je temeljni del okolja Java in ena od stvari, zaradi katerih je tako posebno. To določeno okolje bomo podrobneje preučili v kasnejšem stolpcu.

GNU EMACS

Pred prihodom HotJave je bila morda najuspešnejša aplikacija z dinamično izvedbo GNU EMACS. Makro jezik tega urejevalnika, podoben LISP, je za mnoge programerje postal osnovna stvar. Na kratko je okolje EMACS LISP sestavljeno iz tolmača LISP in številnih funkcij urejanja, ki jih lahko uporabimo za sestavljanje najbolj zapletenih makrov. Ne bi smelo biti presenetljivo, da je bil urejevalnik EMACS prvotno napisan v makrih, namenjenih urejevalniku z imenom TECO. Tako je razpoložljivost bogatega (če neberljivega) jezika makrov v TECO omogočila izdelavo povsem novega urejevalnika. Danes je GNU EMACS osnovni urejevalnik, celotne igre pa so napisane samo v EMACS LISP kodo, znano kot el-code. Zaradi te konfiguracijske zmožnosti je GNU EMACS postal glavni urednik, medtem ko so terminali VT-100, na katerih je bil zasnovan, postali zgolj opombe v pisateljevem stolpcu.

REXX

Eden izmed mojih najljubših jezikov, ki nikoli ni dosegel pravega zaslužka, je bil REXX, ki ga je zasnoval Mike Cowlishaw iz IBM-a. Podjetje je potrebovalo jezik za nadzor aplikacij na velikih računalnikih z operacijskim sistemom VM. REXX sem odkril na Amigi, kjer je bil prek "vrat REXX" tesno povezan z najrazličnejšimi aplikacijami. Ta vrata omogočajo oddaljeno upravljanje aplikacij prek tolmača REXX. Ta povezava tolmača in aplikacije je ustvarila veliko močnejši sistem, kot je bilo mogoče z njegovimi sestavnimi deli. Na srečo jezik živi v NETREXX, različici, ki jo je napisal Mike in je bila zbrana v kodo Java.

Ko sem gledal NETREXX in mnogo starejši jezik (LISP v Javi), se mi je zdelo, da so ti jeziki tvorili pomembne dele zgodbe o aplikaciji Java. Kakšen boljši način je povedati ta del zgodbe, kot pa tu narediti nekaj zabavnega - na primer obuditi BASIC-80? Še pomembneje je, da bi bilo koristno prikazati en način, na katerega lahko v Java pišete skriptne jezike, in z njihovo integracijo z Javo pokazati, kako lahko izboljšajo zmogljivosti vaših aplikacij Java.

OSNOVNE zahteve za izboljšanje vaših aplikacij Java

OSNOVNI je preprosto osnovni jezik. Obstajata dve šoli razmišljanja o tem, kako bi lahko kdo napisal tolmača zanj. Eden od pristopov je pisanje programske zanke, v kateri program tolmača prebere eno vrstico besedila iz interpretiranega programa, ga razčleni in nato pokliče podprogram za njegovo izvajanje. Zaporedje branja, razčlenjevanja in izvrševanja se ponavlja, dokler ena od izjav razlaženega programa tolmaču ne reče, da se ustavi.

Drugi in veliko bolj zanimiv način reševanja projekta je pravzaprav razčlenitev jezika v drevo za razčlenjevanje in nato izvedbo razčlenjevalnega drevesa "na mestu". Tako delujejo tokenizirajoči tolmači in način, kako sem se odločil nadaljevati. Tokeniziranje tolmačev je tudi hitrejše, saj jim ni treba znova pregledati vnosa vsakič, ko izvršijo stavek.

Kot sem že omenil, so trije sestavni deli, potrebni za doseganje dinamične izvedbe, sredstvo za nalaganje, format modula in izvedbeno okolje.

Prva komponenta, sredstvo za nalaganje, bo obravnavana z Java InputStream. Ker so vhodni tokovi bistveni za V / I arhitekturo Jave, je sistem zasnovan za branje v programu iz InputStream in ga pretvorite v izvedljivo obliko. To predstavlja zelo prilagodljiv način vnosa kode v sistem. Seveda bo protokol za podatke, ki gredo čez vhodni tok, OSNOVNA izvorna koda. Pomembno je omeniti, da se lahko uporablja kateri koli jezik; ne zmotite se, če mislite, da te tehnike ni mogoče uporabiti za vašo aplikacijo.

Po vnosu izvorne kode interpretiranega programa v sistem sistem pretvori izvorno kodo v notranjo predstavitev. Za ta projekt sem uporabil drevo razčlenitve kot notranjo obliko predstavitve. Ko je drevo za razčlenitev ustvarjeno, ga je mogoče manipulirati ali izvršiti.

Tretja komponenta je izvedbeno okolje. Kot bomo videli, so zahteve za to komponento dokaj preproste, vendar ima izvedba nekaj zanimivih preobratov.

Zelo hitra osnovna tura

Za tiste, ki morda nikoli niste slišali za BASIC, vam na kratko predstavim jezik, da boste lahko razumeli izzive razčlenjevanja in izvedbe, ki so pred nami. Za več informacij o programu BASIC toplo priporočam vire na koncu tega stolpca.

BASIC je kratica za univerzalni simbolični učni kodeks za začetnike in je bil razvit na univerzi Dartmouth za poučevanje konceptov računanja dodiplomskih študentov. Od svojega razvoja se je BASIC razvil v različna narečja. Najenostavnejša od teh narečij se uporabljajo kot nadzorni jeziki za krmilnike industrijskih procesov; najbolj zapletena narečja so strukturirani jeziki, ki vključujejo nekatere vidike objektno usmerjenega programiranja. Za svoj projekt sem izbral narečje, znano kot BASIC-80, ki je bilo v poznih sedemdesetih letih priljubljeno v operacijskem sistemu CP / M. To narečje je le zmerno bolj zapleteno kot najpreprostejša narečja.

Sintaksa stavka

Vse vrstice izjav so v obliki

[ : [ : ... ] ]

kjer je "Vrstica" številka vrstice stavka, "Ključna beseda" je BASIC ključna beseda stavka, "Parametri" pa niz parametrov, povezanih s to ključno besedo.

Številka vrstice ima dva namena: služi kot oznaka za stavke, ki nadzorujejo potek izvajanja, na primer a Pojdi do stavek in služi kot oznaka za razvrščanje stavkov, vstavljenih v program. Številka vrstice kot oznaka za razvrščanje olajša okolje za urejanje vrstic, v katerem se urejanje in obdelava ukazov mešata v eni interaktivni seji. Mimogrede, to je bilo potrebno, ko ste imeli le teletekst. :-)

Številke vrstic sicer niso zelo elegantne, vendar okolju tolmača omogočajo posodabljanje programa po en stavek naenkrat. Ta sposobnost izhaja iz dejstva, da je stavek en sam razčlenjen entitet in ga je mogoče v podatkovni strukturi povezati s številkami vrstic. Brez številk vrstic je pogosto treba ponovno razčleniti celoten program, ko se vrstica spremeni.

Ključna beseda identificira izjavo BASIC. V primeru bo naš tolmač podprl nekoliko razširjen nabor osnovnih besed, vključno z Pojdi do, gosub, vrnitev, natisni, če, konec, podatkov, obnoviti, preberite, na, rem, za, Naslednji, pustiti, vhod, ustavi se, dim, naključno, tron, in troff. Očitno tega ne bomo obravnavali v tem članku, bo pa v spletu v naslednjem mesecu objavljena dokumentacija "Java In Depth", ki jo boste lahko raziskali.

Vsaka ključna beseda ima nabor zakonitih parametrov ključnih besed, ki ji lahko sledijo. Na primer Pojdi do Ključni besedi mora slediti številka vrstice, če stavku mora slediti pogojni izraz in ključna beseda potem -- in tako naprej. Parametri so specifični za vsako ključno besedo. Nekaj ​​teh seznamov parametrov bom podrobneje opisal nekoliko kasneje.

Izrazi in operatorji

Parameter, naveden v stavku, je pogosto izraz. Različica BASIC, ki jo uporabljam tukaj, podpira vse standardne matematične operacije, logične operacije, stopnjevanje in preprosto knjižnico funkcij. Najpomembnejša komponenta slovnice izrazov je sposobnost klicanja funkcij. Izrazi so precej standardni in podobni izrazom, razčlenjenim v primeru v prejšnjem stolpcu StreamTokenizer.

Spremenljivke in tipi podatkov

Del razloga, da je BASIC tako preprost jezik, je ta, da ima le dva podatkovna tipa: številke in nize. Nekateri skriptni jeziki, kot sta REXX in PERL, sploh ne razlikujejo med vrstami podatkov, dokler niso uporabljeni. Toda pri BASIC se za identifikacijo podatkovnih vrst uporablja preprosta sintaksa.

Imena spremenljivk v tej različici BASIC so nizi črk in številk, ki se vedno začnejo s črko. Spremenljivke ne razlikujejo med velikimi in malimi črkami. Tako so A, B, FOO in FOO2 veljavna imena spremenljivk. Poleg tega je v jeziku BASIC spremenljivka FOOBAR enakovredna FooBar. Za prepoznavanje nizov je imenu spremenljivke dodan znak za dolar ($); tako je spremenljivka FOO $ spremenljivka, ki vsebuje niz.

Končno, ta različica jezika podpira nize z uporabo dim ključna beseda in spremenljivka sintaksa obrazca NAME (index1, index2, ...) za največ štiri indekse.

Struktura programa

Programi v jeziku BASIC se privzeto zaženejo z najmanj oštevilčeno vrstico in se nadaljujejo, dokler ni več vrstic za obdelavo ali ustavi se ali konec ključne besede se izvajajo. Spodaj je prikazan zelo preprost program BASIC:

100 REM To je verjetno kanonični OSNOVNI primer programa 110 REM. Upoštevajte, da so stavki REM prezrti. 120 PRINT "To je testni program." 130 PRINT "Seštevanje vrednosti med 1 in 100" 140 LET skupaj = 0 150 FOR I = 1 DO 100 160 LET skupaj = skupaj + i 170 NEXT I 180 PRINT "Skupno število vseh številk med 1 in 100 je" skupaj 190 END 

Zgornje številke vrstic označujejo leksikalni vrstni red izjav. Ko se zaženejo, vrstici 120 in 130 natisneta sporočila na izhod, vrstica 140 inicializira spremenljivko, zanka v vrsticah od 150 do 170 pa posodobi vrednost te spremenljivke. Na koncu se rezultati natisnejo. Kot lahko vidite, je BASIC zelo preprost programski jezik in zato idealen kandidat za poučevanje računskih konceptov.

Organiziranje pristopa

Značilnost skriptnih jezikov je, da BASIC vključuje program, sestavljen iz številnih stavkov, ki se izvajajo v določenem okolju. Izziv oblikovanja je torej zgraditi predmete, da bi takšen sistem koristen za izvajanje.

Ko sem pogledal težavo, me je pošteno preskočila preprosta podatkovna struktura. Ta struktura je naslednja:

Javni vmesnik za skriptni jezik je sestavljen iz

  • Tovarniška metoda, ki vzame izvorno kodo kot vhod in vrne objekt, ki predstavlja program.
  • Okolje, ki zagotavlja okvir, v katerem se program izvaja, vključno z napravami za vnos / izhod besedila "I / O".
  • Standardni način spreminjanja tega predmeta, morda v obliki vmesnika, ki omogoča kombiniranje programa in okolja za doseganje koristnih rezultatov.

Notranjost je bila struktura tolmača nekoliko bolj zapletena. Vprašanje je bilo, kako se lotiti faktoringa dveh vidikov skriptnega jezika, razčlenjevanja in izvajanja? Nastale so tri skupine razredov - eden za razčlenjevanje, eden za strukturni okvir predstavljanja razčlenjenih in izvedljivih programov in tisti, ki je oblikoval osnovni razred okolja za izvajanje.

V skupini za razčlenjevanje so potrebni naslednji predmeti:

  • Leksikalna analiza za obdelavo kode kot besedila
  • Razčlenjevanje izrazov za izdelavo razčlenitve dreves izrazov
  • Razčlenjevanje stavkov za izdelavo razčlenitve dreves samih stavkov
  • Razredi napak za poročanje o napakah pri razčlenjevanju

Okvirno skupino sestavljajo predmeti, ki vsebujejo drevesa za razčlenitev in spremenljivke. Tej vključujejo:

  • Objekt stavka s številnimi specializiranimi podrazredi za predstavitev razčlenjenih stavkov
  • Predmet izraza, ki predstavlja izraze za ovrednotenje
  • Spremenljiv objekt s številnimi specializiranimi podrazredi za predstavitev atomskih primerkov podatkov
$config[zx-auto] not found$config[zx-overlay] not found