Mercurial > emacs
comparison lisp/progmodes/antlr-mode.el @ 29289:9ad79f5782af
New commands: hide/unhide actions,
upcase/downcase literals.
(antlr-tiny-action-length): New user option.
(antlr-hide-actions): New command. Suggested by
Bjoern Mielenhausen <Bjoern.Mielenhausen@sap.com>.
(antlr-mode-map): New binding [C-c C-v].
(antlr-mode-menu): New entries.
(antlr-downcase-literals): New command.
(antlr-upcase-literals): Ditto.
Minor changes: indendation, mode-name.
(antlr-indent-line): Indent cpp directive at column 0.
(antlr-mode): Use mode-name prefix "Antlr." instead of "Antlr/".
XEmacs bug workaround, XEmacs hint.
(antlr-font-lock-additional-keywords): Workaround for intentional
bug in XEmacs version of font-lock.
(antlr-mode): Set symbol property `mode-name' to "Antlr". Could
be used by a smarter version of `buffers-menu-grouping-function'.
author | Gerd Moellmann <gerd@gnu.org> |
---|---|
date | Mon, 29 May 2000 15:49:05 +0000 |
parents | 048db40ddca6 |
children | 075cc818f566 |
comparison
equal
deleted
inserted
replaced
29288:dbb0996702bd | 29289:9ad79f5782af |
---|---|
1 ;;; antlr-mode.el --- Major mode for ANTLR grammar files | 1 ;;; antlr-mode.el --- Major mode for ANTLR grammar files |
2 | 2 |
3 ;; Copyright (C) 1999 Free Software Foundation, Inc. | 3 ;; Copyright (C) 1999-2000 Free Software Foundation, Inc. |
4 ;; | 4 ;; |
5 ;; Author: Christoph.Wedler@sap.com | 5 ;; Author: Christoph.Wedler@sap.com |
6 ;; Version: $Id: antlr-mode.el,v 1.2 1999/12/16 19:30:34 wedler Exp $ | 6 ;; Version: $Id: antlr-mode.el,v 1.2 1999/12/16 19:30:34 wedler Exp $ |
7 ;; X-URL: http://www.fmi.uni-passau.de/~wedler/antlr-mode/ | 7 ;; X-URL: http://www.fmi.uni-passau.de/~wedler/antlr-mode/ |
8 | 8 |
45 ;; `antlr-indent-line'. The indentation engine of cc-mode is only used inside | 45 ;; `antlr-indent-line'. The indentation engine of cc-mode is only used inside |
46 ;; block comments (it is not easy to use it for actions, esp if they come early | 46 ;; block comments (it is not easy to use it for actions, esp if they come early |
47 ;; in the rule body). By default, this package uses TABs for a basic offset of | 47 ;; in the rule body). By default, this package uses TABs for a basic offset of |
48 ;; 4 to be consistent to both ANTLR's conventions (TABs usage) and the | 48 ;; 4 to be consistent to both ANTLR's conventions (TABs usage) and the |
49 ;; `c-indentation-style' "java" which sets `c-basic-offset' to 4, see | 49 ;; `c-indentation-style' "java" which sets `c-basic-offset' to 4, see |
50 ;; `antlr-tab-offset-alist'. | 50 ;; `antlr-tab-offset-alist'. You might want to set this variable to nil. |
51 | 51 |
52 ;; SYNTAX COLORING comes in three phases. First, comments and strings are | 52 ;; SYNTAX COLORING comes in three phases. First, comments and strings are |
53 ;; highlighted. Second, the grammar code is highlighted according to | 53 ;; highlighted. Second, the grammar code is highlighted according to |
54 ;; `antlr-font-lock-additional-keywords' (rule refs: blue, token refs: brown, | 54 ;; `antlr-font-lock-additional-keywords' (rule refs: blue, token refs: brown, |
55 ;; definition: ditto+bold). Third, actions, semantic predicates and arguments | 55 ;; definition: ditto+bold). Third, actions, semantic predicates and arguments |
75 | 75 |
76 ;; If you edit ANTLR's source files, you might also want to use | 76 ;; If you edit ANTLR's source files, you might also want to use |
77 ;; (autoload 'antlr-set-tabs "antlr-mode") | 77 ;; (autoload 'antlr-set-tabs "antlr-mode") |
78 ;; (add-hook 'java-mode-hook 'antlr-set-tabs) | 78 ;; (add-hook 'java-mode-hook 'antlr-set-tabs) |
79 | 79 |
80 ;; I strongly recommend to use font-lock with a support mode like fast-lock, | |
81 ;; lazy-lock or better jit-lock (Emacs-21.1+) / lazy-shot (XEmacs). | |
82 | |
80 ;; To customize, use `M-x customize-group RET antlr RET' or the custom browser | 83 ;; To customize, use `M-x customize-group RET antlr RET' or the custom browser |
81 ;; (Emacs->Programming->Languages->Antlr). | 84 ;; (Emacs->Programming->Languages->Antlr). |
82 | 85 |
83 ;;; Code: | 86 ;;; Code: |
84 | 87 |
85 (provide 'antlr-mode) | 88 (provide 'antlr-mode) |
86 (eval-when-compile (require 'cl)) | 89 (eval-when-compile (require 'cc-mode)) ; shut up most warnings |
87 (require 'easymenu) ; Emacs | 90 (require 'easymenu) ; Emacs |
88 (eval-when-compile (require 'cc-mode)) ; shut up most warnings | 91 (eval-when-compile ; optional libraries |
92 (defvar outline-level) (defvar imenu-use-markers)) | |
93 (eval-when-compile ; Emacs: cl, XEmacs vars | |
94 (require 'cl)) | |
95 (eval-when-compile ; XEmacs: Emacs vars | |
96 (defvar inhibit-point-motion-hooks) (defvar deactivate-mark)) | |
89 | 97 |
90 (eval-and-compile | 98 (eval-and-compile |
91 (if (string-match "XEmacs" emacs-version) | 99 (if (string-match "XEmacs" emacs-version) |
92 (defalias 'antlr-scan-sexps 'scan-sexps) | 100 (defalias 'antlr-scan-sexps 'scan-sexps) |
93 (defalias 'antlr-scan-sexps 'antlr-scan-sexps-internal)) | 101 (defalias 'antlr-scan-sexps 'antlr-scan-sexps-internal)) |
111 :group 'languages | 119 :group 'languages |
112 :link '(emacs-commentary-link "antlr-mode.el") | 120 :link '(emacs-commentary-link "antlr-mode.el") |
113 :link '(url-link "http://www.fmi.uni-passau.de/~wedler/antlr-mode/") | 121 :link '(url-link "http://www.fmi.uni-passau.de/~wedler/antlr-mode/") |
114 :prefix "antlr-") | 122 :prefix "antlr-") |
115 | 123 |
116 (defconst antlr-version "1.2" | 124 (defconst antlr-version "1.3" |
117 "ANTLR major mode version number.") | 125 "ANTLR major mode version number.") |
118 | 126 |
119 | 127 |
120 ;;;=========================================================================== | 128 ;;;=========================================================================== |
121 ;;; Controlling ANTLR's code generator (language option) | 129 ;;; Controlling ANTLR's code generator (language option) |
160 | 168 |
161 | 169 |
162 ;;;=========================================================================== | 170 ;;;=========================================================================== |
163 ;;; Indent/Tabs | 171 ;;; Indent/Tabs |
164 ;;;=========================================================================== | 172 ;;;=========================================================================== |
173 | |
174 (defcustom antlr-tiny-action-length 3 | |
175 "Maximal number of characters in actions never to hide. | |
176 See command `antlr-hide-actions'." | |
177 :group 'antlr | |
178 :type 'integer) | |
165 | 179 |
166 (defcustom antlr-indent-comment 'tab | 180 (defcustom antlr-indent-comment 'tab |
167 "*Non-nil, if the indentation should touch lines in block comments. | 181 "*Non-nil, if the indentation should touch lines in block comments. |
168 If nil, no continuation line of a block comment is changed. If t, they | 182 If nil, no continuation line of a block comment is changed. If t, they |
169 are changed according to `c-indentation-line'. When not nil and not t, | 183 are changed according to `c-indentation-line'. When not nil and not t, |
217 (define-key map "\C-c\C-a" 'antlr-beginning-of-body) | 231 (define-key map "\C-c\C-a" 'antlr-beginning-of-body) |
218 (define-key map "\C-c\C-e" 'antlr-end-of-body) | 232 (define-key map "\C-c\C-e" 'antlr-end-of-body) |
219 (define-key map "\C-c\C-f" 'c-forward-into-nomenclature) | 233 (define-key map "\C-c\C-f" 'c-forward-into-nomenclature) |
220 (define-key map "\C-c\C-b" 'c-backward-into-nomenclature) | 234 (define-key map "\C-c\C-b" 'c-backward-into-nomenclature) |
221 (define-key map "\C-c\C-c" 'comment-region) | 235 (define-key map "\C-c\C-c" 'comment-region) |
236 (define-key map "\C-c\C-v" 'antlr-hide-actions) | |
222 ;; I'm too lazy to define my own: | 237 ;; I'm too lazy to define my own: |
223 (define-key map "\ea" 'c-beginning-of-statement) | 238 (define-key map "\ea" 'c-beginning-of-statement) |
224 (define-key map "\ee" 'c-end-of-statement) | 239 (define-key map "\ee" 'c-end-of-statement) |
225 map) | 240 map) |
226 "Keymap used in `antlr-mode' buffers.") | 241 "Keymap used in `antlr-mode' buffers.") |
249 :active (antlr-inside-rule-p)] | 264 :active (antlr-inside-rule-p)] |
250 "---" | 265 "---" |
251 ["Backward Statement" c-beginning-of-statement t] | 266 ["Backward Statement" c-beginning-of-statement t] |
252 ["Forward Statement" c-end-of-statement t] | 267 ["Forward Statement" c-end-of-statement t] |
253 ["Backward Into Nomencl." c-backward-into-nomenclature t] | 268 ["Backward Into Nomencl." c-backward-into-nomenclature t] |
254 ["Forward Into Nomencl." c-forward-into-nomenclature t])) | 269 ["Forward Into Nomencl." c-forward-into-nomenclature t] |
270 "---" | |
271 ["Hide Actions (incl. Args)" antlr-hide-actions t] | |
272 ["Hide Actions (excl. Args)" (antlr-hide-actions 2) t] | |
273 ["Unhide All Actions" (antlr-hide-actions 0) t])) | |
255 | 274 |
256 | 275 |
257 ;;;=========================================================================== | 276 ;;;=========================================================================== |
258 ;;; font-lock | 277 ;;; font-lock |
259 ;;;=========================================================================== | 278 ;;;=========================================================================== |
347 (1 antlr-font-lock-tokendef-face)) | 366 (1 antlr-font-lock-tokendef-face)) |
348 ("\\$\\sw+" (0 font-lock-keyword-face)) | 367 ("\\$\\sw+" (0 font-lock-keyword-face)) |
349 ;; the tokens are already fontified as string/docstrings: | 368 ;; the tokens are already fontified as string/docstrings: |
350 (,(lambda (limit) | 369 (,(lambda (limit) |
351 (antlr-re-search-forward "\"\\(\\sw\\(\\sw\\|-\\)*\\)\"" limit)) | 370 (antlr-re-search-forward "\"\\(\\sw\\(\\sw\\|-\\)*\\)\"" limit)) |
352 (1 antlr-font-lock-literal-face t)) | 371 (1 antlr-font-lock-literal-face t) |
372 ,@(and (string-match "XEmacs" emacs-version) | |
373 '((0 nil)))) ; XEmacs bug workaround | |
353 (,(lambda (limit) | 374 (,(lambda (limit) |
354 (antlr-re-search-forward | 375 (antlr-re-search-forward |
355 "^\\(class\\)[ \t]+\\([A-Z\300-\326\330-\337]\\sw*\\)[ \t]+\\(extends\\)[ \t]+\\([A-Z\300-\326\330-\337]\\sw*\\)[ \t]*;" limit)) | 376 "^\\(class\\)[ \t]+\\([A-Z\300-\326\330-\337]\\sw*\\)[ \t]+\\(extends\\)[ \t]+\\([A-Z\300-\326\330-\337]\\sw*\\)[ \t]*;" limit)) |
356 (1 antlr-font-lock-keyword-face) | 377 (1 antlr-font-lock-keyword-face) |
357 (2 antlr-font-lock-ruledef-face) | 378 (2 antlr-font-lock-ruledef-face) |
500 and `replace-match'." | 521 and `replace-match'." |
501 ;; WARNING: Should only be used with `antlr-action-syntax-table'! | 522 ;; WARNING: Should only be used with `antlr-action-syntax-table'! |
502 (let ((continue t)) | 523 (let ((continue t)) |
503 (while (and (re-search-forward regexp bound 'limit) | 524 (while (and (re-search-forward regexp bound 'limit) |
504 (save-match-data | 525 (save-match-data |
505 (if (eq (antlr-syntactic-context) 0) (setq continue nil) t)))) | 526 (if (eq (antlr-syntactic-context) 0) |
527 (setq continue nil) | |
528 t)))) | |
506 (if continue nil (point)))) | 529 (if continue nil (point)))) |
507 | 530 |
508 (defun antlr-search-forward (string) | 531 (defun antlr-search-forward (string) |
509 "Search forward from point for STRING. | 532 "Search forward from point for STRING. |
510 Set point to the end of the occurrence found, and return point. Return | 533 Set point to the end of the occurrence found, and return point. Return |
778 (interactive) | 801 (interactive) |
779 (antlr-end-of-body "Class headers and the file prelude are without `:'")) | 802 (antlr-end-of-body "Class headers and the file prelude are without `:'")) |
780 | 803 |
781 | 804 |
782 ;;;=========================================================================== | 805 ;;;=========================================================================== |
806 ;;; Literal normalization, Hide Actions | |
807 ;;;=========================================================================== | |
808 | |
809 (defun antlr-downcase-literals (&optional transform) | |
810 "Convert all literals in buffer to lower case. | |
811 If non-nil, TRANSFORM is used on literals instead of `downcase-region'." | |
812 (interactive) | |
813 (or transform (setq transform 'downcase-region)) | |
814 (let ((literals 0)) | |
815 (save-excursion | |
816 (goto-char (point-min)) | |
817 (antlr-with-syntax-table antlr-action-syntax-table | |
818 (antlr-invalidate-context-cache) | |
819 (while (antlr-re-search-forward "\"\\(\\sw\\(\\sw\\|-\\)*\\)\"" nil) | |
820 (funcall transform (match-beginning 0) (match-end 0)) | |
821 (incf literals)))) | |
822 (message "Transformed %d literals" literals))) | |
823 | |
824 (defun antlr-upcase-literals () | |
825 "Convert all literals in buffer to upper case." | |
826 (interactive) | |
827 (antlr-downcase-literals 'upcase-region)) | |
828 | |
829 (defun antlr-hide-actions (arg &optional silent) | |
830 "Hide or unhide all actions in buffer. | |
831 Hide all actions including arguments in brackets if ARG is 1 or if | |
832 called interactively without prefix argument. Hide all actions | |
833 excluding arguments in brackets if ARG is 2 or higher. Unhide all | |
834 actions if ARG is 0 or negative. Never hide actions whose character | |
835 length is shorter or equal to `antlr-tiny-action-length'." | |
836 (interactive "p") | |
837 ;; from Emacs/lazy-lock: `save-buffer-state' | |
838 (let ((modified (buffer-modified-p)) | |
839 (buffer-undo-list t) (inhibit-read-only t) | |
840 (inhibit-point-motion-hooks t) deactivate-mark ; Emacs only | |
841 before-change-functions after-change-functions | |
842 buffer-file-name buffer-file-truename) | |
843 (if (> arg 0) | |
844 (let ((regexp (if (= arg 1) "[]}]" "}")) | |
845 (diff (+ (max antlr-tiny-action-length 0) 2))) | |
846 (antlr-hide-actions 0 t) | |
847 (save-excursion | |
848 (goto-char (point-min)) | |
849 (antlr-with-syntax-table antlr-action-syntax-table | |
850 (antlr-invalidate-context-cache) | |
851 (while (antlr-re-search-forward regexp nil) | |
852 (let* ((end (point)) | |
853 (beg (antlr-scan-sexps (point) -1 nil t))) | |
854 (and beg (> end (+ beg diff)) | |
855 (add-text-properties (1+ beg) (1- end) | |
856 '(invisible t intangible t))))))) | |
857 (or silent | |
858 (message "Hide all actions (%s arguments)...done" | |
859 (if (= arg 1) "including" "excluding")))) | |
860 (remove-text-properties (point-min) (point-max) | |
861 '(invisible nil intangible nil)) | |
862 (or silent | |
863 (message "Unhide all actions (including arguments)...done"))) | |
864 (and (not modified) (buffer-modified-p) | |
865 (set-buffer-modified-p nil)))) | |
866 | |
867 | |
868 ;;;=========================================================================== | |
783 ;;; Indentation | 869 ;;; Indentation |
784 ;;;=========================================================================== | 870 ;;;=========================================================================== |
785 | 871 |
786 (defun antlr-indent-line () | 872 (defun antlr-indent-line () |
787 "Indent the current line as ANTLR grammar code. | 873 "Indent the current line as ANTLR grammar code. |
803 ;; check syntax at beginning of indentation ------------------------------ | 889 ;; check syntax at beginning of indentation ------------------------------ |
804 (antlr-with-syntax-table antlr-action-syntax-table | 890 (antlr-with-syntax-table antlr-action-syntax-table |
805 (antlr-invalidate-context-cache) | 891 (antlr-invalidate-context-cache) |
806 (cond ((symbolp (setq syntax (antlr-syntactic-context))) | 892 (cond ((symbolp (setq syntax (antlr-syntactic-context))) |
807 (setq indent nil)) ; block-comments, strings, (comments) | 893 (setq indent nil)) ; block-comments, strings, (comments) |
894 ((eq (char-after) ?#) ; cpp directive | |
895 (setq syntax 'cpp) | |
896 (setq indent 0)) ; indentation at 0 | |
808 ((progn | 897 ((progn |
809 (antlr-next-rule -1 t) | 898 (antlr-next-rule -1 t) |
810 (if (antlr-search-forward ":") (< boi (1- (point))) t)) | 899 (if (antlr-search-forward ":") (< boi (1- (point))) t)) |
811 (setq indent 0)) ; in rule header | 900 (setq indent 0)) ; in rule header |
812 ((if (antlr-search-forward ";") (< boi (point)) t) | 901 ((if (antlr-search-forward ";") (< boi (point)) t) |
822 (and (eq antlr-indent-comment t) | 911 (and (eq antlr-indent-comment t) |
823 (not (eq syntax 'string)) | 912 (not (eq syntax 'string)) |
824 (c-indent-line))) | 913 (c-indent-line))) |
825 ;; do it ourselves | 914 ;; do it ourselves |
826 (goto-char boi) | 915 (goto-char boi) |
827 (antlr-invalidate-context-cache) | 916 (unless (symbolp syntax) ; direct indentation |
828 (incf indent (antlr-syntactic-context)) | 917 (antlr-invalidate-context-cache) |
829 (and (> indent 0) (looking-at antlr-indent-item-regexp) (decf indent)) | 918 (incf indent (antlr-syntactic-context)) |
830 (setq indent (* indent c-basic-offset)) | 919 (and (> indent 0) (looking-at antlr-indent-item-regexp) (decf indent)) |
920 (setq indent (* indent c-basic-offset))) | |
831 ;; the usual major-mode indent stuff: | 921 ;; the usual major-mode indent stuff: |
832 (setq orig (- (point-max) orig)) | 922 (setq orig (- (point-max) orig)) |
833 (unless (= (current-column) indent) | 923 (unless (= (current-column) indent) |
834 (delete-region bol boi) | 924 (delete-region bol boi) |
835 (beginning-of-line) | 925 (beginning-of-line) |
949 t) | 1039 t) |
950 (antlr-language-for-option (match-string 1))) | 1040 (antlr-language-for-option (match-string 1))) |
951 (antlr-language-for-option nil)))))) | 1041 (antlr-language-for-option nil)))))) |
952 (if (stringp (cadr (assq antlr-language antlr-language-alist))) | 1042 (if (stringp (cadr (assq antlr-language antlr-language-alist))) |
953 (setq mode-name | 1043 (setq mode-name |
954 (concat "Antlr/" | 1044 (concat "Antlr." |
955 (cadr (assq antlr-language antlr-language-alist))))) | 1045 (cadr (assq antlr-language antlr-language-alist))))) |
956 ;; indentation, for the C engine ------------------------------------------- | 1046 ;; indentation, for the C engine ------------------------------------------- |
957 (antlr-c-common-init) | 1047 (antlr-c-common-init) |
958 (setq indent-line-function 'antlr-indent-line | 1048 (setq indent-line-function 'antlr-indent-line |
959 indent-region-function nil) ; too lazy | 1049 indent-region-function nil) ; too lazy |
989 (imenu-add-to-menubar | 1079 (imenu-add-to-menubar |
990 (if (stringp antlr-imenu-name) antlr-imenu-name "Index"))) | 1080 (if (stringp antlr-imenu-name) antlr-imenu-name "Index"))) |
991 (antlr-set-tabs) | 1081 (antlr-set-tabs) |
992 (run-hooks 'antlr-mode-hook)) | 1082 (run-hooks 'antlr-mode-hook)) |
993 | 1083 |
1084 ;; In XEmacs, a smarter version of `buffers-menu-grouping-function' could use | |
1085 ;; the following property. The header of the submenu would be "Antlr" instead | |
1086 ;; of "Antlr/C++" or "Antlr/Java" (depending on the buffer ordering). | |
1087 (put 'antlr-mode 'mode-name "Antlr") | |
1088 | |
994 ;;;###autoload | 1089 ;;;###autoload |
995 (defun antlr-set-tabs () | 1090 (defun antlr-set-tabs () |
996 "Use ANTLR's convention for TABs according to `antlr-tab-offset-alist'. | 1091 "Use ANTLR's convention for TABs according to `antlr-tab-offset-alist'. |
997 Used in `antlr-mode'. Also a useful function in `java-mode-hook'." | 1092 Used in `antlr-mode'. Also a useful function in `java-mode-hook'." |
998 (if buffer-file-name | 1093 (if buffer-file-name |