Esistono due casi diversi da considerare, a seconda della sintassi della lingua. Se la tua lingua utilizza la parentesi per indicare l'applicazione della funzione (ad es. f(2+1)
), La precedenza è irrilevante. La funzione deve essere inserita nello stack e espulsa dopo (per l'esempio sopra, il risultato è 2 1 + f
). In alternativa, è possibile trattare la funzione come un valore e inviarla immediatamente e generare un'operazione di invocazione della funzione dopo la parentesi chiusa (che altrimenti dovrebbe essere trattata come qualsiasi altra parentesi), ad esempio f 2 1 + $
dove si $
trova l'operazione di invocazione della funzione.
Se la tua lingua, tuttavia, non utilizza la parentesi per indicare l'invocazione della funzione, ma colloca invece l'argomento direttamente dopo la funzione senza punteggiatura speciale (ad esempio f 2 + 1
), come apparentemente è il caso dell'esempio di Wikipedia, allora le cose sono un po 'più complicate. Si noti che l'espressione che ho appena fornito è un esempio ambiguo: f viene applicato a 2 e 1 aggiunti al risultato oppure aggiungiamo 2 e 1 insieme e quindi chiamiamo f con il risultato?
Ancora una volta, ci sono due approcci. Puoi semplicemente spingere la funzione nello stack dell'operatore quando la incontri e assegnarla come preferisci. Questo è l'approccio più semplice ed è apparentemente ciò che ha fatto l'esempio citato. Vi sono tuttavia problemi pratici. Innanzitutto, come si identifica una funzione? Se hai un set finito è facile, ma se hai funzioni definite dall'utente, questo significa che il tuo parser ha bisogno di troppo feed back nel tuo ambiente, che può diventare disordinato rapidamente. E come gestite le funzioni con più argomenti?
La mia sensazione è che per questo stile di sintassi, usare le funzioni come valori che sono più maneggevoli da un operatore dell'applicazione di funzioni ha molto più senso. Quindi, puoi semplicemente iniettare l'operatore dell'applicazione ogni volta che leggi un valore e anche l'ultima cosa che leggi era un valore, quindi non hai bisogno di alcun modo speciale per dire quali identificatori sono funzioni. Puoi anche lavorare con espressioni che restituiscono funzioni (che è difficile o impossibile con lo stile funzione-come-operazione). Ciò significa che è possibile utilizzare il curry per gestire più funzioni di argomento, il che è una semplificazione enorme rispetto al tentativo di gestirle direttamente.
L'unica cosa che devi decidere allora è qual è la precedenza dell'applicazione di funzione. La scelta spetta a te, ma in tutte le lingue che ho usato che funziona in questo modo, è stato l'operatore più fortemente vincolante nella lingua ed è stato il giusto associativo. (L'unica variante interessante è Haskell, che oltre ad avere la versione fortemente vincolante descritta, ha anche un sinonimo per essa con il simbolo $
che è l'operatore più debolmente vincolante nella lingua, consentendo a espressioni come f 2 + 1
applicare f a 2 e f $ 2 + 1
applicare a tutto il resto dell'espressione)
sin( max( 2 3) / 3 * 3.1415)