Pˇrekladaˇc a obfusk´ator ECMAScriptu Jan Pobˇr´ıslo - semestr´aln´ı pr´ace PJP
Zad´ an´ı Zad´an´ım semestr´ aln´ı pr´ ace je pˇrekladaˇc pro ECMAScript (v. 262) z jazyka rozˇs´ıˇren´eho o tˇr´ıdn´ı dˇedˇen´ı (ECMAScript pouˇz´ıv´a dˇedˇen´ı prototypov´e). Dalˇs´ım poˇzadavkem na pˇrekladaˇc je co nejkratˇs´ı v´ ystupn´ı k´od, s moˇzn´ ym nahrazen´ım jmen identifik´ator˚ u.
Implementace Obecnˇ e Semestr´aln´ı pr´ ace implementuje univerz´aln´ı tokenizer zaloˇzen´ y na stavov´em automatu. Jsou implementov´ any n´ asleduj´ıc´ı automaty: • lex js: Tokenizer dle standartu ECMA-262. • lex rules: Tokenizer pro specifikaci syntaktick´ ych pravidel. Semestr´ aln´ı pr´ ace implementuje univerz´aln´ı LL(1) pˇrekladaˇc pro definovanou gramatiku s automatick´ ym gener´ atorem rezkurzivn´ıho sestupu a podporou s´emantick´ ych pravidel. Syntaktick´ a pravidla mohou b´ yt zad´ana pˇr´ımo jako objekty pythonu nebo pomoc´ı speci´ aln´ıho jazyka pro zad´ av´an´ı syntaktick´ ych pravidel vˇcetnˇe s´emantiky.
Jazyk pro syntaktick´ a pravidla Jazyk pouˇz´ıv´ a bˇeˇznou formu z´ apisu syntaktick´ ych pravidel: Start -> Element1 Element2 Kaˇzd´e syntaktick´e pravidlo je ukonˇceno stˇredn´ıkem a za n´ım m˚ uˇze n´asledovat libovoln´ y poˇcet s´emantick´ ych pravidel.
1
S´ emantika Pravidla se zapisuj´ı ve formˇe pˇriˇrazen´ı: $Element1.atribut1 = $Element2.atribut2 $Element1.atribut1 = "python expression" Identifik´ atorem pro element m˚ uˇze b´ yt n´azev elementu, pokud je v pravidle jedineˇcn´ y, napˇr. $StringLiterar, nebo cel´e ˇc´ıslo urˇcen´e pozic´ı v pravidle. $0 je nejlevˇejˇs´ı expandovan´ y termin´ al / netermin´ al / v´ ystupn´ı symbol. Pro v´ ystup pravidla je urˇcen speci´aln´ı identifik´ator promˇenn´e $$ Elementy Jednotliv´e elementy syntaktick´ ych pravidel mohou b´ yt zaps´any pomoc´ı speci´aln´ı syntaxe pro zjednoduˇsen´ı s´emantick´ ych pravidel. • (Element) V´ ystupn´ı element. V okamˇziku kdyˇz se v´ ystupn´ı element dostnane na vrchol z´ asobn´ıku, je vyps´ an pomoc´ı funkce syntactical.Analyser.output(). • <Element> Rozp´ıˇse element jako bez z´avorek a v´ ysledek je jako v pˇredchoz´ım pˇr´ıpadˇe posl´ an na v´ ystup. • [Element] Rozp´ıˇse element jako bez z´avorek a v´ ysledek je nastaven jako n´avratov´a hodnota pravidla. Kaˇzd´ y element kter´ y obsahuje nealfanumerick´e znaky mus´ı b´ yt uzavˇren do uvozovek, napˇr. <")">. Zv´ yraznˇ en´ı syntaxe Vytvoˇril jsem soubor s jednoduch´ ym zv´ yraznˇen´ım syntaxe pro editor vim: rules.vim. Pravdˇepodobnˇe nejjednoduˇs´ı zp˚ usob jak zv´ yraznˇen´ı nainstalovat je zkop´ırovat ho do sloˇzky ~/.vim/syntax/ a pot´e pˇridat n´asleduj´ıc´ı ˇr´adek do souboru ~/.vim/filetype.vim: au BufNewFile,BufRead *.rules
setf rules
Implementace Parser pro syntaktick´ a pravidla jsem vytvoˇril syntaxi v pythonu a pro ovˇerˇen´ı i v novˇe vytvoˇren´em jazyce. V jazyce pro syntaktyck´a pravidla m´a t´emˇeˇr poloviˇcn´ı poˇcet ˇr´adek a je podstatnˇe pˇrehlednˇejˇs´ı. Implementace v jazyce pro syntaktick´a pravidla (soubor rules_test.rules): Rules ->; Rules ->
Rules; Rule -> Identifier "->" RuleNext ";" Semantic; $$ = "(r0,r2,r4)"
2
RuleNext ->; $$ = "[]" RuleNext -> RuleIdentifier RuleNext; $$ = "[r0]+r1" RuleIdentifier -> IdentifierExpression; $$ = "(r0,’normal’)" RuleIdentifier -> "(" IdentifierExpression ")"; $$ = "(r1,’out’)" RuleIdentifier -> "<" IdentifierExpression ">"; $$ = "(r1,’print’)" RuleIdentifier -> "[" IdentifierExpression "]"; $$ = "(r1,’return’)" IdentifierExpression -> [Identifier]; IdentifierExpression -> [Expression]; Semantic ->; $$ = "[]" Semantic -> LeftVariableField "=" VariableFieldOrExp Semantic; $$ = "[(r0,r2)]+r3" LeftVariableField -> LeftVariable [Field]; $Field.var = $LeftVariable LeftVariable -> [ReturnVariable]; LeftVariable -> [Variable]; Field ->; $$ = "(var,None)" Field -> "." Identifier; $$ = "(var,r1)" VariableFieldOrExp -> Variable [Field]; $Field.var = $Variable VariableFieldOrExp -> [Expression]; Variable -> [IndexVariable]; Variable -> [NameVariable]; Program podporuje automatick´e generov´an´ı diagram˚ u pro pravidla, viz soubor generate_dot.py. Zde je diagram pravidel a netermin´al˚ u pro jazyk syntaktick´ ych pravidel:
3
ECMAScript Parser je ˇreˇsen dle specifikace ECMA-262. Vynech´ an´ı ze specifikace Ze specifikace jsem vypustil mnoˇzinov´ y oper´ator in, jelikoˇz kv˚ uli konstruktu ’for ( LeftHandSideExpression in Expression ) Statement’ by byla nutn´a duplicita vˇetˇsiny pravidel ve variantˇe bez tohoto oper´ atoru. Viz pozn´amka v sekci 11.4 Relational Operators specifikace ECMAScriptu. D´ale specifikace urˇcuje automatick´e doplˇ nov´an´ı stˇredn´ık˚ u, viz 7.9.1 Rules of Automatic Semicolon Insertion. Tyto pravilda jsou pomˇernˇe koplexn´ı a nad r´amec semestr´aln´ı pr´ace. Funkce Semestr´aln´ı pr´ ace m´ a dvˇe rozd´ıln´e funkcionality:
4
• pˇreklad tˇr´ıd: program jsx • pˇreklad jmen identifik´ ator˚ u: program jsreplace Obˇe funkcionality jsou pomˇernˇe z´akladn´ı. Hlubˇs´ı anal´ yza jmen identifik´ator˚ u by byla pomˇernˇe n´ aroˇcn´ a kv˚ uli dynamick´e povaze jazyka. Tˇr´ıdn´ımu dˇedˇen´ı nyn´ı chyb´ı definice konstruktor˚ u, kter´e z ˇcasov´ ych d˚ uvod˚ u nejsem schopen implementovat.
Z´ avˇ er Funkcionalita pˇrekladaˇce je pomˇernˇe omezen´a, ale d´ıky jazyku pro specifikaci syntaktick´ ych pravidel je pomˇernˇe lehce rozˇs´ıˇriteln´a.
5