 
 ;;; Parser functions
 
+(defvar mpd-best (cons 0 0)
+  "The furthest most point that parsing reached. This information
+can be used to determine where parsing failed.")
+
+(defun mpd-set-best ()
+  "Update the current best parsing position."
+  (let* ((cline (line-number-at-pos))
+         (ccol (current-column))
+         (pos (cons cline ccol)))
+    (destructuring-bind (line . col) mpd-best
+        (cond
+         ((> cline line) (setq mpd-best pos))
+         ((and (= cline line) (> ccol col)) (setq mpd-best pos))))))
+
 (defun mpd-get-token-func (token funcs)
   "Get the manipulation function for the given token."
   (or (cdr (assq token funcs)) #'cons))
 
 (defun mpd-parse (tokens &optional funcs pattern)
   "Return the next item in the current buffer."
+  (setq mpd-best (cons 0 0))
   (if pattern
       (mpd-match pattern tokens funcs)
     (dolist (token tokens)

  (save-excursion
    (goto-char (point-min))
    (while (re-search-forward "#[^\n]*\n" nil t)
      (replace-match "" nil nil))))

;;; ParselTongue grammar


                  (symbol (mpd-match-token pattern tokens funcs))
                  (vector (mpd-match-or    pattern tokens funcs)))))
    (unless result
      (mpd-set-best)
      (goto-char start))
    result))

