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

10

Recentemente ho intrapreso il compito di scrivere un linguaggio di programmazione basato su stack. Tuttavia, prima di iniziare a progettare la mia lingua, ho pensato che sarebbe stata una buona idea leggere e sperimentare con i linguaggi basati sugli stack esistenti.

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

Forth's flexibility makes a static BNF grammar inappropriate, and it does not have a monolithic compiler. Extending the compiler only requires writing a new word, instead of modifying a grammar and changing the underlying implementation.

Dalla mia comprensione, in Forth gergo, il termine "parola" sembra essere fondamentalmente sinonimo di "subroutine". Detto questo, la dichiarazione di cui sopra sembra strana. Perché esattamente la capacità di creare nuove funzioni in Forth potrebbe rendere inappropriata una grammatica formale per Forth? Perché dovresti dover riscrivere la grammatica per ogni nuova subroutine che definisci? In che modo scrivere una nuova parola nell'ambiente costituisce estendere il compilatore? L'affermazione sopra sembra simile 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 sottoinsieme semplice di Forth in basso:

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

La grammatica di cui sopra sembrerebbe coprire un sottoinsieme valido di affermazioni Forth, e non sembra così difficile da estendere a coprire tutte le affermazioni valide nella lingua Forth. Inoltre, se il parser di un compilatore implementa la grammatica di cui sopra, non riesco a vedere come il compilatore sarebbe mai stato esteso. Il compilatore aggiungerà semplicemente nuove parole al suo ambiente . Solo l'ambiente è cambiato. Sembra quasi che il precedente estratto da Wikipedia stia combinando il codice di sottolineatura che compone il compilatore (che non cambia) con l'ambiente del compilatore (che non cambia).

In sintesi, perché l'approvazione di Forth per definire nuove parole (subroutine) non è appropriata per una grammatica scritta?

    
posta Christian Dean 06.05.2018 - 02:56
fonte

2 risposte

10

Una parola "normale" è praticamente solo una subroutine.

... ma puoi scrivere un definito dall'utente definizione della parola , 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 fa il colon, e nel processo cambiare come una definizione di parola è "compilata", cambiando così il funzionamento del compilatore e cambiando la grammatica della lingua che viene 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.

    
risposta data 06.05.2018 - 08:05
fonte
3

In Forth, puoi eseguire il codice al momento della compilazione.

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

Più comunemente, puoi definire parole che leggono gli argomenti dal codice sorgente. Tradizionalmente leggevi le parole nello stesso modo del compilatore, ma non è obbligatorio.

Ad esempio, la parola ." (che stampa una stringa) non legge fino allo spazio successivo, legge fino al prossimo " . Se provi ad analizzare il codice : PRINTHELLO ." Hello ; : func2 world!" ; senza un caso speciale per ." , troverai che non è stato analizzato correttamente.

Puoi certamente aggiungere un caso speciale per ." alla tua grammatica, ma la grammatica sarà ancora errata se il programmatore definisce la propria parola come ." - ad esempio, ecco uno: : MY_PRINT POSTPONE ." ; IMMEDIATE . Questa parola è equivalente a ." ; Posso scrivere MY_PRINT Hello ; world! " e la tua grammatica deve essere in grado di analizzarlo. Buona fortuna.

    
risposta data 08.05.2018 - 00:36
fonte

Leggi altre domande sui tag