Function: ebnf-split-prefix

ebnf-split-prefix is a byte-compiled function defined in ebnf-otz.el.gz.

Signature

(ebnf-split-prefix LIS)

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/ebnf-otz.el.gz
(defun ebnf-split-prefix (lis)
  (let* ((len  (length lis))
	 (tail lis)
	 (head (if (eq (ebnf-node-kind (car lis)) 'ebnf-generate-sequence)
		   (ebnf-node-list (car lis))
		 (list (car lis))))
	 (ipre (1+ len)))
    ;; determine prefix length
    (while (and (> ipre 0) (setq tail (cdr tail)))
      (let ((cur head)
	    (this (if (eq (ebnf-node-kind (car tail)) 'ebnf-generate-sequence)
		      (ebnf-node-list (car tail))
		    (list (car tail))))
	    (i 0))
	(while (and cur this
		    (ebnf-node-equal (car cur) (car this)))
	  (setq cur  (cdr cur)
		this (cdr this)
		i    (1+ i)))
	(setq ipre (min ipre i))))
    (if (or (zerop ipre) (> ipre len))
	;; no prefix at all
	(cons nil lis)
      (let* ((tail   (nthcdr ipre head))
	     ;; get prefix
	     (prefix (progn
		       (and tail
			    (setcdr (nthcdr (1- ipre) head) nil))
		       head))
	     empty-p before)
	;; adjust first element
	(if (or (not (eq (ebnf-node-kind (car lis)) 'ebnf-generate-sequence))
		(null tail))
	    (setq lis     (cdr lis)
		  tail    lis
		  empty-p t)
	  (if (= (length tail) 1)
	      (setcar lis (car tail))
	    (ebnf-node-list (car lis) tail))
	  (setq tail (cdr lis)))
	;; eliminate prefix from lis based on ipre
	(while tail
	  (let ((elt (car tail))
		rest)
	    (if (and (eq (ebnf-node-kind elt) 'ebnf-generate-sequence)
		     (setq rest (nthcdr ipre (ebnf-node-list elt))))
		(progn
		  (if (= (length rest) 1)
		      (setcar tail (car rest))
		    (ebnf-node-list elt rest))
		  (setq before tail))
	      (setq empty-p t)
	      (if before
		  (setcdr before (cdr tail))
		(setq lis (cdr lis))))
	    (setq tail (cdr tail))))
	(cons prefix (ebnf-unique-list
		      (if empty-p
			  (nconc lis (list (ebnf-make-empty)))
			lis)))))))