Perché la flessibilità di Forth rende inappropriata una grammatica?


10

Di recente ho intrapreso il compito di scrivere un linguaggio di programmazione basato su stack. Prima di iniziare a progettare la mia lingua, tuttavia, ho pensato che sarebbe stata una buona idea leggere e sperimentare lingue esistenti basate su stack.

Questo mi porta all'argomento di questo post. Stavo leggendo l' articolo di Wikipedia su Forth , un linguaggio basato su stack che utilizza espressioni in stile postfix. Nell'articolo ho visto la seguente dichiarazione:

La flessibilità di Forth rende inappropriata una grammatica BNF statica e non ha un compilatore monolitico. L'estensione del compilatore richiede solo di scrivere una nuova parola, invece di modificare una grammatica e cambiare l'implementazione sottostante.

Da quanto ho capito, nel gergo di Forth, il termine "parola" sembra fondamentalmente sinonimo di "subroutine". Detto questo, l'affermazione di cui sopra sembra strana. Perché esattamente la possibilità di creare nuove funzioni in Forth renderebbe inappropriata una grammatica formale per Forth? Perché dovresti riscrivere la grammatica per ogni nuova subroutine che definisci? In che modo scrivere una nuova parola nell'ambiente costituisce l' estensione del compilatore? L'affermazione precedente sembra affine a dire che una grammatica formale è inappropriata per Python perché puoi definire nuove funzioni.

In effetti, ho deciso di provare a scrivere una grammatica in stile BNF per un semplice sottoinsieme di Forth di seguito:

program        ::= stmt+
stmt           ::= func | expr
func           ::= ':' expr+ ';'
expr           ::= INTEGER | word
word           ::= ('+' | '-' | '*' | '/' )

La grammatica di cui sopra sembrerebbe coprire un sottoinsieme valido di istruzioni Forth, e non sembra così difficile da estendere per coprire tutte le dichiarazioni valide nella lingua Forth. Inoltre, se il parser di un compilatore implementa la grammatica sopra, non riesco a vedere come il compilatore sarebbe mai stato esteso. Il compilatore aggiungerà semplicemente qualsiasi nuova parola al suo ambiente . Viene modificato solo l'ambiente. Sembra quasi che il suddetto estratto di Wikipedia stia fondendo il codice di sottolineatura che compone il compilatore (che non cambia) con l'ambiente del compilatore (che cambia).

In sintesi, perché la capacità di Forth di definire nuove parole (subroutine) potrebbe essere inappropriata per una grammatica scritta?


1
"Inappropriato" è una parola forte in questo contesto. Una parola migliore sarebbe probabilmente "non necessaria".
Robert Harvey,

1
Oh, va bene @RobertHarvery. Tuttavia, se così fosse, il brano che ho citato sembrerebbe applicarsi alla maggior parte delle lingue. Tecnicamente non è mai necessaria una grammatica , ma è bello averne una, specialmente quando si scrivono parser a mano.
Christian Dean,

Ma nella maggior parte delle lingue, il parser non è una semplice libreria di runtime che può essere modificata dal codice utente, influenzando così come viene analizzata la riga successiva.
Jörg W Mittag,

Risposte:


10

Una parola "normale" è praticamente solo una subroutine.

... ma puoi scrivere una parola di definizione definita dall'utente , che cambia il funzionamento del compilatore. Ad esempio, una definizione inizia normalmente con due punti (":") e termina con un punto e virgola (";"). Ma se vuoi, puoi (per esempio) cambiare ciò che fanno i due punti, e nel processo cambiare il modo in cui una definizione di parola viene "compilata", cambiando così il funzionamento del compilatore e cambiando la grammatica della lingua riconosciuta.

Ecco perché sta dicendo che una grammatica è inappropriata: la grammatica può letteralmente cambiare da una parte del programma a un'altra. Il caricamento di un dizionario può modificare non solo le subroutine i cui nomi sono attualmente riconosciuti, ma anche la grammatica che viene analizzata quando si definisce una nuova parola.


2
Sei sicuro che questa proprietà di Forth cambi davvero la grammatica e non solo la semantica?
Doc Brown,

@DocBrown: Alla maggior parte delle persone che usano Forth piace abbastanza, quindi in genere apportano solo le modifiche minime necessarie per l'attività in corso. Qualcuno che fosse abbastanza ambizioso (e pazzo) potrebbe cambiare completamente la sintassi se lo desiderasse - come usare la notazione infix invece che postfix, se lo volessero abbastanza male.
Jerry Coffin,

@DocBrown Che tipo di grammatica potresti scrivere che mi consentirebbe di scrivere un interprete C in Forth, e poi improvvisamente passare a C nel mezzo del programma?
user253751

@immibis: beh, la mia domanda è: Forth permette davvero qualcosa del genere? Da quell'articolo collegato, questo non è intrinsecamente chiaro per me.
Doc Brown,

@DocBrown Sì. Puoi eseguire il tuo codice in fase di compilazione, ciò significa che se lo desideri puoi assumere completamente il compilatore. Fondamentalmente è possibile eseguire il compilatore / interprete C nel mezzo del compilatore / interprete Forth. (se vuoi eventualmente tornare a Forth o no dipende da te)
user253751

3

In Forth, puoi eseguire il codice in fase di compilazione.

In particolare, è possibile eseguire codice che consuma parole dall'input. Ad esempio, è possibile scrivere un compilatore C in Forth, quindi chiamarlo in fase di compilazione e quindi scrivere il resto del programma in C.

Più comunemente, è possibile definire parole che leggono argomenti dal codice sorgente. Tradizionalmente leggi le parole nello stesso modo del compilatore, ma non è necessario.

Ad esempio, la ."parola (che stampa una stringa) non legge fino allo spazio successivo, legge fino al successivo ". Se si tenta di analizzare il codice : PRINTHELLO ." Hello ; : func2 world!" ;senza un caso speciale per .", si scoprirà che non viene analizzato correttamente.

Si può certamente aggiungere un caso speciale per ."per la grammatica, ma la grammatica sarà ancora essere corretto se il programmatore definisce la propria parola come ."- per esempio eccone uno: : MY_PRINT POSTPONE ." ; IMMEDIATE. Questa parola equivale a ."; Posso scrivere MY_PRINT Hello ; world! "e la tua grammatica deve essere in grado di analizzarla. Buona fortuna.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.