Limbajul extensibil
|
"A cunoaste o limba nu este totul. Mai trebuie sa ai si ceva de spus."
Acest capitol contine: surse de inspiratie in proiectarea unui nou limbaj de programare, descrierea sintactica a limbajului LEDA utilizind EBNF, semantica instructiunilor de baza ale limbajului, modul in care se definesc extendorii in LEDA si exemple de programe sursa scrise in LEDA.
Inainte de a concepe un nou limbaj de programare trebuie avute in vedere urmatoarele aspecte:
Obiectivul unui proiectant de limbaj este, prin urmare, acela de a crea un limbaj facil pentru utilizator, cit mai puternic, clar din punctul de vedere al redactarii, simplu de inteles, posedind avansate mecanisme de detectie a erorilor. Vor trebui, asadar, folosite structuri si notatii apropiate de limbajul utilizatorului, indiferent daca limbajul de programare e specializat sau nu. Astfel vom asista la o minimizare a efortului de programare si la o invatare mult mai rapida a acestui limbaj.
Surse de idei:
Limbajele de programare trebuie sa posede anumite caracteristici astfel incit sa fie acceptate de potentialii utilizatori. Ele vor folosi, pe cit posibil, cuvinte rezervate al caror inteles e larg cunoscut, fara a genera dubii. Sintaxa trebuie sa aiba constructii convenabile, clare si sa reflecte semantica, in sensul ca sintaxa va urmari sabloanele gindirii umane, programatorul prevazind comportamentul unei instructiuni doar stiindu-i numele. Limbajele trebuiesc a fi facil de utilizat, concise, cu reguli usor de retinut.
Urmarind paradigmele programarii structurate, limbajele vor oferi mecanisme de abstractizare, de ascundere a informatiilor, de modularitate. In plus, se vor evita aparitia erorilor si pierderea de timp pentru corectare. Erorile se vor evidentia intr-un mod precis ( localizare, tip, mesaje explicative ) si se vor propune metode de corectare.
Un alt aspect este acela al portabilitatii si independentei de periferice. E bine ca metodele de procesare a intrarilor si iesirilor ( atit la nivel inalt, cit si la nivel apropiat de hardware ) sa fie scoase in afara limbajului de programare, asa cum se intimpla la limbajele C si C++.
In concluzie, proiectantul unui limbaj de programare trebuie sa aiba in vedere aspecte multiple pentru a inventa un limbaj de programare ( extensibil ) cu adevarat eficient si folositor.
LEDA este:
int
), boolean
( bool
) si caracter ( char
), iar ca
instructiuni initiale: asignarea, while, if,
primitive de intrare/iesire ( read
si
write
),
Sintaxa limbajului:
- letter ::= A | B | ... | Z | a | b | ... | z
- digit ::= 0 | 1 | ... | 9
- punct ::= + | - | * | / | % | \ | # | $ | . | , | : | ; | _ | = |
< | > | ! | ? | ' | " | ( | ) | [ | ] | { | } | &
- text ::= { letter | digit | punct |
space }
- a_op ::= + | - | / | %
- b_op2 ::= and | or
- b_op1 ::= not
- space ::= _
- r_op ::= < | > | =
- b_cst ::= false | true
- c_cst ::= 'letter' | 'digit' | 'punct' |
'space'
- ident ::= letter { letter | digit }
- u_number ::= { digit }
- number ::= + u_number | - u_number |
u_number
- i_exp ::= number | i_exp a_op i_exp |
i_var | ( i_exp )
- b_exp ::= b_cst | b_exp b_op2 b_exp |
b_op1 b_exp | ( b_exp ) | b_var
- c_exp ::= c_cst | c_var | ( c_exp )
- r_exp ::= b_exp | i_exp r_op i_exp |
c_exp r_op c_exp
- var ::= i_var | c_var | b_var
- i_var ::= i_vars | i_varc
- b_var ::= b_vars | b_varc
- c_var ::= c_vars | c_varc
- i_vars ::= ident
- i_varc ::= ident { [ i_exp ] }
- b_vars ::= ident
- b_varc ::= ident { [ i_exp ] }
- c_vars ::= ident
- c_varc ::= ident { [ i_exp ] }
- stat ::= { assign | if | while |
read | write | note }
- assign ::= i_var := i_exp | b_var :=
b_exp | c_var := c_exp
- if ::= if r_exp then stat else
stat fi | if r_exp then stat
fi
- while ::= while r_exp do stat
od
- read ::= read var
- write ::= write var
- note ::= note text
- decl ::= { ident : type }
- type ::= simple | compose
- simple ::= int | char | bool
- compose ::= array[ u_number ] of
type
- use_ext ::= { ident }
- prog ::= prog ident use_ext use_ext
decl decl body prog_body end
- def_ext ::= extension ident syntax
syntax use_ext use_ext decl decl ext_body stat
end
- syntax ::= { text | $ ident :
def_token }
- def_token ::= def_var | def_exp |
def_stat
- def_var ::= var type
- def_exp ::= exp type
- def_stat ::= stat
- ext_call ::= text
- prog_body := { stat | ext_call }
- ext_body ::= pascal text | { stat | ext_call } |
operator { stat | ext_call }
leda ::= { def_ext } prog
Remarci
Fiecare instructiune si fiecare definitie de extindere au asociate, in mod bijectiv, cite un icon, deoarece LEDA se doreste a fi un limbaj vizual.
In ceea ce priveste semantica, instructiunile de baza incluse in LEDA se comporta exact ca si cele din limbajul Pascal. La fel, specificatiile tehnice ale limbajului sint similare cu cele ale Pascal-ului.
|
Din acest exemplu putem observa urmatoarele aspecte:
extension
, syntax
, body
inlocuiesc
meta-terminalii _SBL_, _SSY_, respectiv _SSE_ prezentati in capitolul precedent;
for
nou definita poate fi considerata ca
apartine nivelului 1 al limbajului, ea definindu-se prin intermediul
elementelor nivelului 0 ( baza ).
|
O serie de observatii:
for2
apartine multimii elementelor de nivel secund
fiind definit cu ajutorul unui element al nivelului 1 (
for
);
for2
va fi exprimat
doar prin intructiuni de baza astfel:
|
|
Observatii:
matprod
apartine multimii elementelor nivelului 3
fiind definit prin intermediul unui element al nivelului 1 (
for
), prin intermediul unui element de nivel 2 (
for2
) si cu ajutorul elementelor bazei;