Programmēšana

Kā izveidot tulku Java, 1. daļa: PAMATI

Kad es teicu draugam, ka es Java valodā esmu uzrakstījis BASIC tulku, viņš tik smējās, ka gandrīz izlēja sodas, kuru viņš turēja, pa visām drēbēm. "Kāpēc pasaulē jūs Java būvētu BASIC tulku?" bija paredzamais pirmais jautājums no viņa mutes. Atbilde ir vienkārša un sarežģīta. Vienkāršā atbilde ir tāda, ka bija jautri rakstīt tulku Java valodā, un, ja es gatavotos rakstīt tulku, es tikpat labi varētu uzrakstīt tādu, par kuru man ir patīkamas atmiņas kopš personīgās skaitļošanas sākuma. Sarežģītajā pusē es pamanīju, ka daudzi cilvēki, kas mūsdienās izmanto Java, ir pārgājuši no tumsas, kas rada krītošos Duke sīklietotnes, un pāriet uz nopietnām lietojumprogrammām. Bieži vien, veidojot lietojumprogrammu, jūs vēlētos, lai to varētu konfigurēt. Pārkonfigurācijas izvēles mehānisms ir kaut kāds dinamiskas izpildes dzinējs.

Pazīstama kā makro valodas vai konfigurācijas valodas, dinamiska izpilde ir funkcija, kas ļauj lietotājam "ieprogrammēt" lietojumprogrammu. Dinamiskas izpildes dzinēja priekšrocība ir tā, ka rīkus un lietojumprogrammas var pielāgot sarežģītu uzdevumu veikšanai, neaizstājot rīku. Java platforma piedāvā plašu dinamisko izpildes dzinēju iespēju klāstu.

HotJava un citas karstas iespējas

Īsi izpētīsim dažas no pieejamajām dinamiskās izpildes dzinēja opcijām un pēc tam padziļināti aplūkosim mana tulka ieviešanu. Dinamiskas izpildes dzinējs ir iegultais tulks. Tulka darbībai nepieciešamas trīs iespējas:

  1. Līdzeklis, kā ielādēt instrukcijas
  2. Moduļa formāts izpildāmo instrukciju glabāšanai
  3. Modelis vai vide mijiedarbībai ar resursdatora programmu

HotJava

Slavenākajam iegultajam tulkotājam ir jābūt HotJava "sīklietotņu" videi, kas ir pilnībā pārveidojusi to, kā cilvēki skatās uz tīmekļa pārlūkiem.

HotJava "sīklietotnes" modeļa pamatā bija uzskats, ka Java lietojumprogramma var izveidot vispārēju bāzes klasi ar zināmu saskarni un pēc tam dinamiski ielādēt šīs klases apakšklases un izpildīt tās izpildes laikā. Šīs sīklietotnes nodrošināja jaunas iespējas un bāzes klases robežās nodrošināja dinamisku izpildi. Šī dinamiskās izpildes spēja ir būtiska Java vides sastāvdaļa un viena no lietām, kas to padara tik īpašu. Mēs aplūkosim šo konkrēto vidi padziļināti vēlākā slejā.

GNU EMACS

Pirms HotJava ierašanās, iespējams, visveiksmīgākā lietojumprogramma ar dinamisku izpildi bija GNU EMACS. Šī redaktora LISP līdzīgā makro valoda daudziem programmētājiem ir kļuvusi par galveno. Īsāk sakot, EMACS LISP vide sastāv no LISP tulka un daudzām rediģēšanas veida funkcijām, kuras var izmantot, lai sastādītu vissarežģītākos makro. Nevajadzētu uzskatīt par pārsteidzošu faktu, ka EMACS redaktors sākotnēji tika rakstīts makros, kas paredzēti redaktoram ar nosaukumu TECO. Tādējādi bagātīgas (ja nelasāmas) makro valodas pieejamība TECO ļāva izveidot pilnīgi jaunu redaktoru. Mūsdienās GNU EMACS ir bāzes redaktors, un visas spēles ir rakstītas tikai ar EMACS LISP kodu, kas pazīstams kā el-kods. Šī konfigurācijas spēja ir padarījusi GNU EMACS par galvenā redaktoru, savukārt VT-100 termināļi, ar kuriem tā bija paredzēta darbībai, ir kļuvuši tikai par zemsvītras piezīmēm rakstnieka slejā.

REXX

Viena no manām iecienītākajām valodām, kas nekad nepadarīja pelnīto šļakatu, bija REXX, ko izstrādājis Maiks Kovlishavs no IBM. Uzņēmumam bija nepieciešama valoda, lai kontrolētu lietojumprogrammas lielos lieldatoros, kuros darbojas VM operētājsistēma. Es atklāju REXX Amiga, kur tas bija cieši savienots ar visdažādākajām lietojumprogrammām, izmantojot "REXX porti". Šīs porti ļāva vadīt lietojumprogrammas attālināti, izmantojot REXX tulku. Šī tulka un lietojumprogrammas savienošana radīja daudz jaudīgāku sistēmu, nekā tas bija iespējams ar tā sastāvdaļām. Par laimi, valoda dzīvo NETREXX - versijā, kuru Maiks uzrakstīja un kas tika apkopota Java kodā.

Kad es skatījos NETREXX un daudz agrāku valodu (LISP Java valodā), man šķita, ka šīs valodas veido svarīgas Java lietojumprogrammas stāsta daļas. Kā gan labāk izstāstīt šo stāsta daļu, nekā šeit izdarīt kaut ko jautru - piemēram, atdzīvināt BASIC-80? Vēl svarīgāk ir tas, ka būtu lietderīgi parādīt vienu veidu, kā skriptu valodas var rakstīt Java valodā, un, integrējot tās ar Java, parādīt, kā tās var uzlabot jūsu Java lietojumprogrammu iespējas.

Pamata prasības jūsu Java lietotņu uzlabošanai

BASIC ir pavisam vienkārša pamatvaloda. Ir divas domu skolas par to, kā varētu rakstīt tulku. Viena pieeja ir uzrakstīt programmēšanas cilpu, kurā tulka programma nolasa no interpretētās programmas vienu teksta rindu, parsē to un pēc tam izsauc apakšprogrammu, lai to izpildītu. Lasīšanas, parsēšanas un izpildes secība tiek atkārtota, līdz kāds no interpretētās programmas izteikumiem liek tulkotājam apstāties.

Otrais un daudz interesantākais veids, kā īstenot projektu, faktiski ir parsēt valodu parsēšanas kokā un pēc tam izpildīt parsēšanas koku "vietā". Tā darbojas tulkotāju marķēšana un veids, kā es izvēlējos turpināt. Tulkotāju marķēšana ir arī ātrāka, jo viņiem nav nepieciešams atkārtoti skenēt ievadi katru reizi, kad viņi izpilda paziņojumu.

Kā jau minēju iepriekš, trīs komponenti, kas nepieciešami dinamiskas izpildes sasniegšanai, ir ielādes līdzekļi, moduļa formāts un izpildes vide.

Pirmo komponentu, kas ir ielādes līdzeklis, veiks Java InputStream. Tā kā ievades plūsmām ir būtiska nozīme Java I / O arhitektūrā, sistēma ir paredzēta lasīšanai programmā no InputStream un pārveidojiet to izpildāmā formā. Tas ir ļoti elastīgs veids, kā ievadīt kodu sistēmā. Protams, datu protokols, kas iet pa ievades straumi, būs PAMATTEKSTS. Ir svarīgi atzīmēt, ka var izmantot jebkuru valodu; nepieļaujiet kļūdu, domājot, ka šo paņēmienu nevar piemērot jūsu lietojumprogrammai.

Pēc tam, kad interpretētās programmas pirmkods ir ievadīts sistēmā, sistēma avota kodu pārveido par iekšēju attēlojumu. Es izvēlējos parsēšanas koku izmantot kā iekšējo attēlojuma formātu šim projektam. Kad parsēšanas koks ir izveidots, to var manipulēt vai izpildīt.

Trešais komponents ir izpildes vide. Kā mēs redzēsim, prasības šim komponentam ir diezgan vienkāršas, taču ieviešanai ir pāris interesanti pavērsieni.

Ļoti ātra BASIC tūre

Tiem no jums, kuri, iespējams, nekad nav dzirdējuši par BASIC, es jums īsumā ieskatu valodu, lai jūs varētu saprast gaidāmās parsēšanas un izpildes problēmas. Lai iegūtu papildinformāciju par BASIC, es ļoti iesaku resursus šīs slejas beigās.

BASIC nozīmē Beginners All-purpose Symbolic Instructional Code, un tas tika izstrādāts Dartmutas universitātē, lai mācītu skaitļošanas koncepcijas bakalaura studentiem. Kopš tās attīstības BASIC ir pārtapis dažādos dialektos. Vienkāršākie no šiem dialektiem tiek izmantoti kā vadības valodas rūpniecisko procesu kontrolieriem; vissarežģītākie dialekti ir strukturētas valodas, kurās iekļauti daži objektorientētās programmēšanas aspekti. Savam projektam es izvēlējos dialektu, kas pazīstams kā BASIC-80 un kas septiņdesmito gadu beigās bija populārs operētājsistēmā CP / M. Šis dialekts ir tikai mēreni sarežģītāks nekā vienkāršākie dialekti.

Izraksta sintakse

Visas paziņojuma rindas ir formas

[ : [ : ... ] ]

kur "Līnija" ir izraksta rindas numurs, "Atslēgvārds" ir BASIC priekšraksta atslēgvārds un "Parametri" ir parametru kopa, kas saistīta ar šo atslēgvārdu.

Rindas numuram ir divi mērķi: tas kalpo kā etiķete paziņojumiem, kas kontrolē izpildes plūsmu, piemēram, a iet uz paziņojumu, un tas kalpo kā šķirošanas tags programmās ievietotajiem paziņojumiem. Kā šķirošanas tags līnijas numurs atvieglo līnijas rediģēšanas vidi, kurā rediģēšana un komandu apstrāde tiek sajaukta vienā interaktīvā sesijā. Starp citu, tas bija nepieciešams, kad viss, kas jums bija, bija teletips. :-)

Lai gan tas nav ļoti elegants, līniju numuri tulka videi dod iespēju atjaunināt programmu pa vienam. Šī spēja izriet no fakta, ka paziņojums ir viena parsēta entītija un datu struktūrā to var saistīt ar rindu numuriem. Bez līniju numuriem, mainoties līnijai, bieži vien ir nepieciešams parsēt visu programmu.

Atslēgvārds identificē paziņojumu BASIC. Šajā piemērā mūsu tulks atbalstīs nedaudz paplašinātu BASIC atslēgvārdu kopu, ieskaitot iet uz, gosub, atgriešanās, izdrukāt, ja, beigas, dati, atjaunot, lasīt, ieslēgts, rem, priekš, Nākamais, ļaujiet, ievade, apstāties, blāvs, nejaušināt, trons, un trofs. Acīmredzot mēs nepārskatīsim visus šos šajā rakstā, bet mana dokumenta nākamā mēneša "Java dziļumā" tiešsaistē būs daži dokumenti.

Katram atslēgvārdam ir likumīgu atslēgvārdu parametru kopums, kas tam var sekot. Piemēram, iet uz pēc atslēgvārda jāievada rindas numurs - ja paziņojumam jāseko nosacītai izteiksmei, kā arī atslēgvārdam pēc tam -- un tā tālāk. Parametri ir raksturīgi katram atslēgvārdam. Pāris no šiem parametru sarakstiem es detalizēti apskatīšu mazliet vēlāk.

Izteiksmes un operatori

Bieži vien paziņojumā norādītais parametrs ir izteiksme. Šeit izmantotā BASIC versija atbalsta visas standarta matemātiskās darbības, loģiskās darbības, eksponenci un vienkāršu funkciju bibliotēku. Izteiksmes gramatikas vissvarīgākā sastāvdaļa ir spēja izsaukt funkcijas. Paši izteicieni ir diezgan standarta un līdzīgi tiem, kas parsēti manā iepriekšējā StreamTokenizer slejā.

Mainīgie un datu veidi

Daļa no iemesla, kāpēc BASIC ir tik vienkārša valoda, ir tāpēc, ka tajā ir tikai divi datu tipi: skaitļi un virknes. Dažas skriptu valodas, piemēram, REXX un PERL, pat nenodala šo datu tipu, kamēr tie netiek izmantoti. Bet, izmantojot BASIC, datu tipu identificēšanai tiek izmantota vienkārša sintakse.

Mainīgie nosaukumi šajā BASIC versijā ir burtu un ciparu virknes, kas vienmēr sākas ar burtu. Mainīgie nav reģistrjutīgi. Tādējādi A, B, FOO un FOO2 ir derīgi mainīgo nosaukumi. Turklāt BASIC mainīgais FOOBAR ir ekvivalents FooBar. Lai identificētu virknes, mainīgā nosaukumam tiek pievienota dolāra zīme ($); tādējādi mainīgais FOO $ ir mainīgais, kas satur virkni.

Visbeidzot, šī valodas versija atbalsta masīvus, izmantojot blāvs atslēgvārds un mainīga sintakse formā NAME (indekss1, indekss2, ...) līdz četriem indeksiem.

Programmas struktūra

Programmas BASIC programmā pēc noklusējuma sākas ar zemāko numurēto rindu un turpinās, līdz vairs nav vai nav vairāk apstrādājamo rindu apstāties vai beigas atslēgvārdi tiek izpildīti. Zemāk parādīta ļoti vienkārša BASIC programma:

100 REM Tas, iespējams, ir kanoniskais BASIC 110 REM programmas piemērs. Ņemiet vērā, ka REM paziņojumi tiek ignorēti. 120 PRINT "Šī ir testa programma." 130 PRINT "Apkopojot vērtības starp 1 un 100" 140 LET kopā = 0 150 FOR I = 1 līdz 100 160 LET kopā = kopā + i 170 NEXT I 180 PRINT "Visu ciparu no 1 līdz 100 kopsumma ir" kopā 190 END 

Rindu numuri iepriekš norāda apgalvojumu leksisko secību. Kad tie tiek palaisti, 120. un 130. rinda izdrukā ziņojumus izvadē, 140. rinda inicializē mainīgo, un cilpa 150. līdz 170. līnijā atjaunina šī mainīgā vērtību. Visbeidzot, rezultāti tiek izdrukāti. Kā redzat, BASIC ir ļoti vienkārša programmēšanas valoda un tāpēc ideāls kandidāts skaitļošanas jēdzienu pasniegšanai.

Pieejas organizēšana

Parasti skriptu valodās BASIC ietver programmu, kas sastāv no daudziem paziņojumiem, kas darbojas noteiktā vidē. Dizaina izaicinājums ir objektu konstruēšana, lai lietderīgi ieviestu šādu sistēmu.

Kad es paskatījos uz problēmu, man diezgan izlēca vienkārša datu struktūra. Šī struktūra ir šāda:

Publiskā saskarne ar skriptu valodu sastāv no

  • Rūpnīcas metode, kas avota kodu izmanto kā ievadi un atgriež objektu, kas pārstāv programmu.
  • Vide, kas nodrošina ietvaru, kurā programma tiek izpildīta, ieskaitot "I / O" ierīces teksta ievadei un teksta izvadei.
  • Standarta veids, kā modificēt šo objektu, iespējams, saskarnes veidā, kas ļauj apvienot programmu un vidi, lai sasniegtu noderīgus rezultātus.

Iekšēji tulka struktūra bija nedaudz sarežģītāka. Jautājums bija par to, kā rīkoties, ņemot vērā abus skriptu valodas aspektus - parsēšanu un izpildi? Rezultātā tika izveidotas trīs klašu grupas - viena parsēšanai, viena strukturētajai struktūrai, kurā attēlotas parsētas un izpildāmas programmas, un viena, kas veidoja bāzes vides klasi izpildei.

Parsēšanas grupā ir nepieciešami šādi objekti:

  • Leksiskā analīze koda apstrādei tekstā
  • Izteiksmes parsēšana, lai izveidotu izteiksmju parsēšanas kokus
  • Pārskatu parsēšana, lai izveidotu pašu izteikumu parsēšanas kokus
  • Kļūdu klases ziņošanai par kļūdām parsējot

Ietvara grupu veido objekti, kas satur parsēšanas kokus un mainīgos. Tie ietver:

  • Izraksta objekts ar daudzām specializētām apakšklasēm, lai attēlotu parsētus priekšrakstus
  • Izteiksmes objekts, kas pārstāv izteicienus novērtēšanai
  • Mainīgs objekts ar daudzām specializētām apakšklasēm, lai attēlotu datu atomu gadījumus
$config[zx-auto] not found$config[zx-overlay] not found