2012-05-07 10 views
13

La documentación para Parsec.Expr.buildExpressionParser dice:Parsec.Expr repitió operador de prefijo/Postfix no soportado

prefijo y de sufijo operadores de la misma precedencia sólo pueden ocurrir una vez (es decir --2 no está permitida si - es prefijo negar).

y, de hecho, esto me está mordiendo, ya que el lenguaje que estoy tratando de analizar permite la repetición arbitraria de sus operadores de prefijo y de sufijo (pensar en una expresión de C como **a[1][2]).

Entonces, ¿por qué Parsec hace esta restricción, y cómo puedo evitarla?

Creo que puedo mover mis analizadores prefijo/postfijo al analizador term ya que tienen la precedencia más alta.

es decir

**a + 1 

se analiza como

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

pero lo que pude haber hecho si quería que va a analizar como

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

si buildExpressionParser hizo lo que yo quiero, yo simplemente podría haber reorganizado el orden de los operadores en la tabla.

Nota Ver here una solución mejor

Respuesta

13

me lo resolvió a mí mismo mediante el uso de chainl1:

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

Estos combinadores utilizan chainl1 con un analizador op que siempre tiene éxito, y simplemente compone las funciones devueltos por el analizador term en orden de izquierda a derecha o de derecha a izquierda. Estos se pueden usar en la tabla buildExprParser; donde le ha hecho esto:

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

ahora tienes que hacer esto:

de esta manera, buildExprParser todavía se puede utilizar para establecer la precedencia de operadores, pero ahora sólo se ve una sola Prefix o Postfix operador en cada precedencia. Sin embargo, ese operador tiene la capacidad de absorber tantas copias de sí mismo como sea posible y devolver una función que lo hace parecer como si hubiera un solo operador.

+0

Encontré su respuesta extremadamente útil, pero me encontré con otro problema, detallado [aquí] (http://stackoverflow.com/questions/11174775), y agradecería que pudiera echar un vistazo, en el de casualidad tienes una solución. –

+0

Gracias por la útil respuesta. Estoy teniendo algunas dificultades con una generalización de este problema. Si tiene alguna sugerencia, sería muy bienvenido (vea http://stackoverflow.com/questions/33214163/parsec-expr-repeated-prefix-with-different-priority/33217888#33217888) – BartBog

Cuestiones relacionadas