]> code.delx.au - gnu-emacs-elpa/blobdiff - packages/wisi/wisi-parse.el
Merge commit '469cd3bc117bfb8da0c03a2a2fb185e80c81d068'
[gnu-emacs-elpa] / packages / wisi / wisi-parse.el
index e2b3d86131798e21f4fa72c0126910cc7a19a331..bd7ce7eec216b7383f8db455a4b0dee661451d80 100755 (executable)
@@ -1,6 +1,6 @@
 ;;; wisi-parse.el --- Wisi parser
 
-;; Copyright (C) 2013  Free Software Foundation, Inc.
+;; Copyright (C) 2013, 2014  Free Software Foundation, Inc.
 
 ;; This file is part of GNU Emacs.
 
@@ -26,8 +26,8 @@
 
 ;;; Code:
 
+(require 'cl-lib)
 (require 'semantic/wisent)
-(eval-when-compile (require 'cl-macs))
 
 (cl-defstruct (wisi-parser-state
            (:copier nil))
 If a file needs more than this, it's probably an indication that
 the grammar is excessively redundant.")
 
+(defvar wisi-parse-max-parallel-current (cons 0 0)
+  "Cons (count . point); Maximum number of parallel parsers used in most recent parse,
+point at which that max was spawned.")
+
+(defvar wisi-debug 0
+  "wisi debug mode:
+0 : normal - ignore parse errors, for indenting new code
+1 : report parse errors (for running tests)
+2 : show parse states, position point at parse errors, debug-on-error works in parser
+3 : also show top 10 items of parser stack.")
+
 (defun wisi-parse (automaton lexer)
   "Parse input using the automaton specified in AUTOMATON.
 
@@ -92,9 +103,6 @@ the grammar is excessively redundant.")
            :label 0
            :active  'shift
            :stack   (make-vector wisent-parse-max-stack-size nil)
-           ;; FIXME: better error message when stack overflows, so
-           ;; user can set wisent-parse-max-stack-size in file-local
-           ;; vars.
            :sp      0
            :pending nil)))
         (active-parser-count 1)
@@ -103,6 +111,8 @@ the grammar is excessively redundant.")
         (token (funcall lexer))
         some-pending)
 
+    (setq wisi-parse-max-parallel-current (cons 0 0))
+
     (aset (wisi-parser-state-stack (aref parser-states 0)) 0 0) ;; Initial state
 
     (while (not (eq active 'accept))
@@ -121,14 +131,17 @@ the grammar is excessively redundant.")
              (let ((j (wisi-free-parser parser-states)))
                (cond
                 ((= j -1)
-                 ;; add to parser-states; the new parser won't be executed again in this parser-index loop
+                 ;; Add to parser-states; the new parser won't be executed
+                 ;; again in this parser-index loop.
                  (setq parser-states (vconcat parser-states (vector nil)))
                  (setq j (1- (length parser-states))))
                 ((< j parser-index)
-                 ;; the new parser won't be executed again in this parser-index loop; nothing to do
+                 ;; The new parser won't be executed again in this
+                 ;; parser-index loop; nothing to do.
                  )
                 (t
-                 ;; don't let the new parser execute again in this parser-index loop
+                 ;; Don't let the new parser execute again in this
+                 ;; parser-index loop.
                  (setq some-pending t)
                  (setf (wisi-parser-state-active result)
                        (cl-case (wisi-parser-state-active result)
@@ -137,19 +150,24 @@ the grammar is excessively redundant.")
                         )))
                  )
                (setq active-parser-count (1+ active-parser-count))
+               (when (> active-parser-count (car wisi-parse-max-parallel-current))
+                 (setq wisi-parse-max-parallel-current (cons active-parser-count (point))))
                (setf (wisi-parser-state-label result) j)
                (aset parser-states j result))
-             (when (> wisi-debug 1) (message "spawn parser (%d active)" active-parser-count)))
+             (when (> wisi-debug 1)
+                (message "spawn parser (%d active)" active-parser-count)))
 
            (when (eq 'error (wisi-parser-state-active parser-state))
              (setq active-parser-count (1- active-parser-count))
-             (when (> wisi-debug 1) (message "terminate parser (%d active)" active-parser-count))
+             (when (> wisi-debug 1)
+                (message "terminate parser (%d active)" active-parser-count))
              (cl-case active-parser-count
                (0
                 (cond
                  ((= active-parser-count-prev 1)
-                  ;; we were not in a parallel parse; report the error
-                  (let ((state (aref (wisi-parser-state-stack parser-state) (wisi-parser-state-sp parser-state))))
+                  ;; We were not in a parallel parse; report the error.
+                  (let ((state (aref (wisi-parser-state-stack parser-state)
+                                      (wisi-parser-state-sp parser-state))))
                     (signal 'wisi-parse-error
                             (wisi-error-msg "syntax error in grammar state %d; unexpected %s, expecting one of %s"
                                             state
@@ -157,9 +175,9 @@ the grammar is excessively redundant.")
                                             (mapcar 'car (aref actions state))))
                     ))
                  (t
-                  ;; report errors from all parsers that failed on this token
+                  ;; Report errors from all parsers that failed on this token.
                   (let ((msg))
-                    (dotimes (index (length parser-states))
+                    (dotimes (_ (length parser-states))
                       (let* ((parser-state (aref parser-states parser-index))
                              (state (aref (wisi-parser-state-stack parser-state)
                                           (wisi-parser-state-sp parser-state))))
@@ -177,22 +195,22 @@ the grammar is excessively redundant.")
                  ))
 
                (1
-                (setf (wisi-parser-state-active parser-state) nil); don't save error for later
+                (setf (wisi-parser-state-active parser-state) nil); Don't save error for later.
                 (wisi-execute-pending (wisi-parser-state-pending
                                        (aref parser-states (wisi-active-parser parser-states))))
                 (setf (wisi-parser-state-pending
                        (aref parser-states (wisi-active-parser parser-states)))
                       nil))
                (t
-                ;; we were in a parallel parse, and this parser
+                ;; We were in a parallel parse, and this parser
                 ;; failed; mark it inactive, don't save error for
-                ;; later
+                ;; later.
                 (setf (wisi-parser-state-active parser-state) nil)
                 )))
            )));; end dotimes
 
       (when some-pending
-       ;; change pending-* parsers to *
+       ;; Change pending-* parsers to *.
        (dotimes (parser-index (length parser-states))
          (cond
           ((eq (wisi-parser-state-active (aref parser-states parser-index)) 'pending-shift)
@@ -317,7 +335,16 @@ nil, 'shift, or 'accept."
 (defun wisi-execute-pending (pending)
   (while pending
     (when (> wisi-debug 1) (message "%s" (car pending)))
-    (apply (pop pending))))
+
+    (cond
+     ((and (>= emacs-major-version 24)
+          (>= emacs-minor-version 3))
+      (apply (pop pending)))
+
+     (t
+      (let ((func-args (pop pending)))
+       (apply (car func-args) (cdr func-args))))
+     )))
 
 (defun wisi-parse-1 (token parser-state pendingp actions gotos)
   "Perform one shift or reduce on PARSER-STATE.
@@ -445,4 +472,4 @@ the first and last tokens of the nonterminal."
     ))
 
 (provide 'wisi-parse)
-;; end of file
+;;; wisi-parse.el ends here