Programovanie

Ako zostaviť tlmočník v prostredí Java, časť 1: ZÁKLADY

Keď som povedal priateľovi, že som napísal tlmočníka BASIC v Jave, zasmial sa tak silno, že takmer vylial sódu, ktorú držal, na celé oblečenie. „Prečo by ste na svete stavali tlmočník BASIC v Jave?“ bola predvídateľná prvá otázka z jeho úst. Odpoveď je jednoduchá a zložitá. Jednoduchá odpoveď je, že bolo zábavné písať tlmočníka v Jave, a keby som mal písať tlmočníka, mohol by som napísať taký, na ktorý mám pekné spomienky z počiatkov osobného používania počítača. Po komplexnej stránke som si všimol, že mnoho ľudí, ktorí dnes používajú Javu, sa dostali cez hranicu vytvárania bubnujúcich appletov Duke a prechádzajú k vážnym aplikáciám. Pri vytváraní aplikácie by ste často chceli, aby bola konfigurovateľná. Mechanizmus voľby pre opätovnú konfiguráciu je akýsi druh dynamického spúšťacieho nástroja.

Známe ako jazyky jazykov alebo konfiguračné jazyky, dynamické vykonávanie je funkcia, ktorá umožňuje používateľovi „naprogramovať“ aplikáciu. Výhodou nástroja na dynamické vykonávanie je, že nástroje a aplikácie je možné prispôsobiť tak, aby vykonávali zložité úlohy bez výmeny nástroja. Platforma Java ponúka širokú škálu možností dynamického spúšťacieho modulu.

HotJava a ďalšie horúce možnosti

Poďme v krátkosti preskúmať niektoré dostupné možnosti dynamického spúšťacieho modulu a potom sa pozrieme do hĺbky na implementáciu môjho tlmočníka. Nástroj na dynamické vykonávanie je zabudovaný tlmočník. Tlmočník potrebuje na svoju činnosť tri vybavenie:

  1. Prostriedok na načítanie pokynov
  2. Formát modulu na ukladanie pokynov, ktoré sa majú vykonať
  3. Model alebo prostredie pre interakciu s hostiteľským programom

HotJava

Najznámejším vloženým tlmočníkom musí byť prostredie „appletu“ HotJava, ktoré úplne zmenilo pohľad ľudí na webové prehliadače.

„Appletový“ model HotJava bol založený na predstave, že aplikácia Java dokáže vytvoriť všeobecnú základnú triedu so známym rozhraním a potom dynamicky načítať podtriedy tejto triedy a spúšťať ich za behu programu. Tieto applety poskytovali nové funkcie a v medziach základnej triedy poskytovali dynamické vykonávanie. Táto schopnosť dynamického vykonávania je základnou súčasťou prostredia Java a jednou z vecí, ktoré ho robia takým zvláštnym. Na toto konkrétne prostredie sa pozrieme podrobnejšie v neskoršom stĺpci.

GNU EMACS

Pred príchodom HotJava bola asi najúspešnejšia aplikácia s dynamickým spustením GNU EMACS. Makro jazyk podobný LISP tohto editora sa stal základom mnohých programátorov. Stručne povedané, prostredie EMACS LISP pozostáva z tlmočníka LISP a mnohých funkcií typu úprav, ktoré možno použiť na zostavenie najkomplexnejších makier. Nemalo by byť prekvapujúce, že editor EMACS bol pôvodne napísaný v makrách určených pre editora s názvom TECO. Dostupnosť bohatého (ak nečitateľného) jazyka makra v TECO teda umožnila vytvorenie úplne nového editora. Dnes je GNU EMACS základným editorom a celé hry nie sú napísané ničím iným ako kódom EMACS LISP, známym ako el-code. Vďaka tejto konfiguračnej schopnosti sa GNU EMACS stal hlavným editorom, zatiaľ čo terminály VT-100, na ktorých bol navrhnutý, sa stali iba poznámkami pod čiarou v stĺpci spisovateľa.

REXX

Jedným z mojich obľúbených jazykov, ktorý nikdy nezískal taký rozruch, aký si zaslúži, bol REXX, ktorý navrhol Mike Cowlishaw z IBM. Spoločnosť potrebovala jazyk na riadenie aplikácií na veľkých sálových počítačoch s operačným systémom VM. REXX som objavil na Amige, kde bol úzko spojený so širokou škálou aplikácií cez „porty REXX“. Tieto porty umožňovali vzdialenú správu aplikácií pomocou tlmočníka REXX. Toto spojenie tlmočníka a aplikácie vytvorilo oveľa výkonnejší systém, ako bolo možné s jeho komponentmi. Našťastie jazyk žije v NETREXX, verzii, ktorú napísal Mike a ktorá bola skompilovaná do kódu Java.

Keď som sa díval na NETREXX a oveľa starší jazyk (LISP v Jave), napadlo ma, že tieto jazyky tvorili dôležitú súčasť príbehu aplikácií Java. Aký lepší spôsob, ako povedať túto časť príbehu, ako robiť tu niečo zábavné - napríklad vzkriesiť BASIC-80? Dôležitejšie je, že by bolo užitočné ukázať jeden spôsob, ako možno písať skriptovacie jazyky v jazyku Java, a prostredníctvom ich integrácie s jazykom Java ukázať, ako môžu vylepšiť možnosti vašich aplikácií Java.

ZÁKLADNÉ požiadavky na vylepšenie vašich aplikácií Java

BASIC je, jednoducho, základný jazyk. Existujú dva myšlienkové prúdy, ako by sa dalo pripraviť na tlmočenie. Jedným z prístupov je napísanie programovacej slučky, v ktorej tlmočnícky program načíta jeden riadok textu z interpretovaného programu, analyzuje ho a potom zavolá podprogram, ktorý ho vykoná. Postupnosť čítania, syntaktickej analýzy a vykonávania sa opakuje, kým jeden z príkazov interpretovaného programu nepovie tlmočníkovi, aby sa zastavil.

Druhým a oveľa zaujímavejším spôsobom riešenia tohto projektu je syntaktická analýza jazyka do stromu syntaktickej analýzy a potom jeho vykonanie „na mieste“. Takto fungujú tokenizační tlmočníci a spôsob, akým som sa rozhodol postupovať. Tokenizační tlmočníci sú tiež rýchlejší, pretože nepotrebujú znovu skenovať vstup zakaždým, keď vykonajú príkaz.

Ako som už spomenul vyššie, tri komponenty potrebné na dosiahnutie dynamického vykonávania sú prostriedok načítania, formát modulu a prostredie vykonávania.

Prvý komponent, prostriedok na načítanie, bude spracovaný prostredím Java InputStream. Pretože vstupné toky sú základom v I / O architektúre Java, systém je navrhnutý na čítanie v programe z InputStream a previesť ho do spustiteľnej formy. To predstavuje veľmi flexibilný spôsob vkladania kódu do systému. Samozrejme, protokolom pre údaje prechádzajúce vstupným prúdom bude ZÁKLADNÝ zdrojový kód. Je dôležité poznamenať, že je možné použiť akýkoľvek jazyk; neurobte chybu, keď si myslíte, že túto techniku ​​nie je možné na vašu aplikáciu použiť.

Po zadaní zdrojového kódu interpretovaného programu do systému systém prevedie zdrojový kód na internú reprezentáciu. Ako interný formát reprezentácie pre tento projekt som sa rozhodol použiť syntaktický strom. Po vytvorení syntaktického stromu s ním možno manipulovať alebo ho vykonať.

Treťou zložkou je prostredie vykonávania. Ako uvidíme, požiadavky na tento komponent sú pomerne jednoduché, ale implementácia má niekoľko zaujímavých zvratov.

Veľmi rýchla ZÁKLADNÁ prehliadka

Pre tých z vás, ktorí ste možno nikdy nepočuli o jazyku BASIC, vám poskytnem krátky letmý pohľad na jeho jazyk, aby ste mohli porozumieť budúcim výzvam pri analýze a vykonávaní. Ak chcete získať viac informácií o jazyku BASIC, vrelo odporúčam zdroje na konci tohto stĺpca.

BASIC je skratka pre Symbolický inštruktážny kód pre začiatočníkov. Bol vyvinutý na univerzite v Dartmouthe za účelom výučby výpočtových koncepcií pre vysokoškolských študentov. Od svojho vývoja sa BASIC vyvinul do rôznych dialektov. Najjednoduchšie z týchto dialektov sa používajú ako riadiace jazyky pre radiče priemyselných procesov; najkomplexnejšie dialekty sú štruktúrované jazyky, ktoré obsahujú niektoré aspekty objektovo orientovaného programovania. Pre svoj projekt som si vybral dialekt známy ako BASIC-80, ktorý bol na konci sedemdesiatych rokov populárny v operačnom systéme CP / M. Tento dialekt je len mierne zložitejší ako najjednoduchšie dialekty.

Syntax výpisu

Všetky riadky príkazu sú formulára

[ : [ : ... ] ]

kde „Riadok“ je číslo riadku príkazu, „Kľúčové slovo“ je kľúčové slovo príkazu BASIC a „Parametre“ predstavuje množinu parametrov spojených s týmto kľúčovým slovom.

Číslo riadku má dva účely: Slúži ako štítok pre príkazy, ktoré riadia tok vykonania, ako napríklad a ísť do príkaz a slúži ako triediaca značka pre príkazy vložené do programu. Ako značka na triedenie uľahčuje číslo riadku prostredie na úpravu riadkov, v ktorom sa úpravy a spracovanie príkazov zmiešajú v jednej interaktívnej relácii. Mimochodom, toto sa vyžadovalo, keď ste mali iba typ písma. :-)

Aj keď to nie je veľmi elegantné, čísla riadkov dávajú prostrediu tlmočníka možnosť aktualizovať program po jednom príkaze. Táto schopnosť vyplýva zo skutočnosti, že príkaz je jediná analyzovaná entita a môže byť v dátovej štruktúre prepojený s číslami riadkov. Bez čísel riadkov je často potrebné pri zmene riadku znova analyzovať celý program.

Kľúčové slovo identifikuje príkaz BASIC. V tomto príklade bude náš tlmočník podporovať mierne rozšírenú sadu základných kľúčových slov vrátane ísť do, gosub, návrat, tlačiť, ak, koniec, údaje, obnoviť, čítať, na, rem, pre, Ďalšie, nechajme, vstup, prestaň, dim, náhodne, trona troff. Je zrejmé, že v tomto článku sa nebudeme podrobne zaoberať všetkými týmito témami, ale v mojej dokumentácii „Java In Depth“, ktorá sa bude konať môj budúci mesiac, môžete preskúmať niektoré dokumentácie.

Každé kľúčové slovo má súbor legálnych parametrov kľúčového slova, ktoré ho môžu nasledovať. Napríklad ísť do za kľúčovým slovom musí nasledovať číslo riadku, znak ak za príkazom musí nasledovať podmienený výraz, ako aj kľúčové slovo potom -- a tak ďalej. Parametre sú špecifické pre každé kľúčové slovo. O pár týchto zoznamov parametrov sa podrobnejšie zmienim neskôr.

Výrazy a operátory

Parameter uvedený vo vyhlásení je často výraz. Verzia BASIC, ktorú tu používam, podporuje všetky štandardné matematické operácie, logické operácie, umocňovanie a knižnicu jednoduchých funkcií. Najdôležitejšou súčasťou gramatiky výrazu je schopnosť volať funkcie. Samotné výrazy sú pomerne štandardné a podobné tým, ktoré sú analyzované príkladom v mojom predchádzajúcom stĺpci StreamTokenizer.

Premenné a typy údajov

Jedným z dôvodov, prečo je jazyk BASIC taký jednoduchý jazyk, je ten, že má iba dva dátové typy: čísla a reťazce. Niektoré skriptovacie jazyky, napríklad REXX a PERL, nerozlišujú medzi dátovými typmi, kým sa nepoužívajú. Ale s programom BASIC sa na identifikáciu dátových typov používa jednoduchá syntax.

Názvy premenných v tejto verzii jazyka BASIC sú reťazce písmen a číslic, ktoré sa vždy začínajú písmenom. Premenné nerozlišujú veľké a malé písmená. Takže A, B, FOO a FOO2 sú všetky platné názvy premenných. Ďalej je v BASICe premenná FOOBAR ekvivalentná FooBaru. Na identifikáciu reťazcov je k názvu premennej pripojený znak dolára ($); teda premenná FOO $ je premenná obsahujúca reťazec.

Nakoniec táto verzia jazyka podporuje polia používajúce dim kľúčové slovo a premenná syntax formulára NÁZOV (index1, index2, ...) až pre štyri indexy.

Štruktúra programu

Programy v ZÁKLADNOM programe sa predvolene spúšťajú od najnižšie očíslovaného riadku a pokračujú, kým už nebudú ďalšie riadky na spracovanie alebo prestaň alebo koniec kľúčové slová sa vykonajú. Veľmi jednoduchý program BASIC je uvedený nižšie:

100 REM Toto je pravdepodobne kanonický ZÁKLADNÝ príklad 110 programu REM. Upozorňujeme, že príkazy REM sú ignorované. 120 TLAČ „Toto je testovací program.“ 130 TLAČ "Sčítanie hodnôt medzi 1 a 100" 140 LET celkom = 0 150 PRE I = 1 AŽ 100 160 LET celkom = spolu + i 170 ĎALŠIE I 180 TLAČ "Celkom všetkých číslic medzi 1 a 100 je" celkom 190 KONIEC 

Čísla riadkov vyššie označujú lexikálne poradie výrokov. Keď sú spustené, riadky 120 a 130 tlačia správy na výstup, riadok 140 inicializuje premennú a slučka v riadkoch 150 až 170 aktualizuje hodnotu tejto premennej. Nakoniec sa výsledky vytlačia. Ako vidíte, BASIC je veľmi jednoduchý programovací jazyk, a preto je ideálnym kandidátom na výučbu výpočtových koncepcií.

Organizácia prístupu

Typické pre skriptovacie jazyky, BASIC zahŕňa program zložený z mnohých príkazov, ktoré sa spúšťajú v konkrétnom prostredí. Výzvou v oblasti dizajnu je potom postaviť objekty tak, aby takýto systém mohli implementovať užitočným spôsobom.

Keď som sa pozrel na problém, spravodlivo na mňa vyskočila priama dátová štruktúra. Táto štruktúra je nasledovná:

Verejné rozhranie pre skriptovací jazyk musí pozostávať z

  • Továrna metóda, ktorá berie ako vstup zdrojový kód a vracia objekt predstavujúci program.
  • Prostredie, ktoré poskytuje rámec, v ktorom sa program vykonáva, vrátane zariadení „I / O“ na zadávanie a výstup textu.
  • Štandardný spôsob úpravy tohto objektu, možno vo forme rozhrania, ktorý umožňuje kombinovať program a prostredie s cieľom dosiahnuť užitočné výsledky.

Vnútorne bola štruktúra tlmočníka o niečo komplikovanejšia. Otázkou bolo, ako postupovať pri zohľadňovaní dvoch aspektov skriptovacieho jazyka, analýze a vykonávaní? Výsledkom boli tri skupiny tried - jedna pre syntaktickú analýzu, druhá pre štrukturálny rámec reprezentácie analyzovaných a spustiteľných programov a druhá, ktorá tvorila základnú triedu prostredia pre vykonávanie.

V skupine analýzy sú požadované nasledujúce objekty:

  • Lexikálna analýza na spracovanie kódu ako textu
  • Analýza výrazov, na zostavenie analyzovaných stromov výrazov
  • Parsing Statement, to construct parse Stromy samotných príkazov
  • Triedy chýb pre hlásenie chýb pri analýze

Skupina rámcov sa skladá z objektov, ktoré obsahujú parsovacie stromy a premenné. Tie obsahujú:

  • Objekt vyhlásenia s mnohými špecializovanými podtriedami, ktoré predstavujú analyzované príkazy
  • Objekt výrazu, ktorý predstavuje výrazy na vyhodnotenie
  • Variabilný objekt s mnohými špecializovanými podtriedami, ktoré predstavujú atómové inštancie údajov
$config[zx-auto] not found$config[zx-overlay] not found