pStatement = addLocation $ choice
  [token Semicolon $> EmptyStmt
  ,pTypedef TypDecl
  ,VarDecl <$> pVarDecl (\typ name e -> Decl name (VarDef typ e))
  ,ReturnStmt <$> (keyword "return" *> pExpression <*! token Semicolon)
  ,ReturnStmtVoid <$ (keyword "return" *!> token Semicolon)
  ,ExprStmt <$> pExpression <*! token Semicolon
  ,pCompoundStatement
  ,keyword "if" *!> (IfStmt <$> inParens pExpression <*> pStatement <*> pElse)
  ,keyword "while" *!> (WhileStmt <$> inParens pExpression <*> pStatement)
  ,BreakStmt <$ keyword "break"
  ,ContinueStmt <$ keyword "continue"
  ] <|> failParse "Out of luck in pStatement"
pStatement = addLocation $ choice
  [token Semicolon $> EmptyStmt
  ,pTypedef TypDecl
  ,VarDecl <$> pVarDecl (\typ name e -> Decl name (VarDef typ e))
  ,ReturnStmt <$> (keyword "return" *> pExpression <*! token Semicolon)
  ,ReturnStmtVoid <$ (keyword "return" *!> token Semicolon)
  ,ExprStmt <$> pExpression <*! token Semicolon
  ,pCompoundStatement
  ,keyword "if" *!> (IfStmt <$> inParens pExpression <*> pStatement <*> pElse)
  ,keyword "while" *!> (WhileStmt <$> inParens pExpression <*> pStatement)
  ,BreakStmt <$ keyword "break"
  ,ContinueStmt <$ keyword "continue"
  ] <|> failParse "Out of luck in pStatement"
pStatement = addLocation $ choice
  [token Semicolon $> EmptyStmt
  ,pTypedef TypDecl
  ,VarDecl <$> pVarDecl (\typ name e -> Decl name (VarDef typ e))
  ,ReturnStmt <$> (keyword "return" *> pExpression <*! token Semicolon)
  ,ReturnStmtVoid <$ (keyword "return" *!> token Semicolon)
  ,ExprStmt <$> pExpression <*! token Semicolon
  ,pCompoundStatement
  ,keyword "if" *!> (IfStmt <$> inParens pExpression <*> pStatement <*> pElse)
  ,keyword "while" *!> (WhileStmt <$> inParens pExpression <*> pStatement)
  ,BreakStmt <$ keyword "break"
  ,ContinueStmt <$ keyword "continue"
  ] <|> failParse "Out of luck in pStatement"