Grammar translation in Parsec

I am trying to convert the following grammar

callExpr:
    primaryExpr
  | callExpr primaryExpr

for expressing Parsec in Haskell.

Obviously, the problem is that it is left recursive, so I am trying to make out its recursive climbing style. The pseudo code I'm trying to implement is:

e = primaryExp
while(true) {
    e2 = primaryExp
    if(e2 failed) break;
    e = CallExpr(e, e2)
}

and my attempt to translate this into Haskell:

callExpr :: IParser Expr
callExpr = do
    e <- primaryExpr
    return $ callExpr' e
  where
    callExpr' e = do
        e2m <- optionMaybe primaryExpr
        e' <- maybe e (\e2 -> callExpr' (CallExpr e e2)) e2m
        return e'

where primaryExprhas type IParser Expr and iparser is defined as

type IParser a = ParsecT String () (State SourcePos) a

This, however, gives me the following type error:

Couldn't match type `ParsecT String () (State SourcePos) t0'
              with `Expr'
Expected type: ParsecT String () (State SourcePos) Expr
  Actual type: ParsecT
                 String
                 ()
                 (State SourcePos)
                 (ParsecT String () (State SourcePos) t0)
In a stmt of a 'do' block: return $ callExpr' e
In the expression:
  do { e <- primaryExpr;
       return $ callExpr' e }
In an equation for `callExpr':
    callExpr
      = do { e <- primaryExpr;
             return $ callExpr' e }
      where
          callExpr' e
            = do { e2m <- optionMaybe primaryExpr;
                   .... }

How to fix this type of error?

+4
source share
1 answer

chainl1. chainl1 p op p -s, op -s - . op , p -s .

, , , chainl1 op, :

callExpr :: IParser Expr
callExpr = chainl1 primaryExpr (return CallExpr)

callExpr, .

return $ callExpr' e, callExpr' e , callExpr' e .

-, maybe e (\e2 -> callExpr' (CallExpr e e2)) e2m e ( e'?), return e.

+5

All Articles