Qual è il motivo per cui non sono riuscito a creare un linguaggio che supporti le funzioni infix, postfix e prefix e altro?

StackOverflow https://stackoverflow.com/questions/427040

Domanda

Ho riflettuto sulla creazione di un linguaggio che sarebbe estremamente adatto alla creazione di DSL, consentendo definizioni di funzioni che sono infisso, postfisso, prefisso o addirittura consistono in più parole. Ad esempio, è possibile definire un operatore di moltiplicazione infix come segue (dove è già definito moltiplica (X, Y)):

a * b => multiply(a,b)

O un postfisso " quadrato " operatore:

a squared => a * a

O un operatore ternario in stile C o Java, che coinvolge due parole chiave intervallate da variabili:

a ? b : c => if a==true then b else c

Chiaramente c'è molto spazio per le ambiguità in una tale lingua, ma se è staticamente tipizzato (con l'inferenza del tipo), allora la maggior parte delle ambiguità potrebbe essere eliminata e quelle che rimangono potrebbero essere considerate un errore di sintassi (da correggere aggiungere parentesi, se del caso).

C'è qualche motivo che non vedo che renderebbe questa estremamente difficile, impossibile o semplicemente una cattiva idea?

Modifica: Un certo numero di persone mi ha indicato lingue che potrebbero fare questo o qualcosa del genere, ma in realtà sono interessato a suggerimenti su come potrei implementare il mio parser per esso, o problemi che potrei incontrare se lo facessi.

È stato utile?

Soluzione

Questo non è troppo difficile da fare. Ti consigliamo di assegnare a ciascun operatore una fissità (infisso, prefisso o postfisso) e una precedenza . Rendi la precedenza un numero reale; mi ringrazierai più tardi. Gli operatori di precedenza superiore si legano più strettamente degli operatori di precedenza inferiore; a parità di livelli di precedenza, puoi richiedere chiarimenti tra parentesi, ma probabilmente preferirai consentire ad alcuni operatori di essere associativi in modo da poter scrivere

x + y + z

senza parentesi. Una volta che hai una fissità, una precedenza e un'associatività per ciascun operatore, ti consigliamo di scrivere un parser precedenza operatore . Questo tipo di parser è abbastanza semplice da scrivere; esegue la scansione dei token da sinistra a destra e utilizza uno stack ausiliario. C'è una spiegazione nel libro dei draghi ma non l'ho mai trovato molto chiaro, in parte perché il libro dei draghi descrive un caso molto generale di analisi della precedenza dell'operatore. Ma non credo che lo troverai difficile.

Un altro caso di cui dovresti fare attenzione è quando hai

prefix (e) postfix

dove prefisso e postfix hanno la stessa precedenza. Questo caso richiede anche parentesi per chiarire le ambiguità.

Il mio documento Espressioni non analisi con operatori Prefix e Postfix ha un parser di esempio nella parte posteriore e puoi scaricare il codice, ma è scritto in ML, quindi il suo funzionamento potrebbe non essere ovvio per l'amatore. Ma l'intera faccenda della fissità e così via è spiegata in dettaglio.

Altri suggerimenti

Che cosa hai intenzione di fare per l'ordine delle operazioni?

a * b squared

Potresti voler dare un'occhiata a Scala che ha un tipo di approccio unico per operatori e metodi.

Haskell ha proprio quello che stai cercando.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top