Initial Commit
[packages] / xemacs-packages / semantic / wisent / bison-wisent.el
1 ;;; bison-wisent.el --- Translate Yacc/Bison files to wisent
2
3 ;;; Copyright (C) 2002 Eric M. Ludlam
4
5 ;; Author: Eric M. Ludlam <zappo@gnu.org>
6 ;; X-RCS: $Id: bison-wisent.el,v 1.1 2007-11-26 15:12:27 michaels Exp $
7
8 ;; Semantic is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; any later version.
12
13 ;; This software is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
17
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
20 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 ;; Boston, MA 02110-1301, USA.
22
23 ;;; Commentary:
24 ;;
25 ;; Wisent is a port of Bison to Emacs Lisp.  As such, existing
26 ;; grammars as found in GNU tools such as GCC can be used almost in
27 ;; tact.  This program will translate existing yacc/bison grammars
28 ;; into a form wisent can handle.  It is then up to the programmer to
29 ;; add the actions needed to tag a file, or do something else useful.
30
31 ;;; Code:
32 (defalias 'yacc->wisent 'bison->wisent)
33 (require 'cc-mode)
34
35 ;;;###autoload
36 (defun bison->wisent ()
37   "Treat the current buffer as a YACC or BISON file, and translate to wisent.
38 Replaces all comments with wisent compatible comments.
39 Finds % commands that wisent cannot handle, and comments them out.
40 Deletes all actions, replacing them with small comments."
41   (interactive)
42   (with-syntax-table c-mode-syntax-table
43     (bison->wisent-program-delete)
44     (bison->wisent-action-replace)
45     (bison->wisent-comment-replace)
46     (bison->wisent-command-replace)
47     ))
48
49 (defun bison->wisent-program-delete ()
50   "Delete the C program section of a yacc/bison gramar."
51   (goto-char (point-min))
52   (re-search-forward "^%%" nil nil 2)
53   (beginning-of-line)
54   (delete-region (point) (point-max)))
55
56 (defun bison->wisent-in-c-action ()
57   "Return non-nil if point is in a C style yacc/bison action."
58   (condition-case nil
59       (save-excursion
60         (up-list -1)
61         (and (looking-at "{")
62              (not (eq (preceding-char) ?'))
63              (not (eq (preceding-char) ?%))
64              ))
65     (error nil)))
66
67 (defun bison->wisent-action-replace-once ()
68   "Replace one C action with a amall wisent comment.
69 Return t on success."
70   (while (and (re-search-forward "{" nil t)
71               (not (bison->wisent-in-c-action))))
72   (if (not (bison->wisent-in-c-action))
73      nil
74     ;; Replace this action with a small comment
75     (up-list -1)
76     (delete-region (point) (progn
77                              (forward-sexp 1)
78                              (point)))
79     (delete-horizontal-space)
80     (if (not (looking-at "$"))
81         (save-excursion
82           (newline)
83           (indent-for-tab-command)))
84     (insert ";; ")
85     t))
86
87 (defun bison->wisent-action-replace  ()
88   "Find all yacc actions and remove, replace with small comments."
89   (goto-char (point-min))
90   (re-search-forward "^%%" nil t)
91   (while (bison->wisent-action-replace-once)))
92
93
94 (defun bison->wisent-comment-replace-once ()
95   "Replace one C comment with a wisent comment.
96 Return t on success."
97  (if (not (re-search-forward "/\\*" nil t))
98      nil
99    (let ((s (match-beginning 0))
100          (e nil)
101          (c nil))
102      (if (not (re-search-forward "\\*/" nil t))
103          (error "Unterminated comment!"))
104      (setq e (match-end 0))
105      (goto-char (match-beginning 0))
106      (delete-char 2)
107      (delete-horizontal-space)
108      (setq e (point))
109      (if (not (looking-at "$"))
110          (progn (insert "\n")
111                 (indent-for-tab-command)))
112      (goto-char s)
113      (delete-char 2)
114      (setq c (current-column))
115      (insert ";;")
116      (forward-line 1)
117      (beginning-of-line-text)
118      (while (< (point) e)
119        (if (or (looking-at "\\s-\\*")
120                (looking-at "\\*\\s-"))
121            (progn (replace-match ";;")
122                   (goto-char (match-end 0))
123                   )
124          (beginning-of-line-text)
125          (delete-horizontal-space)
126          (indent-to-column c)
127          (insert ";; "))
128        (forward-line 1)
129        (beginning-of-line))
130      (goto-char e)
131      t)))
132
133 (defun bison->wisent-comment-replace ()
134   "Find all the C comments in this buffer and convert them to .wy comments."
135   (goto-char (point-min))
136   (while (bison->wisent-comment-replace-once)))
137
138 (defun bison->wisent-command-replace ()
139   "Find all commands not supported by wisent, and delete them."
140   (goto-char (point-min))
141   (while (re-search-forward "%\\({\\|union\\|type\\)" nil t)
142     (goto-char (match-beginning 0))
143     (let ((txt (match-string 0))
144           (s (point))
145           (e (cond
146               ((looking-at "%{")
147                (forward-sexp 1)
148                (point))
149               ((looking-at "%union")
150                (forward-sexp 2)
151                (point))
152               (t
153                (point-at-eol))
154               )))
155       (delete-region s e)
156       (insert ";; Deleted a " txt " here"))
157     ))
158
159 (provide 'bison-wisent)
160
161 ;;; bison-wisent.el ends here