Re: pretty-printing with yacc and lex

macrakis@osf.org (Stavros Macrakis)
27 Mar 1996 00:10:17 -0500

          From comp.compilers

Related articles
Source for compiler using yacc/lex wanted platon!fauzan@uunet.uu.net (1996-03-05)
Re: Source for compiler using yacc/lex wanted theedge@sun11.rbg.informatik.th-darmstadt.de (1996-03-22)
Re: pretty-printing with yacc and lex scooter@mccabe.com (Scott Stanchfield) (1996-03-22)
Re: pretty-printing with yacc and lex macrakis@osf.org (1996-03-27)
| List of all articles for this month |
From: macrakis@osf.org (Stavros Macrakis)
Newsgroups: comp.compilers
Date: 27 Mar 1996 00:10:17 -0500
Organization: OSF Research Institute
References: <96-03-042@comp.compilers >96-03-145 96-03-161
Keywords: tools, parse

Scott Stanchfield <scooter@mccabe.com> writes:


      As long as people use _reasonable_ pre-processor definitions, there
      should be no problem pretty-printing code...


Although I dislike "crazy" preprocessor definitions, pretty-printing
in their presence is not that hard. See Emacs Lisp code below
demonstrating how (of course, this isn't a complete implementation).


My code will accept the example given, and even worse cases, e.g.


#define begin {
#define end }


begin
      x := x + 1;
      begin
            g(y);
#if foobar
      end
end
#elif barfoo /* resume #if-level indentation */
            z := z + 1
      end
      f(w);
end
#else
            begin
                  moredepth(x,y,z);
      end end
end
#endif


Of course, it's not perfect....


----------------


-s




----------------


Here's the code:


;;; Bare-bones pretty printer, demonstrating pretty-printing with
;;; C-like token macros.


;;; #define xxx ... defines a macro.


;;; { and } are only indentation depth changers


(defconst indent_tab 3)


(defun do-indent (depth)
    (delete-horizontal-space)
    (insert-char ? (* indent_tab depth)))


(defun do-indent-buf ()
    (interactive)
    (goto-char (point-min))
    (let ((depth 0) (depth-stack ()))
        (while (not (eobp))
            (cond ((looking-at "^#define \\([a-z]+\\)") ;handle macro defn
(put (intern (match-string 1))
'cmacro
(progn (goto-char (match-end 0))
(tokens-to-eol))))
((looking-at "^#if\\b") (forward-line 1)
(setq depth-stack (cons depth depth-stack)))
((looking-at "^#else\\b") (forward-line 1)
(setq depth (car depth-stack)))
((looking-at "^#endif\\b") (forward-line 1)
(setq depth (car depth-stack)
depth-stack (cdr depth-stack)))
(t
(do-indent depth)
(let ((line (tokens-to-eol))
(carline)
(closersonlyp t))
(while line
(setq carline (car line) line (cdr line))
(cond ((eq carline '\{)
(setq depth (1+ depth) closersonlyp nil))
((eq carline '\}) (setq depth (1- depth)))
((get carline 'cmacro)
(setq line (append (get carline 'cmacro) line)))
(t (setq closersonlyp nil))))
(if closersonlyp
(save-excursion (beginning-of-line 0)
(do-indent depth)))))))))


(defun tokens-to-eol ()
    (let (line)
        (while (looking-at "[, ]*\\([^, {}\n]+\\|[{}]\\)[, ]*")
            (setq line (cons (intern (match-string 1)) line))
            (goto-char (match-end 0)))
        (beginning-of-line 2)
        (nreverse line)))


--


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.