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