From: Mattias Waldau
Subject: Parser generator wanted (e.g.SLR(1))
Date: 
Message-ID: <1051@kuling.UUCP>
Parsergenerator that generates simple lisp code understandable by 
GnuEmacs wanted.

Mattias Waldau	E-Mail: ·······@emil.uu.se
Comp. Sc. Dept, Uppsala University, Sweden
-- 
Sverker Janson	E-Mail: ·······@emil.uu.se
Comp. Sc. Dept, Uppsala University, Sweden

From: Daniel F. Boyd
Subject: Re: Parser generator wanted (e.g.SLR(1))
Date: 
Message-ID: <2299@bingvaxu.cc.binghamton.edu>
I wanted to make a couple key commands to do some
transpose-like functions.  One of the professors at the math
department here gave me this module.  Thanks to Craig Squier
for this module.
	I don't know if this is what you wanted, but it's
nice anyway.  Also useful for novices learning Elisp (worked
for me...)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;
;;;; module: 	generate.el	
;;;; version: 	2.0
;;;; author: 	Ciaran A Byrne ······@gec-rl-hrc.co.uk
;;;; date:	2:Sept:87
;;;;
;;;;;;;;;;;;;;;;;;;; macro lisp expansion ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;
;;;;	user commands:
;;;;		start-generating	- replaces start-kbd-macro ^X(
;;;;		stop-generating		-     "	   end-kbd-macro   ^X)
;;;;		expand-macro		- produces REAL emacs lisp code
;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
(defmacro caar (x) (list 'car (list 'car x)))
(defmacro cadr (x) (list 'car (list 'cdr x)))
(defmacro caadr (x) (list 'car (list 'car (list 'cdr x))))
(defmacro caddr (x) (list 'car (list 'cdr (list 'cdr x))))
(defmacro cadar (x) (list 'car (list 'cdr (list 'car x))))

(defmacro cdar (x) (list 'cdr (list 'car x)))
(defmacro cddr (l) "" (list 'cdr (list 'cdr l)))
(defmacro cdadr (x) (list 'cdr (list 'car (list 'cdr x))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; replace macro bindings

(global-set-key "\^X(" 'start-generating)
(global-set-key "\^X)" 'stop-generating)


(defvar gen-history '(first . last) "command-history subsection pair")
(defvar generate-on nil "true if recording commands")


(defun start-generating () "records commands issued
until the command stop-generating is invoked.

The recorded commands can be turned into emacs lisp using
the command expand-macro.

Keystrokes are echoed in the minibuffer to remind you that
you are doing something weird"
 
  (interactive)
  (if generate-on (message "Already generating !")
    (progn
      (setq generate-on t)
      (message "Started generating")
      (rplaca gen-history command-history) ; note beginning of macro
      (unwind-protect
          (command-loop-3)	; run soft command loop
        (stop-generating)))))

(defun stop-generating ()  "Ends command recording.
See also: start-generating
expand-macro"
  
  (interactive)
  (rplacd gen-history  command-history) ; note end of macro
  (message "Stopped generating")
  (setq generate-on nil)
  )

(defun expand-macro (buffer fname doc) "Expands the most recently recorded command sequence
into emacs lisp. Outputs into BUFFER and calls the function NAME
with DOC string.

See also: start-generating, stop-generating"
  
  (interactive "sBuffer for expansion : 
SNew function name : 
sDoc string : ")
  
  (if generate-on (stop-generating))
  
  (let ( (macro (rev-sub-list gen-history)) )	; chop macro out
    
    (get-buffer-create buffer)
    (set-buffer buffer)
    (goto-char (point-max))
    (set-mark (point))
    
    (insert "\n(defun " (symbol-name fname) " () " )   ; function header
    (insert "\"" doc)
    (insert "\nmacroised by " (user-full-name))
    (insert " @ " (current-time-string)  "\"\n")
    (insert "\n(interactive)\n")
    
    (setq standard-output (get-buffer buffer))
    (mapcar 'print macro)
    
    (exchange-point-and-mark)
    
    (mapcar 'delete-matching-lines	; zap useless stuff
            '(   "^$"
                 "start-generating"
                 "stop-generating"
                 "expand-macro"
                 "execute-extended-command nil"
                 ; etc ?
                 )
            )
    
    (narrow-to-region (point) (point-max))
    (emacs-lisp-mode)
    (indent-region (point) (point-max) nil)	; neaten it all up
    
    (mapcar 'merge-multiple-numeric-args
            '(
              previous-line
              next-line
              delete-backward-char
              backward-delete-char-untabify
              backward-kill-word
              kill-word
              forward-char
              backward-char
              ; etc ?
              ))
    
    (goto-char (point-max))
    (insert "\n)\n")
    (widen)
    ))

(defun rev-sub-list (pp) "returns sublist from INTERVAL eg. (beginning . end) ,
where beginning & end point into the same list.
The item at end should be nearer the front of the list.
The car of the result is the element at beginning."
  
  (let ( (stop (car pp))
         (here (cdr pp))
         (result nil)  )
    
    (if (not (memq (car stop) here)) (message "bad arg to rev-sub-list")
      (while (not (eq here stop))
        (setq result (cons (car here) result)) ; build in reverse
        (setq here (cdr here)))
      )
    result))

(defun command-loop-3 () "Mimics the internal command_loop_1,
but locks the RECORD arg to command-execute to true.

Handles universal & prefix arguments, fakes self-insert-command.

Fixes up incremental searches in command-history so that the non-incremental
versions are used instead
"
  (while generate-on			; global flag
    
    (if (null (input-pending-p)) (sit-for 2))
    
    (let* ( (ks (read-key-sequence ""))
            (last-command-char (string-to-char (substring ks -1)))
            (kc (key-binding ks)) )
      
      (cond
       ((eq kc 'universal-argument) (universal-argument))
       
       ((eq kc 'digit-argument) (digit-argument prefix-arg))
       
       ((eq kc 'self-insert-command) (log-self-insert prefix-arg))
       
       ((eq kc 'stop-generating) (stop-generating))
       
       ( t
         (command-execute kc 'record)))
      
      ; now patch search commands
      (cond
       ((eq kc 'isearch-forward)
        (rplaca command-history
                (list 'search-forward search-last-string)))
       
       ((eq kc 'isearch-backward)
        (rplaca command-history
                (list 'search-backward search-last-string)))
       
       ((eq kc 'isearch-forward-regexp)
        (rplaca command-history
                (list 're-search-forward search-last-regexp)))
       
       ((eq kc 'isearch-backward-regexp)
        (rplaca command-history
                (list 're-search-backward search-last-regexp)))
       ))))
 
(defun string-copy (s n) "returns STRING concatted N times"
  (let ( (res "") )
    (while (> n 0)
      (setq res (concat res s))
      (setq n (1- n)))
    res))

(defun log-self-insert (n) "replaces self-insert-command (q.v.)
adds an insert command to command-history,
amalgamates the current insertion with a previous insert command
in command-history, if there is one."
  
  (setq n (if (integerp n) n 1))
  (let ((ins (string-copy (char-to-string last-input-char) n)))
    
    (insert ins)			;do the insertion
    
    ; the comand-history may look like:
    ; ( (insert "t") ... )
    ; if, say, "o" is the last input char, change to just:
    ; (insert "to")
    
    (if (eq 'insert (caar command-history))
        (let* ( (prev (cadar command-history))
                (str (concat prev ins)) )
          
          (rplacd (car command-history) (list str)))
      (setq command-history (cons (list 'insert ins) command-history)))))

(defconst numarg "[ \t]+\\([0-9]+\\)")

(defun merge-multiple-numeric-args (s) "coalesces a pair of lisp lines
invoking the same FUNCTION with a numeric arg so that
a single function with the 2 component args added is used instead.

e.g.
(previous-line 4)
(previous-line 1)	becomes just 	(previous-line 5)
"

(goto-char (point-min))

(if (symbolp s) (setq s (symbol-name s)))

(while
    (re-search-forward 
     (concat s numarg ".*\n[ \t]*(" s numarg) (point-max) t)
  
  (let* ( (md (match-data))
          (arg1 (buffer-substring (nth 2 md) (nth 3 md)))
          (arg2 (buffer-substring (nth 4 md) (nth 5 md)))  
          (newarg (+ (string-to-int arg1) (string-to-int arg2))) )
    
    (delete-region (nth 0 md) (nth 1 md))
    (insert s " " (int-to-string newarg))
    (goto-char (nth 0 md)))))

-- 
Daniel F. Boyd				| "If it wasn't for disappointments,
Student Consultant, SUNY Binghamton     |  I wouldn't have any appointments."
·······@bingvaxu.cc.binghamton.edu	| 	-- They Might Be Giants
From: Mott Given
Subject: Re: Parser generator wanted (e.g.SLR(1))
Date: 
Message-ID: <1497@dsacg1.UUCP>
What is Elisp?  Is it a public domain version of LISP?  Who distributes it
and what types of hardware does it run on?  How does it compare to other
LISPs?  
From: Mott Given
Subject: Re: Parser generator wanted (e.g.SLR(1))
Date: 
Message-ID: <1498@dsacg1.UUCP>
What is Elisp?  Is it public domain?  What types of hardware does it run on?
How does it compare to other versions of LISP?


Mott Given @ Defense Logistics Agency Systems Automation Center,
             DSAC-TMP, Bldg. 27-1, P.O. Box 1605, Columbus, OH 43216-5002
INTERNET:  ······@dsacg1.dla.mil                          I speak for myself
UUCP:      ·······@dsacg1.UUCP
Phone:       614-238-9431     AUTOVON: 850-9431   FAX: 614-238-3214
From: Mott Given
Subject: Re: Parser generator wanted (e.g.SLR(1))
Date: 
Message-ID: <1499@dsacg1.UUCP>
What is Elisp?  Is it public domain?  Who distributes it?  How does it compare
to other types of LISP?


-- 
Mott Given @ Defense Logistics Agency Systems Automation Center,
             DSAC-TMP, Bldg. 27-1, P.O. Box 1605, Columbus, OH 43216-5002
INTERNET:  ······@dsacg1.dla.mil   UUCP: ·······@dsacg1.uucp 
Phone:  614-238-9431  AUTOVON: 850-9431   FAX: 614-238-3214 I speak for myself
From: Mott Given
Subject: Re: Parser generator wanted (e.g.SLR(1))
Date: 
Message-ID: <1500@dsacg1.UUCP>
From article <····@bingvaxu.cc.binghamton.edu>, by ·······@bingvaxu.cc.binghamton.edu (Daniel F. Boyd):
    
    What is Elisp?   
    Is it public domain?
    What types of hardware will it run on?
    How does it compare to other types of LISP?

-- 
Mott Given @ Defense Logistics Agency Systems Automation Center,
             DSAC-TMP, Bldg. 27-1, P.O. Box 1605, Columbus, OH 43216-5002
INTERNET:  ······@dsacg1.dla.mil   UUCP: ·······@dsacg1.uucp 
Phone:  614-238-9431  AUTOVON: 850-9431   FAX: 614-238-3214 I speak for myself
From: Bob Sutterfield
Subject: Re: Parser generator wanted (e.g.SLR(1))
Date: 
Message-ID: <BOB.89Jul19094727@tinman.cis.ohio-state.edu>
In article <····@dsacg1.UUCP> ·······@dsacg1.UUCP (Mott Given) writes:
   What is Elisp?

That generally refers to the version of Lisp inside GNU Emacs.  It's
not unlikely that someone has written a parser generator (in elisp)
that operates on a bufferful of source, producing a bufferful of
parser.

"Emacs: it's not just for editing any more."
"Emacs: the lifestyle"
"Emacs: I've heard there's a text editor in there, too."
"Emacs: it's not just an editor, it's an adventure."

   Is it a public domain version of LISP?

No, but it's free.

   Who distributes it and what types of hardware does it run on?

You can get GNU Emacs via FTP from
prep.ai.mit.edu:pub/gnu/edist.tar-18.54.Z or via UUCP from osu-cis
(we're across town from you, so it's a local call).  Write me for
directions if you need them.

In article <····@dsacg1.UUCP> ·······@dsacg1.UUCP (Mott Given) writes:
   ...
   What types of hardware does it run on?

Nigh onto everything that runs a UNIX(tm)-like operating system, and a
few other things as well.  It won't run on a micro like a PC or a Mac.