miniatura|Codi font d'un programa escrit en llenguatge BASIC. Un llenguatge de programació és un llenguatge informàtic utilitzat per controlar el comportament d'una màquina, normalment un ordinador. Cada llenguatge té una sèrie de regles sintàctiques i semàntiques estrictes que cal seguir per escriure un programa informàtic, i que en descriuen l'estructura i el significat respectivament. Aquestes regles permeten especificar tant la classe de dades amb què treballarà el programa com les accions que realitzarà. Mentre que alguns llenguatges es defineixen per una especificació formal (un document), altres són definits oficiosament per una implementació concreta (un compilador).

Actualment existeixen milers de llenguatges de programació, i se'n creen de nous contínuament. Alguns dels més extensos són ASM, C, C++, C# i Java, tot i que els llenguatges de programació relacionats amb la web, com ara PHP i Javascript estan esdevenint més i més populars.

Classificació alt nivell-baix nivell Els llenguatges se solen classificar principalment en llenguatges de baix nivell, que són molt propers al codi binari utilitzat internament per un tipus d'ordinador determinat, i llenguatges d'alt nivell, que són més propers al llenguatge humà i més independents del tipus d'ordinador.

La diferència entre llenguatges de baix i alt nivell es fa evident comparant dos programes que escriuen "Hola" en pantalla, el primer usant llenguatge d'assemblador per màquines x86 (baix nivell), MODEL SMALL IDEAL STACK 100H

DATASEG HW DB 'Hola!$'

CODESEG MOV AX, @data MOV DS, AX MOV DX, OFFSET HW MOV AH, 09H INT 21H MOV AX, 4C00H INT 21H END i el segon utilitzant un llenguatge d'alt nivell (Python), print("Hola!") Els llenguatges d'alt nivell es poden classificar també segons el tipus de model de programació que utilitzen (procedimentals, funcionals, orientats a objectes, etc.). També hi ha llenguatges de marcatge, que no són llenguatges de programació, sinó que s'utilitzen per estructurar o donar forma a un text. Avui en dia existeixen gran quantitat de llenguatges, més o menys especialitzats en diferents tasques.

Elements del llenguatge de programació Tots els llenguatges de programació tenen alguns elements de formació primitius per a la descripció de les dades i dels processos o transformacions aplicades a aquestes dades (tal com la suma de dos nombres o la selecció d'un element que forma part d'una col·lecció). Aquests elements primitius són definits per regles sintàctiques i semàntiques que descriuen la seva estructura i significat respectivament.

Sintaxi miniatura|Amb freqüència els elements de la sintaxi es fan que se'ls ressalta amb colors diferents per facilitar la seva lectura. Aquest exemple està escrit en Python.

A la forma visible d'un llenguatge de programació se la coneix com a sintaxi. La majoria dels llenguatges de programació són purament textuals, és a dir, utilitzen seqüències de text que inclouen paraules, nombres i puntuació, de manera similar als llenguatges naturals escrits. D'altra banda, hi ha alguns llenguatges de programació que són més gràfics en la seva naturalesa, utilitzant relacions visuals entre símbols per especificar un programa.

La sintaxi d'un llenguatge de programació descriu les combinacions possibles dels símbols que formen un programa sintàcticament correcte. El significat que se li dona a una combinació de símbols és manejat per la seva semàntica (ja sigui formal o com parteix del codi dur de la referència d'implementació). Ja que la majoria dels llenguatges són textuals, aquest article tracta de la sintaxi textual.

La sintaxi dels llenguatges de programació és definida generalment utilitzant una combinació d'expressions regulars (per a l'estructura lèxica) i la Notació De Backus-naur (per a l'estructura gramatical). Aquest és un exemple d'una gramàtica simple, obtinguda de Lisp:

expressió ::= àtom |llista àtom ::= nombre|símbol nombre ::= [+-]?['0'-'9']+ símbol ::= ['A'-'Z''a'-'z'].* llista ::= '(' expressió* ')'

Amb aquesta gramàtica s'especifica el següent:

una expressió pot ser un àtom o una llista; un àtom pot ser un nombre o un símbol; un nombre és una seqüència contínua d'un o més dígits decimals, precedit opcionalment per un signe més o un signe menys; un símbol és una lletra seguida de zero o més caràcters (excloent espais); una llista és un parell de parèntesi que obren i tanquen, amb zero o més expressions al mig.

Alguns exemples de seqüències ben formades d'acord amb aquesta gramàtica:

'12345', '()', '(a b c232 (1))'

No tots els programes sintàcticament correctes són semànticament correctes. Molts programes sintàcticament correctes tenen inconsistències amb les regles del llenguatge; i poden (depenent de l'especificació del llenguatge i la solidesa de la implementació) resultar en un error de traducció o execució. En alguns casos, tals programes poden exhibir un comportament indefinit. A més, fins i tot quan un programa està ben definit dins d'un llenguatge, encara pot tenir un significat que no és el que la persona que ho va escriure estava tractant de construir.

Usant el llenguatge natural, per exemple, pot no ser possible assignar-li significat a una oració gramaticalment vàlida o l'oració pot ser falsa:

"Les idees verdes i descolorides dormen furiosament" és una oració ben formada gramaticalment però no té significat comunament acceptat. "Pepet és un solter casat" també està ben formada gramaticalment però expressa un significat que no pot ser veritable.

El següent fragment en el llenguatge C és sintàcticament correcte, però executa una operació que no està definida semànticament (ja que p és un punter nul, les operacions p→real i p→im no tenen cap significat):

complex *p = NULL; complex abs_p = sqrt (p→real * p→real + p→im * p→im);

Si la declaració de tipus de la primera línia fos omesa, el programa dispararia un error de compilació, perquè la variable "p" no estaria definida. Però el programa seria sintàcticament correcte encara, ja que les declaracions de tipus proveeixen informació semàntica només.

La gramàtica necessària per especificar un llenguatge de programació pot ser classificada per la seva posició en la Jerarquia de Chomsky. La sintaxi de la majoria dels llenguatges de programació pot ser especificada utilitzant una gramàtica Tipus-2, és a dir, són gramàtiques lliures de context. Alguns llenguatges, incloent Perl i a Lisp, contenen construccions que permeten l'execució durant la fase d'anàlisi. Els llenguatges que permeten construccions que permeten al programador alterar el comportament d'un analitzador fan de l'anàlisi de la sintaxi un problema sense decisió única, i generalment enfosqueixen la separació entre anàlisi i execució. En contrast amb el sistema de macros de Lisp i els blocs Begin de Perl, que poden tenir càlculs generals, les macros de C són mers reemplaçaments de cadenes, i no requereixen execució de codi.

Sistema de tipatge El sistema de tipus defineix com un llenguatge de programació classifica els valors i expressions en tipus, com els manipula, i com hi interacciona. Generalment això inclou la descripció de les estructures de dades que el llenguatge pot construir. El disseny i estudi matemàtic d'aquests sistemes és conegut com la Teoria de tipus (type theory).

S'ha de recordar però que els computadors digitals moderns emmagatzemen internament totes les estructures simplement com a uns i zeros (binari).

Llenguatges tipats vers llenguatges no tipats Un llenguatge és tipat si l'especificació de cada operació defineix a quins tipus de dades una operació és aplicable, amb la implicació que no és aplicable als altres tipus. Per exemple, "aquest text entre cometes" és un string. En la majoria de llenguatges de programació, dividir un número per un string no té sentit. En conseqüència la majoria dels llenguatges de programació moderns rebutjaran qualsevol intent de dur a terme una operació com aquesta. En alguns llenguatges, l'operació sense sentit es detectarà en temps de compilació (comprovació de tipus "estàtica") i serà rebutjada pel compilador. Mentre que en d'altres, l'operació sense sentit es detectarà en temps d'execució (comprovació de tipus "dinàmica"), resultant en una excepció en temps d'execució (runtime exception).

Un cas especial de llenguatges tipats són els llenguatges mono-tipats. Normalment són llenguatges de script o de marcatge, com Rexx o SGML, i només tenen un tipus de dades - majoritàriament, cadenes de caràcters que són utilitzats tant per dades simbòliques com numèriques.

En contrast, un llenguatge no tipat, com la majoria de llenguatges assembladors, permet qualsevol operació sobre qualsevol tipus de dades, considerades com a seqüències de bits de mides vàries. Llenguatges d'alt nivell no tipats inclouen BCPL i algunes varietats de Forth.

A la pràctica, mentre que pocs llenguatges es consideren tipats des del punt de vista de la Teoria de tipus (verificar o rebutjar totes les operacions), la majoria del llenguatges moderns ofereixen un cert grau de tipatge. Molts llenguatges de producció ofereixen alguna manera de subvertir o fer un bypass al sistema de tipus.

Tipus estàtics versus dinàmics En els sistemes de tipatge estàtics totes les expressions tenen els seus tipus determinats abans que el programa s'executi els (normalment al moment de compilar). Per exemple, 1 i (2+2) són expressions d'enters; no es poden passar a una funció que espera una cadena, o emmagatzemar-se en una variable definida per contenir dates.

Els llengües estàticament tipats poden ser o bé tipats de forma manifestada o bé tipats de forma inferida. En el primer cas, el programador ha d'escriure explícitament els tipus en certes posicions textuals (per exemple, en les declaracions de variables). En el segon cas, el compilador infereix els tipus de les expressions i les declaracions basant-se en el context.

El tipatge dinàmic, també anomenat tipat latent, determina el tipus de les operacions en temps d'execució; en altres paraules, els tipus estan associats amb valors de temps d'execució més que no pas a expressions textuals.

Tipus febles i tipus forts Els llenguatges feblement tipats permeten que un valor d'un tipus pugui ser tractat com d'un altre tipus; per exemple una cadena pot ser operada com un nombre. Això pot ser útil a vegades, però també pot introduir certs tipus de fallades que no poden ser detectades durant la compilació o de vegades ni tan sols durant l'execució.

Els llenguatges fortament tipats eviten que passi l'anteriorment explicat: qualsevol intent de dur a terme una operació sobre el tipus equivocat dispara un error. Als llenguatges amb tipus forts se'ls sol anomenar de tipus segurs.

Llenguatges amb tipus febles com Perl i JavaScript permeten un gran nombre de conversions de tipus implícites. Per exemple en JavaScript l'expressió 2 * x converteix implícitament x a un nombre, i aquesta conversió és reeixida inclusivament quan x és null, undefined, un Array o una cadena de lletres. Aquestes conversions implícites són útils amb freqüència, però també poden ocultar errors de programació.

Les característiques destàtics i forts són ara generalment considerades conceptes ortogonals, però el seu tractament en textos de l'àmbit de la programació és divers. Alguns utilitzen el terme de tipus forts per referir-se a tipus fortament estàtics o, per augmentar la confusió, simplement com a equivalència de tipus estàtics. De tal manera que C ha estat considerat com a llenguatge tant de tipus forts, com de tipus estàtics febles.

Semàntica estàtica