2012-05-07 11 views
13

La documentazione per Parsec.Expr.buildExpressionParser dice:Parsec.Expr ripetuto operatore prefisso/suffisso non supportato

prefisso e suffisso operatori con la stessa precedenza può avvenire solo una volta (cioè --2 non è consentito se - è il prefisso negare).

e in effetti, questo mi sta mordendo, dal momento che la lingua che sto cercando di analizzare permette la ripetizione arbitraria dei suoi operatori prefisso e suffisso (pensare ad un'espressione C come **a[1][2]).

Quindi, perché Parsec fa questa restrizione e come posso aggirarlo?

Penso di poter spostare i parser di prefisso/postfix nel parser term poiché hanno la precedenza più alta.

cioè

**a + 1 

viene analizzato come

(*(*(a)))+(1) 

ma quello che avrei potuto fare se volevo che analizzare come

*(*((a)+(1))) 

se buildExpressionParser fatto quello che voglio, potrebbe semplicemente aver riorganizzato l'ordine degli operatori nella tabella.

Nota Vedere here per una soluzione migliore

risposta

13

ho risolto io stesso utilizzando chainl1:

prefix p = Prefix . chainl1 p $ return  (.) 
postfix p = Postfix . chainl1 p $ return (flip (.)) 

Questi combinatori utilizzano chainl1 con una op parser che riesce sempre, e semplicemente compone le funzioni restituiti dal parser term in ordine da sinistra a destra o da destra a sinistra. Questi possono essere usati nella tabella buildExprParser; dove si sarebbe fatto questo:

exprTable = [ [ Postfix subscr 
       , Postfix dot 
       ] 
      , [ Prefix pos 
       , Prefix neg 
       ] 
      ] 

ora fare questo:

in questo modo, buildExprParser può ancora essere utilizzato per impostare la precedenza degli operatori, ma ora vede solo un singolo Prefix o Postfix operatore ad ogni precedenza. Tuttavia, quell'operatore ha la capacità di estrarre tutte le copie di se stesso che può e restituire una funzione che fa sembrare che ci fosse solo un singolo operatore.

+0

Ho trovato estremamente utile la risposta, ma mi sono imbattuto in un altro problema, dettagliato [qui] (http://stackoverflow.com/questions/11174775), e sarei grato se potesse dare un'occhiata, sul off possibilità di avere una soluzione. –

+0

Grazie per la risposta utile. Sto avendo un po 'di difficoltà con una generalizzazione di questo problema. Se hai qualche suggerimento, sarebbe molto gradito (vedi http://stackoverflow.com/questions/33214163/parsec-expr-repeated-prefix-with-different-priority/33217888#33217888) – BartBog