Specificarea limbajului de programare - Programming language specification

În calcul , o specificație a limbajului de programare (sau standard sau definiție ) este un artefact de documentare care definește un limbaj de programare, astfel încât utilizatorii și implementatorii să poată fi de acord asupra a ceea ce înseamnă programele din acel limbaj. Specificațiile sunt de obicei detaliate și formale și sunt utilizate în principal de implementatori, utilizatorii făcând referire la acestea în caz de ambiguitate; specificația C ++ este frecvent citată de utilizatori, de exemplu, datorită complexității. Documentația aferentă include o referință a limbajului de programare , care este destinat în mod expres utilizatorilor, și o justificare a limbajului de programare , care explică de ce specificația este scrisă așa cum este; acestea sunt de obicei mai informale decât o specificație.

Standardizare

Nu toate limbajele de programare majore au specificații, iar limbile pot exista și pot fi populare de zeci de ani fără o specificație. Un limbaj poate avea una sau mai multe implementări, al căror comportament acționează ca un standard de facto , fără ca acest comportament să fie documentat într-o specificație. Perl (prin Perl 5 ) este un exemplu notabil de limbaj fără specificații, în timp ce PHP a fost specificat doar în 2014, după ce a fost utilizat timp de 20 de ani. Un limbaj poate fi implementat și apoi specificat, sau specificat și apoi implementat, sau acestea se pot dezvolta împreună, ceea ce este o practică obișnuită astăzi. Acest lucru se datorează faptului că implementările și specificațiile oferă verificări reciproce: scrierea unei specificații necesită precizarea precisă a comportamentului unei implementări, iar implementarea verifică dacă o specificație este posibilă, practică și consecventă. Scrierea unei specificații înainte de implementare a fost în mare parte evitată de la ALGOL 68 (1968), din cauza dificultăților neașteptate în implementare atunci când implementarea este amânată. Cu toate acestea, limbile sunt încă implementate ocazional și câștigă popularitate fără o specificație formală: o implementare este esențială pentru utilizare, în timp ce o specificație este de dorit, dar nu esențială (în mod informal, „discuții de cod”).

ALGOL 68 a fost primul (și posibil unul dintre ultimele) limbaj major pentru care s-a făcut o definiție formală completă înainte de a fi implementată.

Formulare

O specificație a limbajului de programare poate lua mai multe forme, inclusiv următoarele:

  • O definiție explicită a sintaxei și semanticii limbajului. În timp ce sintaxa este specificată în mod obișnuit folosind o gramatică formală, definițiile semantice pot fi scrise în limbaj natural (de exemplu, abordarea luată pentru limbajul C ), sau o semantică formală (de exemplu, specificațiile standard ML și Scheme ). Un exemplu notabil este limbajul C, care a câștigat popularitate fără o specificație formală, fiind în schimb descris ca parte a unei cărți, Limbajul de programare C (1978) și doar mult mai târziu fiind standardizat formal în ANSI C (1989).
  • O descriere a comportamentului unui compilator (uneori numit „traducător”) pentru limbă (de exemplu, limbajul C ++ și Fortran ). Sintaxa și semantica limbajului trebuie deduse din această descriere, care poate fi scrisă într-un limbaj natural sau formal.
  • Un model de implementare , uneori scris în limba specificată (de exemplu, Prolog ). Sintaxa și semantica limbajului sunt explicite în comportamentul implementării modelului.

Sintaxă

Sintaxa unui limbaj de programare este de obicei descrisă utilizând o combinație a următoarelor două componente:

Semantică

Formularea unei semantici riguroase a unui limbaj de programare mare, complex, practic este o sarcină descurajantă chiar și pentru specialiști cu experiență, iar specificațiile rezultate pot fi dificil de înțeles de către oricine, cu excepția experților. Următoarele sunt câteva dintre modalitățile prin care semantica limbajului de programare poate fi descrisă; toate limbile folosesc cel puțin una dintre aceste metode de descriere, iar unele limbi combină mai multe

Limbaj natural

Cele mai utilizate limbi sunt specificate utilizând descrieri ale semanticului în limbaj natural. Această descriere ia de obicei forma unui manual de referință pentru limbă. Aceste manuale pot rula la sute de pagini, de exemplu, versiunea tipărită a The Java Language Specification, Ed. 3. are o lungime de 596 de pagini.

Imprecizia limbajului natural ca vehicul pentru descrierea semanticii limbajului de programare poate duce la probleme cu interpretarea specificației. De exemplu, semantica firelor Java a fost specificată în limba engleză și s-a descoperit ulterior că specificația nu oferea îndrumări adecvate pentru implementatori.

Semantica formala

Semantica formală se bazează pe matematică. Drept urmare, ele pot fi mai precise și mai puțin ambigue decât semantica dată în limbajul natural. Cu toate acestea, descrierile suplimentare ale limbii naturale ale semanticii sunt adesea incluse pentru a ajuta la înțelegerea definițiilor formale. De exemplu, Standardul ISO pentru Modula-2 conține atât o definiție formală, cât și o limbă naturală pe paginile opuse.

Limbaje de programare a căror semantică este descrisă în mod formal pot obține multe beneficii. De exemplu:

  • Semantica formală permite dovezi matematice ale corectitudinii programului;
  • Semantica formală facilitează proiectarea sistemelor de tip și dovezi cu privire la soliditatea acestor sisteme de tip;
  • Semantica formală poate stabili standarde neechivoce și uniforme pentru implementările unui limbaj.

Suportul automat al instrumentelor vă poate ajuta să realizați unele dintre aceste beneficii. De exemplu, un verificator automat de teoreme sau un verificator de teoreme poate crește încrederea unui programator (sau a unui proiectant de limbă) în corectitudinea probelor despre programe (sau limbajul în sine). Puterea și scalabilitatea acestor instrumente variază foarte mult: verificarea formală completă este intensă din punct de vedere al calculului, rareori depășește programele care conțin câteva sute de linii și pot necesita asistență manuală considerabilă din partea unui programator; instrumentele mai ușoare, cum ar fi modelele de verificare, necesită mai puține resurse și au fost utilizate pe programe care conțin zeci de mii de linii; multe compilatoare aplică verificări de tip static oricărui program pe care îl compilează.

Implementare referință

O implementare de referință este o implementare unică a unui limbaj de programare care este desemnat ca fiind autoritar. Comportamentul acestei implementări este menit să definească comportamentul corect al unui program scris în limbă. Această abordare are mai multe proprietăți atractive. În primul rând, este precis și nu necesită nicio interpretare umană: disputele cu privire la semnificația unui program pot fi soluționate pur și simplu prin executarea programului cu privire la implementarea de referință (cu condiția ca implementarea să se comporte determinist pentru acel program).

Pe de altă parte, definirea semanticii limbajului printr-o implementare de referință are, de asemenea, mai multe dezavantaje potențiale. Principalul dintre ele este că combină limitele implementării de referință cu proprietățile limbajului. De exemplu, dacă implementarea de referință are o eroare, atunci acea eroare trebuie considerată a fi un comportament autoritar. Un alt dezavantaj este că programele scrise în acest limbaj se pot baza pe ciudățenii în implementarea de referință, împiedicând portabilitatea între diferite implementări.

Cu toate acestea, mai multe limbi au folosit cu succes abordarea de implementare de referință. De exemplu, interpretul Perl este considerat a defini comportamentul autoritar al programelor Perl. În cazul Perl, modelul open-source al distribuției software a contribuit la faptul că nimeni nu a produs vreodată o altă implementare a limbajului, astfel încât problemele implicate în utilizarea unei implementări de referință pentru a defini semantica limbajului sunt discutabile.

Test suite

Definirea semanticii unui limbaj de programare în termeni de suită de testare implică scrierea unui număr de exemple de programe în limbă și apoi descrierea modului în care acele programe ar trebui să se comporte - probabil prin notarea rezultatelor lor corecte. Programele, plus rezultatele lor, sunt numite „suita de testare” a limbajului. Orice implementare corectă a limbajului trebuie să producă exact rezultatele corecte pe programele de suită de testare.

Principalul avantaj al acestei abordări a descrierii semantice este că este ușor să se determine dacă o implementare a limbajului trece o suită de teste. Utilizatorul poate pur și simplu să execute toate programele din suita de testare și să compare ieșirile cu ieșirile dorite. Cu toate acestea, atunci când este utilizată singură, abordarea suitei de testare are și dezavantaje majore. De exemplu, utilizatorii vor să ruleze propriile programe, care nu fac parte din suita de testare; într-adevăr, o implementare a limbajului care ar putea rula doar programele din suita sa de testare ar fi în mare măsură inutilă. Dar o suită de testare nu descrie, prin ea însăși, cum ar trebui să se comporte implementarea limbajului pentru orice program care nu se află în suita de testare; determinarea acelui comportament necesită o oarecare extrapolare din partea implementatorului, iar diferiți implementatori pot să nu fie de acord. În plus, este dificil să folosești o suită de teste pentru a testa comportamentul care este intenționat sau permis să fie nedeterminist .

Prin urmare, în practica obișnuită, suitele de testare sunt utilizate numai în combinație cu una dintre celelalte tehnici de specificare a limbajului, cum ar fi o descriere a limbajului natural sau o implementare de referință.

Vezi si

linkuri externe

Specificații lingvistice

Câteva exemple de specificații lingvistice oficiale sau proiecte:

Note