Che cos'è esattamente un linguaggio di programmazione? Cosa ci consente di scrivere in un linguaggio del genere?

26

Bene, sono nuovo alla programmazione e ammetto che questa è una domanda abbastanza astratta.

Il linguaggio naturale che parliamo ogni giorno esiste perché le persone possono capirsi l'un l'altro. Come possono i computer capire il mio codice scritto in una determinata lingua?

Diciamo che il signor A crea una nuova lingua. Come viene accettato dalle macchine? Il creatore deve comunicare con la macchina usando il linguaggio macchina per creare una nuova lingua? Che cosa garantisce di poter scrivere in una lingua mentre viene compreso correttamente dalla macchina?

    
posta Erica Xu 24.10.2011 - 22:07
fonte

5 risposte

39

Puoi riassumere praticamente l'intera risposta al tuo insieme di domande con la parola "compilatore" . Un compilatore è un programma speciale la cui funzione è quella di prendere il codice sorgente come input, applicare regole linguistiche determinate dal progettista del linguaggio al fine di capire cosa significa il codice e produrre codice con lo stesso significato in un'altra lingua come output. Questo è generalmente il codice macchina o una qualche forma di bytecode (il "codice macchina" per macchine virtuali), sebbene esistano compilatori specializzati che traducono il codice in altri linguaggi di alto livello. Sono oltre lo scopo di questa domanda, però.

Non tutte le lingue hanno un compilatore. Alcuni di loro hanno invece un interprete , che fa tutte le stesse cose che fa un compilatore, tranne che invece di produrre codice macchina dopo aver determinato cosa significa il programma, esegue semplicemente il programma immediatamente. Ma i principi di base per analizzare (leggere) il codice e determinare cosa significa sono uguali.

Rispondere a una domanda più approfondita di quella che otterrebbe nella teoria del compilatore, che è un argomento molto vasto. Se sei interessato all'argomento, dovresti iniziare leggendo l'articolo di Wikipedia per "compilatore" e controllando i link da esso, e se hai domande specifiche, sentiti libero di chiedere loro qui.

    
risposta data 24.10.2011 - 22:15
fonte
11

Come hai sottolineato, gli umani comunicano tra loro in una lingua "naturale" come inglese, francese, tedesco. Sono chiamati naturali perché li acquisiamo naturalmente piuttosto che inventarli intenzionalmente (l'esperanto è un'eccezione).

Un linguaggio formale è uno inventato per qualche scopo o altro. Un linguaggio di programmazione come C, ad esempio, è un linguaggio formale inventato allo scopo di programmare i computer.

Tutte le lingue, possono essere descritte usando una grammatica. Una gerarchia di grammatiche è stata descritta da Noam Chomsky nel 1956. Si compone dei seguenti livelli:

Grammatiche di tipo 0 (grammatiche senza restrizioni). Sono i più generali e equivalgono a una macchina di Turing. In quanto tale, il problema di decidere se una determinata stringa fa parte di una grammatica senza restrizioni è indecidibile.

Grammatiche di tipo 1 (grammatiche sensibili al contesto). Quasi tutte le lingue naturali come l'inglese sono sensibili al contesto. Un esempio di sensibilità al contesto in inglese sono le due frasi: "Il tempo vola come una freccia". e "La frutta vola come una banana". In generale, è difficile per i computer capire i linguaggi sensibili al contesto.

Grammatiche di tipo 2 (senza contesto). Le lingue prive di contesto sono la base teorica per la sintassi della maggior parte dei linguaggi di programmazione.

Grammatiche di tipo 3 (grammatiche regolari). La famiglia di lingue regolari può essere ottenuta tramite espressioni regolari. Le lingue regolari sono comunemente usate per definire i modelli di ricerca e la struttura lessicale dei linguaggi di programmazione.

Le grammatiche di tipo 2 (context-free) e di tipo 3 (regolari) sono più spesso dai computer perché i parser per loro possono essere implementati in modo efficiente.

BNF (Backus Normal Form o Backus-Naur Form) è una tecnica di notazione per il contesto - grammatiche libere, spesso utilizzate per descrivere la sintassi dei linguaggi utilizzati nell'informatica.

Ad esempio un identificatore può essere descritto come:

<identifier> ::= <letter> { <letter> | <digit> }

che significa che deve iniziare con una lettera e può contenere ulteriori lettere o cifre.

In precedenza, una lettera è definita a 'a' | 'b' | 'c' ecc. e le cifre sono definite da '0' a '9' usando lo stesso tipo di notazione.

Un'istruzione C per "potrebbe essere definita come:

 <for_statement> ::=
    'for' '(' <expression> ';' <expression> ';' <expression> ')' <statement> 

Gli analizzatori e parser lessicali (i primi stadi di un compilatore o di un interprete) sono quindi costruiti per accettare la grammatica specifica descritta dal BNF per un particolare linguaggio. Gli analizzatori lessicali vengono in genere utilizzati per separare i vari token di una lingua (come una parola chiave, un identificatore o un numero) e il parser viene utilizzato per capire come funzionano i token, ad esempio come viene costruita una istruzione "for" .

    
risposta data 25.10.2011 - 00:52
fonte
5

In primo luogo, definiamo "lingua" in termini di cosa sia. La lingua richiede prima un vocabolario (una lista di parole che definiscono concetti che sono gli oggetti della comunicazione) e quindi una sintassi (un "primer" o un insieme di regole che definiscono la struttura della comunicazione).

A questo livello di base, C # non è poi così diverso dall'inglese. Ciò che rende C # un "linguaggio di programmazione" è il suo intento, e quindi il suo design; è progettato per essere digerito in singoli comandi di basso livello. In quanto tale, il vocabolario predefinito è limitato, la sintassi è rigidamente applicata e l'intero linguaggio è progettato per essere consumato in un modo predefinito ben noto dal suo "pubblico" (il computer, più precisamente il compilatore, che digerirà il codice sorgente in una "lingua intermedia" di semplici comandi che possono essere ulteriormente tradotti in codice macchina dal "runtime"). Non scrivi prosa o poesia in C #; dici al computer di fare un lavoro nel modo più inequivocabile possibile.

Per i computer, sì, uno strumento, di solito chiamato compilatore, è necessario per prendere ciò che scrivi nel codice e convertirlo nelle istruzioni che il computer può utilizzare. L'informatica, come la maggior parte della tecnologia, è un processo intrinsecamente iterativo e "stratificato". Quando i computer sono stati inventati per la prima volta, sono stati programmati inserendo manualmente le istruzioni binarie. Queste istruzioni sono state standardizzate per ciascun processore in "codici macchina" esadecimali; la differenza sta solo nel modo in cui le cifre binarie sono raggruppate per la visualizzazione agli umani. Quindi, nel codice assemblatore, l'elenco di comandi e alcuni identificatori di base come i nomi dei registri sono stati sostituiti per i loro codici esadecimali durante la scrittura dei programmi; ASM può ancora essere convertito 1: 1 nel codice macchina nativo. Il salto di qualità è stato alla programmazione "imperativa" di terza generazione, che fondamentalmente richiede concetti astratti comprensibili dall'uomo come variabili e loop logici e li digerisce nelle istruzioni native, utilizzando modelli basati su parole chiave e sintassi. Le lingue iniziali come COBOL, FORTRAN, Pascal e C possono ancora essere "tradotte" da un essere umano in un particolare linguaggio macchina (in genere 8086 ASM). Poi è arrivata la rivoluzione della programmazione orientata agli oggetti, che è fondamentalmente regole di sintassi aggiuntive che definiscono il codice come concettualmente incapsulato in "oggetti" che hanno una combinazione di stato e logica.

Oggigiorno, siamo nella "quarta generazione" di lingue, che sono lingue scritte per definire la comunicazione con altri programmi invece che direttamente sulla macchina. Ampiamente definito, questo include linguaggi di "markup" come XML / HTML, linguaggi "scripting" come JavaScript e SQL e la maggior parte dei linguaggi "sandbox" come Java e .NET Framework (che vengono compilati in un IL che viene poi interpretato ulteriormente da un runtime che astrae i dettagli specifici della macchina e della piattaforma). Si potrebbe anche dire che comprende il regno dei linguaggi di programmazione funzionale, che sono HEAVILY dipendenti da un runtime per fornire l'astrazione non solo dei dettagli specifici della macchina, ma dei dettagli specifici dell'operazione. Questi linguaggi di quarta generazione sono più o meno fattibili da un umano per tradurre in istruzioni macchina native, e il punto è che non sarebbe uno sforzo utile; la forza di queste lingue è il processo a strati in cui sono usate per dire a un computer cosa fare ai bassi livelli.

    
risposta data 24.10.2011 - 23:15
fonte
4

È una buona domanda. Una risposta adeguata costituisce una buona metà di ciò che viene chiamato "Computer Science".

Per iniziare, ti consiglio di sfogliare denotazionale e operational semantica, quindi leggendo questo libro . Vi darà una comprensione più o meno solida di ciò che è il linguaggio di programmazione e di come può essere definito formalmente.

Se quanto sopra è un po 'troppo accademico, puoi iniziare con Petzold, "Codice" , e poi tornare a la semantica.

    
risposta data 24.10.2011 - 22:35
fonte
4

Se scrivi un programma in un linguaggio di programmazione, un programma diverso convertirà i simboli del tuo programma in simboli che il computer comprende. A volte questo richiede diversi passaggi. Ad esempio in C:

  1. L'utente scrive il programma in un linguaggio ad alto livello (C) che non è compreso dalla CPU, ma viene compreso direttamente dal programmatore (speriamo!).

  2. Il compilatore converte C in linguaggio Assmebly, che non è compreso direttamente dalla CPU ma è facile da convertire in qualcos'altro.

  3. Assempler converte l'assembly in una sequenza di codici binari che sono compresi direttamente dalla CPU. Alcuni compilatori saltano il passaggio precedente (passaggio 2) e producono il file binario compilato direttamente dal codice sorgente.

Per garantire che il computer comprenda il tuo programma, il compilatore o l'interprete ti darà un errore e di solito si fermerà se incontra qualcosa che non è compilabile, come un errore di sintassi. Se il tuo programma non può essere compilato, non potrà mai arrivare allo stadio in cui il tuo programma proverà a eseguirlo e fallirà perché non lo ha "compreso".

Per creare una nuova lingua, devi prima progettare il tuo linguaggio di alto livello e poi devi trovare un modo per mappare i simboli della tua nuova lingua ai comandi di linguaggio assembly che la tua CPU comprende.

    
risposta data 24.10.2011 - 22:17
fonte

Leggi altre domande sui tag