emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/bison-mode 9dcb46e 02/29: Checking in the current state of


From: ELPA Syncer
Subject: [nongnu] elpa/bison-mode 9dcb46e 02/29: Checking in the current state of bison-mode.
Date: Sun, 29 Aug 2021 10:58:39 -0400 (EDT)

branch: elpa/bison-mode
commit 9dcb46e61e8be5280a7cdf031e14cb33056ffd00
Author: Wilfred Hughes <me@wilfred.me.uk>
Commit: Wilfred Hughes <me@wilfred.me.uk>

    Checking in the current state of bison-mode.
---
 bison-mode.el | 989 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 989 insertions(+)

diff --git a/bison-mode.el b/bison-mode.el
new file mode 100644
index 0000000..51bfaab
--- /dev/null
+++ b/bison-mode.el
@@ -0,0 +1,989 @@
+; -*- Mode: Emacs-Lisp; -*- 
+
+;;;; bison-mode.el --- Major mode for editing bison/yacc files
+;;;; Copyright (C) 1998 Eric Beuscher
+
+;; Author:   Eric Beuscher <beuscher@eecs.tulane.edu>
+;; Created:  2 Feb 1998
+;; Version:  .1 (why not start somewhere besides 1.)
+;; Keywords: bison-mode, yacc-mode
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2 of the License, or 
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;;;;Commentary
+
+;;;; I wrote this since I saw one mode for yacc files out there roaming the
+;;;; world.     I was daunted by the fact the it was written in 1990, and emacs
+;;;; has evolved so much since then (this I assume based on its evolution since
+;;;; i started using it).     So I figured if i wanted one, I should make it
+;;;; myself.     Please excuse idiosyncrasies, as this was my first major mode
+;;;; of this kind.     The indentation code may be a bit weird, I am not sure,
+;;;; it was my first go at doing emacs indentation, so I look at how other
+;;;; modes did it, but then basically did what I thought was right
+
+;;;; I hope this is useful to other hackers, and happy Bison/Yacc hacking
+;;;; If you have ideas/suggestions/problems with this code, I can be reached at
+;;;; beuscher@eecs.tulane.edu 
+
+;;;; Eric --- Sat Mar  7 1:40:20 CDT 1998
+
+
+;;;; Bison Sections:
+;;;; there are five sections to a bison file (if you include the area above the
+;;;; C declarations section.     most everything in this file either does
+;;;; actions based on which section you are deemed to be in, or based on an
+;;;; assumption that the function will only be called from certain sections.
+;;;; the function `bison--section-p' is the section parser
+
+;;;; Indentation:
+;;;; indentations are done based on the section of code you are in.    there is
+;;;; a procedure `bison--within-braced-c-expression-p' that checks for being in
+;;;; C code.    if you are within c-code, indentations should occur based on
+;;;; how you have your C indentation set up.     i am pretty sure this is the
+;;;; case.
+;;;; there are four variables, which control bison indentation within either
+;;;; the bison declarations section or the bison grammar section
+;;;; `bison-rule-separator-column'
+;;;; `bison-rule-separator-column'
+;;;; `bison-decl-type-column'
+;;;; `bison-decl-token-column'
+
+;;;; flaw: indentation works on a per-line basis, unless within braced C sexp,
+;;;; i should fix this someday
+;;;; and to make matters worse, i never took out c-indent-region, so that is
+;;;; still the state of the `indent-region-function' variable
+
+;;;; Electricity:
+;;;; by default, there are electric -colon, -pipe, -open-brace, -close-brace,
+;;;; -semicolon, -percent, -less-than, -greater-than
+;;;; the indentation caused by these work closely with the 4 indentation
+;;;; variables mentioned above.
+;;;; any of these can be turned off individually by setting the appropriate
+;;;; `bison-electric-...' variable.     or all of them can be turned off by
+;;;; setting `bison-all-electricity-off'
+
+;;;; todo:  should make available a way to use C-electricity if in C sexps
+
+
+;;;;  these are the lines i use to set up correct auto-ing
+;;(autoload 'bison-mode "bison-mode.el")
+;;(add-to-set! auto-mode-alist '("\\.y$" . bison-mode))
+
+;;(autoload 'flex-mode "flex-mode")
+;;(add-to-set! auto-mode-alist '("\\.l$" . flex-mode))
+
+
+
+;; *************** dependencies ***************
+
+(require 'derived)                     ;; define-derived-mode
+(require 'flex-mode)                   ;; for flex-mode derivation
+(require 'make-regexp)                 ;; make-regexp
+
+
+;; *************** internal vars ***************
+
+(defvar bison--declarers '("%union" "%token" "%type"
+                          "%left" "%right" "%nonassoc")
+  "commands which can declare a token or state type")
+
+(defvar bison--word-constituent-re "\\(\\sw\\|_\\)")
+(defvar bison--production-re
+  (concat "^" bison--word-constituent-re "+:"))
+
+(defvar bison--pre-c-decls-section 0
+  "section before c-declarations-section, if that section exists")
+(defvar bison--c-decls-section 1
+  "section denoted by %{ and $} for c-declarations at the top of a bison file")
+(defvar bison--bison-decls-section 2
+  "section before the rules section")
+(defvar bison--grammar-rules-section 3
+  "section delimited by %%'s where productions and rules are enumerated")
+(defvar bison--c-code-section 4
+  "section after the second %% where c-code can be placed")
+
+(defvar bison--c-decls-section-opener "%{")
+(defvar bison--c-decls-section-closer "%}")
+(defvar bison--grammar-rules-section-delimeter "%%")
+
+
+;; *************** user-definable vars ***************
+
+(defvar bison-rule-separator-column 8
+  "column for rule and production separators \"|\" and \";\"")
+(defvar bison-rule-enumeration-column 16
+  "column for beginning enumeration of a production's rules")
+(defvar bison-decl-type-column 8
+  "columnn in which tokens' and states' types should be when declared")
+(defvar bison-decl-token-column 24
+  "column in which tokens and states are listed when declared,
+as with %token, %type, ...")
+
+
+(defvar bison-all-electricity-off nil
+  "non-nil means all electric keys will be disabled,
+nil means that a bison-electric-* key will be on or off based on the individual
+key's electric variable")
+
+;;; i know lisp has the dual name spaces, but i find it more aesthetically
+;;; pleasing to not take advantage of that
+(defvar bison-electric-colon-v t
+  "non-nil means use an electric colon")
+(defvar bison-electric-pipe-v t
+  "non-nil means use an electric pipe")
+(defvar bison-electric-open-brace-v t
+  "non-nil means use an electric open-brace")
+(defvar bison-electric-close-brace-v t
+  "non-nil means use an electric close-brace")
+(defvar bison-electric-semicolon-v t
+  "non-nil means use an electric semicolon")
+(defvar bison-electric-percent-v t
+  "non-nil means use an electric percent")
+(defvar bison-electric-less-than-v t
+  "non-nil means use an electric less-than")
+(defvar bison-electric-greater-than-v t
+  "non-nil means use an electric greater-than")
+
+
+(defvar bison-font-lock-keywords-1 c-font-lock-keywords
+  "Basic highlighting for Bison mode.")
+
+(defvar bison-font-lock-keywords-2
+  (append
+   (list
+    (cons (concat "^\\(" (make-regexp bison--declarers) "\\)")
+         '(1 font-lock-keyword-face))
+    )
+   bison-font-lock-keywords-1)
+  "Gaudy highlighting for Bison mode.")
+
+(defvar bison-font-lock-keywords bison-font-lock-keywords-2
+  "Default expressions to highlight in Bison mode")
+
+
+;; *************** utilities ***************
+
+(defun copy-list (ls)
+  "return a new list with the same elements as LS"
+  (cond ((null ls) '())
+       (t (cons (car ls) (copy-list (cdr ls))))))
+
+(defun same-line-p (pt1 pt2 &optional bol eol)
+  (let ((bol (or bol (save-excursion (beginning-of-line) (point))))
+       (eol (or eol (save-excursion (end-of-line) (point)))))
+    (and (<= bol pt1) (<= bol pt2)
+        (>= eol pt1) (>= eol pt2))))
+
+(defun just-no-space ()
+  "Delete all spaces and tabs around point, leaving no spaces."
+  (interactive "*")
+  (skip-chars-backward " \t")
+  (delete-region (point) (progn (skip-chars-forward " \t") (point)))
+  t)
+
+(defun white-space-separation (pt1 pt2)
+  "return t if there is nothing but whitespace between pt1 and pt2 not
+inclusive"
+  (save-excursion
+    (goto-char (+ pt1 1))
+    (not (re-search-forward "[^ \t\n]" pt2 t))))
+
+(defun previous-white-space-p ()
+  "return t if there is whitespace between the beginning of the line and the
+current (point)"
+  (save-excursion
+    (let ((current-point (point)))
+      (beginning-of-line)
+      (if (re-search-forward "\\s " current-point t)
+         t
+       nil))))
+
+(defun previous-non-ws-p ()
+  "return t if there are non-whitespace characters between beginning of line
+and \(point\)"
+  (save-excursion
+    (let ((current-point (point)))
+      (beginning-of-line)
+    (re-search-forward "[^ \t]" current-point t)
+    )))
+
+(defun following-non-ws-p ()
+  "return t if there are non-whitespace characters on the line"
+  (save-excursion
+    (let ((current-point (point)))
+      (end-of-line)
+      (re-search-backward "[^ \t]+" current-point t)
+      )))
+
+(defun line-of-whitespace-p ()
+  "return t if the line consists of nothiing but whitespace, nil otherwise"
+  (save-excursion
+    (let ((eol (progn (end-of-line) (point))))
+      (beginning-of-line)      ;; should already be there anyway
+      (not (re-search-forward "[^ \t\n]" eol t)))))
+
+
+(defun goto-next-non-ws ()
+  "goto and return pt of next non-whitespace character")
+
+;; *************** bison-mode ***************
+
+(define-derived-mode bison-mode flex-mode "Bison"
+  "Major mode for editing bison/yacc files
+
+"
+  ;; try to set the indentation correctly
+  (setq-default c-basic-offset 4)
+  (make-variable-buffer-local 'c-basic-offset)
+
+  (c-set-offset 'knr-argdecl-intro 0)
+  (make-variable-buffer-local 'c-offsets-alist)
+  
+  ;; remove auto and hungry anything
+  (c-toggle-auto-hungry-state -1)
+  (c-toggle-auto-state -1)
+  (c-toggle-hungry-state -1)
+
+  (use-local-map bison-mode-map)
+  
+  (define-key bison-mode-map ":" 'bison-electric-colon)
+  (define-key bison-mode-map "|" 'bison-electric-pipe)
+  (define-key bison-mode-map "{" 'bison-electric-open-brace)
+  (define-key bison-mode-map "}" 'bison-electric-close-brace)
+  (define-key bison-mode-map ";" 'bison-electric-semicolon)
+  (define-key bison-mode-map "%" 'bison-electric-percent)
+  (define-key bison-mode-map "<" 'bison-electric-less-than)
+  (define-key bison-mode-map ">" 'bison-electric-greater-than)
+
+  ;(define-key bison-mode-map [tab] 'bison-indent-command)
+  (define-key bison-mode-map [tab] 'bison-indent-line)
+  ;(define-key bison-mode-map [f10] 'c-indent-command)
+  
+  (make-local-variable 'indent-line-function)
+  (setq indent-line-function 'bison-indent-new-line)
+  (make-local-variable 'comment-start)
+  (make-local-variable 'comment-end)
+  (setq comment-start "/*"
+       comment-end "*/")
+  (make-local-variable 'font-lock-keywords)
+  (setq font-lock-keywords nil)
+  (make-local-variable 'font-lock-defaults)
+  (setq font-lock-defaults '((bison-font-lock-keywords
+                             bison-font-lock-keywords-1
+                             bison-font-lock-keywords-2)
+                            nil nil nil))
+
+)
+
+
+;; *************** section parsers ***************
+
+(defun bison--section-p ()
+  "Return the section that user is currently in"
+  (save-excursion
+    (let ((bound (point)))
+      (beginning-of-buffer)
+      (bison--section-p-helper bound))))
+
+(defun bison--section-p-helper (bound)
+  (if (re-search-forward
+       (concat "^" bison--c-decls-section-opener)
+       bound t)
+      (if (re-search-forward
+               (concat "^" bison--c-decls-section-closer)
+               bound t)
+         (if (re-search-forward
+              (concat "^" bison--grammar-rules-section-delimeter)
+              bound t)
+             (if (re-search-forward
+                  (concat "^" bison--grammar-rules-section-delimeter)
+                  bound t)
+                 bison--c-code-section
+               bison--grammar-rules-section)
+           bison--bison-decls-section)
+       bison--c-decls-section)
+    (if (re-search-forward
+           (concat "^" bison--grammar-rules-section-delimeter)
+           bound t)
+       (if (re-search-forward
+            (concat "^" bison--grammar-rules-section-delimeter)
+            bound t)
+           bison--c-code-section
+         bison--grammar-rules-section)
+      (if (re-search-forward
+          (concat "^" bison--c-decls-section-opener)
+          nil t)
+         bison--pre-c-decls-section
+       (if (re-search-forward
+            (concat "^" bison--grammar-rules-section-delimeter)
+            nil t)
+           bison--bison-decls-section
+         bison--pre-c-decls-section)))))
+
+
+;; *************** syntax parsers ***************
+
+(defun bison--production-p ()
+  "return t if the \(point\) rests immediately after a production"
+  (save-excursion
+    (let ((current-point (point)))
+      (beginning-of-line)
+      (let ((position (re-search-forward
+                      bison--production-re current-point t)))
+       (and position
+            (not (previous-white-space-p))
+            (= position current-point))))))
+
+(defun bison--find-production-opener ()
+  "return and goto the point of the nearest production opener above \(point\)"
+  (re-search-backward bison--production-re nil t))
+  
+
+(defun bison--find-next-production ()
+  "return the position of the beginning of the next production,
+or nil if there isnt one"
+  (save-excursion
+    (if (re-search-forward bison--production-re nil t)
+       (progn
+         (beginning-of-line)
+         (point))
+      nil)))
+
+(defun bison--find-grammar-end ()
+  "return the position of the end of the grammar rules (assuming we are within
+the grammar rules section), or nil if there isnt one"
+  (save-excursion
+    (if (re-search-forward
+        (concat "^" bison--grammar-rules-section-delimeter)
+        nil t)
+       (progn
+         (beginning-of-line)
+         (point))
+      nil)))
+
+(defun bison--find-grammar-begin ()
+  "return the position of the beginning of the grammar rules (assuming we are
+within the grammar rules section), or nil if there isnt one"
+  (save-excursion
+    (if (re-search-backward
+        (concat "^" bison--grammar-rules-section-delimeter)
+        nil t)
+       (point)
+      nil)))
+
+(defun bison--within-started-production-p ()
+  "is used by bison-electric-* functions to determine actions
+return t if within a production, nil if not
+
+a point is within a production if there is some non whitespace text before
+either the beginnings of another production or the end of the grammar rules"
+  (save-excursion
+    (let ((bound (cond ((bison--find-next-production))
+                      ((bison--find-grammar-end))
+                      (t nil))))
+      (if bound
+         (let ((sval (re-search-forward
+                      (concat "\\(\\s \\|" ;; whitespace or
+                                           ;; comments
+                              (regexp-quote comment-start)
+                              "\\(.\\|\n\\)*" ;; comment body
+                              (regexp-quote comment-end)
+                              "\\)+")  ;; end or
+                      bound t)))
+           (if sval
+               (not (= sval bound))
+             nil))
+       nil))))
+
+(defun bison--within-some-sexp-p (starter ender)
+  "return t if the \(point\) is within the sexp marked by the re's STARTER and
+ENDER"
+  (save-excursion
+    (let ((current-point (point)))
+      (if (re-search-backward starter nil t) ;; find nearest starter
+         ;; look for ender, if found, then not within sexp
+         (progn
+           (goto-char (match-end 0))
+           (not (re-search-forward ender current-point t)))))))
+
+(defun bison--within-c-comment-p ()
+  "return t if the point is within a c comment delimited by \"/*\" \"*/\""
+  (bison--within-some-sexp-p (regexp-quote comment-start)
+                            (regexp-quote comment-end)))
+          
+
+(defun bison--within-string-p (&optional point)
+  "
+start from the beginning of the buffer and toggle state as un-escaped \"'s are
+found."
+  (let ((point (or point (point)))
+       (in-p nil))
+    (save-excursion
+      (beginning-of-buffer)
+
+      (while (re-search-forward "[^\\]\"" point t)
+       (setq in-p (not in-p)))
+
+      in-p)))
+       
+;;; bison--within-braced-c-expression-p
+;;; new and improved, no more recursion, does not break when literal strings
+;;; contain un-matched braces
+(defun bison--within-braced-c-expression-p (section)
+  "return t if the point is within an sexp delimited by braces \({,}\)
+"
+  ;;(debug)
+  (save-excursion
+    (bison--within-braced-c-expression-p-h section (point))))
+
+(defun bison--within-braced-c-expression-p-h (section low-pt)
+  "
+Notes:
+save excursion is done higher up, so i dont concern myself here.
+"
+  (cond ((= section bison--pre-c-decls-section) nil)
+       ((= section bison--c-decls-section)
+        (let ((opener (save-excursion (search-backward "%{"))))
+          (bison--within-braced-c-expression-p-h-h opener low-pt)))
+       ((= section bison--bison-decls-section)
+        (let ((opener (save-excursion
+                        (or (search-backward "%}" nil t)
+                            (point-min)))))
+          (bison--within-braced-c-expression-p-h-h opener low-pt)))
+       ((= section bison--grammar-rules-section)
+        (let ((opener (save-excursion (bison--find-production-opener))))
+          (if opener
+              (bison--within-braced-c-expression-p-h-h opener low-pt)
+            nil)))
+       ((= section bison--c-code-section)
+        t)
+;;      (let ((opener (save-excursion (bison--find-production-opener))))
+;;        (if opener
+;;            (bison--within-braced-c-expression-p-h-h
+;;             opener low-pt 1))))
+       ))
+
+(defun bison--within-braced-c-expression-p-h-h (high-pt low-pt)
+  "
+Notes:
+HIGH-PT goes toward (point-min), LOW-PT goes toward (point-max)
+save excursion is done higher up, so i dont concern myself here.
+"
+  (let ((pt (point)))
+    (let ((success nil) (count 1) (done nil))
+      ;; loop until open brace found, that is not in comment or string literal
+      (while (and (not done)
+                 (re-search-backward "[^%]{" high-pt t count)) ;find nearest
+                                                               ;starter
+       (goto-char (match-end 0))
+       (if (or (bison--within-c-comment-p)
+               (bison--within-string-p))
+           
+           (setq count (+ count 1))
+         (progn
+           (setq success t)
+           (setq done t))))
+       
+      (if success
+         (let ((end-pt
+                (condition-case nil
+                    (progn (forward-sexp) (point))
+                  (error nil))))
+           (if end-pt
+               (if (> end-pt low-pt)
+                   t                   ; then in braced-c-exp
+                 nil)
+             t))                       ; if no sexp close brace, then w/in
+       nil))))
+
+
+(defun bison--bison-decl-opener-p (bol eol)
+  "return t if the current line is a bison declaration starter
+\(i.e. has a %type, %token, %right, ...\)"
+  (save-excursion
+    (goto-char bol)
+    (re-search-forward
+     (concat "^" (make-regexp (copy-list bison--declarers))) eol t)))
+
+(defun bison--production-opener-p (bol eol)
+  "return t if the current line is a line that introduces a new production"
+  (save-excursion
+    (goto-char bol)
+    (re-search-forward bison--production-re eol t)))
+
+(defun bison--find-bison-semicolon ()
+  "return the position of next semicolon not within braces, nil otherwise"
+  (save-excursion
+    (if (search-forward ";" nil t)
+       (if (not (bison--within-braced-c-expression-p (bison--section-p)))
+           (point)
+         (bison--find-bison-semicolon))
+      nil)))
+
+(defun bison--within-production-body-p (section)
+  "return t if the \(point\) is within the body of a production
+
+this procedure will fail if it is in a production header"
+  (save-excursion
+    (if (= section bison--grammar-rules-section)
+       (let ((current-point (point)))
+         (if (re-search-backward bison--production-re nil t)
+             t
+           nil))
+      nil)))
+
+(defun bison--production-alternative-p (bol eol section)
+  "return t if the current line contains a \"|\" used to designate a rule
+alternative"
+  (save-excursion
+    (goto-char bol)
+    (if (search-forward "|" eol t)
+       (not (bison--within-braced-c-expression-p section))
+      nil)))
+
+
+;; *************** indent functions ***************
+
+(defun bison--handle-indent-c-sexp (section indent-column bol)
+  (let* ((o-brace (re-search-backward "[^%]{" bol t))
+        )
+    (if o-brace
+       (if (save-excursion
+             (goto-char o-brace)
+             (bison--within-braced-c-expression-p section))
+           (c-indent-line)
+         (if (= (current-indentation) o-brace) ;; if o-brace is first char
+             (if (not (= o-brace indent-column)) ;; but not in right spot
+                 (progn
+                   (back-to-indentation)
+                   (just-no-space)
+                   (indent-to-column indent-column))
+               ;; else all is good
+               )
+           ;; else, non-ws before o-brace, leave it alone
+           ))
+      (c-indent-line))))
+
+(defun bison-indent-new-line (&optional c-sexp)
+  "Indent a fresh line of bison code
+
+assumes indenting a new line, i.e. at column 0
+"
+  (interactive)
+
+  ;;(message "indent new line")
+  (let* ((section (bison--section-p))
+        (c-sexp (or c-sexp (bison--within-braced-c-expression-p section)))
+        )
+    (cond
+     (c-sexp
+      (cond
+       ((= section bison--grammar-rules-section)
+       (c-indent-line
+        (save-excursion
+          (forward-line -1)
+          (let ((bol (save-excursion (beginning-of-line) (point)))
+                (eol (save-excursion (end-of-line) (point))))
+            (if (bison--production-opener-p bol eol)
+                (list
+                 (cons 'defun-block-intro
+                       (progn
+                         (re-search-forward bison--production-re) ; SIGERR
+                         (- (re-search-forward "[^ \t]") ; SIGERR
+                            1))))
+              nil)))))
+      (t (c-indent-line))))
+     ((= section bison--pre-c-decls-section)
+      (c-indent-line))
+;;;     ((= section bison--c-decls-section) ; is on column 0 anyway
+;;;      (indent-to-column 0)
+;;;      )
+     ((= section bison--bison-decls-section)
+      (indent-to-column bison-decl-token-column))
+     ((= section bison--grammar-rules-section)
+      (indent-to-column
+       (save-excursion
+        (let* ((bound (or (save-excursion (bison--find-production-opener))
+                          (bison--find-grammar-begin)))
+               (prev-semi (search-backward ";" bound t))
+               )
+          (if prev-semi
+              (if (bison--within-braced-c-expression-p section) ; CRACK
+                  bison-rule-enumeration-column
+                0)
+            (if (save-excursion (bison--find-production-opener))
+                bison-rule-enumeration-column
+              0))))))
+     ((= section bison--c-code-section)) ;;leave-alone
+     )))
+
+(defun bison-indent-line ()
+  "Indent a line of bison code
+"
+  (interactive)
+  
+  ;;(message "indent-line")
+  (let* ((pos (- (point-max) (point)))
+        (reset-pt (function (lambda ()
+                              (if (> (- (point-max) pos) (point))
+                                  (goto-char (- (point-max) pos))))))
+        (bol (save-excursion (beginning-of-line) (point)))
+        (eol (save-excursion (end-of-line) (point)))
+        )
+    (let* ((section (bison--section-p))
+          (c-sexp (bison--within-braced-c-expression-p section))
+          (ws-line (line-of-whitespace-p))
+          )
+      (cond
+       ;; if you are a line of whitespace, let indent-new-line take care of it
+       (ws-line
+       (bison-indent-new-line c-sexp))
+       
+       ((= section bison--pre-c-decls-section)
+       ;; leave things alone
+       )
+       
+       ((= section bison--c-decls-section)
+       (if c-sexp
+           (bison--handle-indent-c-sexp section 0 bol)
+         (if (not (= (current-indentation) 0))
+             (progn
+               (back-to-indentation)
+               (just-no-space)
+               (function reset-pt)))))
+       
+       ((= section bison--bison-decls-section)
+       (let ((opener (bison--bison-decl-opener-p bol eol)))
+         (cond
+          (opener
+           (goto-char opener)
+           (skip-chars-forward " \t" eol)
+           (if (looking-at "{")
+               (save-excursion
+                 (if (following-non-ws-p)
+                     (progn
+                       (forward-char 1)
+                       (just-no-space)
+                       (newline)
+                       (bison-indent-new-line t))))
+             (let ((complete-type t))
+               (if (looking-at "<")
+                   (progn
+                     (setq complete-type nil)
+                     (if (not (= (current-column) bison-decl-type-column))
+                         (progn
+                           (just-no-space)
+                           (indent-to-column bison-decl-type-column))
+                       (and (re-search-forward
+                             (concat "<" bison--word-constituent-re "+>")
+                             eol t)
+                            (setq complete-type t)))))
+               (and complete-type
+                    (skip-chars-forward " \t" eol)
+                    (looking-at
+                     (concat "\\(" bison--word-constituent-re "\\|'\\)"))
+                    (if (not (= (current-column) bison-decl-token-column))
+                        (progn
+                          (just-no-space)
+                          (indent-to-column bison-decl-token-column))))))
+           (funcall reset-pt))
+          (c-sexp
+           (bison--handle-indent-c-sexp section 0 bol))
+          (t
+           (back-to-indentation)
+           ;; only tab in names, leave comments alone
+           (cond (;; put word-constiuents in bison-decl-token-column
+                  (looking-at bison--word-constituent-re)
+                  (if (not (= (current-column) bison-decl-token-column))
+                      (progn
+                        (just-no-space)
+                        (indent-to-column bison-decl-token-column))))
+                 ;; put/keep close-brace in the 0 column
+                 ((looking-at "}")
+                  (if (not (= (current-column) 0))
+                      (just-no-space)))
+                 ;; leave comments alone
+                 ((looking-at (regexp-quote comment-start)) nil)
+                 ;; else do nothing
+                 )
+           (funcall reset-pt)))))
+       ((= section bison--grammar-rules-section)
+       (cond
+        ((bison--production-opener-p bol eol)
+         (beginning-of-line)
+         (re-search-forward bison--production-re);; SIGERR
+         (if (following-non-ws-p)
+             (if (> (current-column) bison-rule-enumeration-column)
+                 (progn
+                   (just-no-space)
+                   (newline)
+                   (indent-to-column bison-rule-enumeration-column))
+               (save-excursion
+                 (re-search-forward bison--word-constituent-re);; SIGERR
+                 (let ((col (current-column)))
+                   (cond ((> col (+ 1 bison-rule-enumeration-column))
+                          (forward-char -1)
+                          (just-no-space)
+                          (indent-to-column bison-rule-enumeration-column))
+                         ((< col (+ 1 bison-rule-enumeration-column))
+                          (forward-char -1)
+                          (indent-to-column
+                           bison-rule-enumeration-column)))))))
+         (funcall reset-pt))
+        ((bison--production-alternative-p bol eol section)
+         (back-to-indentation);; should put point on "|"
+         (if (not (= (current-column) bison-rule-separator-column))
+             (progn
+               (just-no-space)
+               (indent-to-column bison-rule-separator-column)))
+         (forward-char 1)
+         (if (following-non-ws-p)
+             (save-excursion
+               (re-search-forward bison--word-constituent-re);; SIGERR
+               (let ((col (current-column)))
+                 (cond ((> col (+ 1 bison-rule-enumeration-column))
+                        (forward-char -1)
+                        (just-no-space)
+                        (indent-to-column bison-rule-enumeration-column))
+                       ((< col (+ 1 bison-rule-enumeration-column))
+                        (forward-char -1)
+                        (indent-to-column
+                         bison-rule-enumeration-column))))))
+         (funcall reset-pt))
+        (c-sexp
+         (bison--handle-indent-c-sexp
+          section bison-rule-enumeration-column bol)
+         (funcall reset-pt))
+        ((bison--within-production-body-p section)
+         (back-to-indentation)
+         (if (not (= (current-column) bison-rule-enumeration-column)) 
+             (progn
+               (just-no-space)
+               (indent-to-column
+                bison-rule-enumeration-column)))
+         (funcall reset-pt))
+        (t
+         (let ((cur-ind (current-indentation)))
+           (if (eq (save-excursion (search-backward "}" bol t))
+                   cur-ind)
+               (if (not (= cur-ind bison-rule-enumeration-column))
+                   (progn
+                     (back-to-indentation)
+                     (just-no-space)
+                     (indent-to-column bison-rule-enumeration-column)
+                     (funcall reset-pt)))
+             ;; else leave alone
+             )))))
+       ((= section bison--c-code-section)
+       (c-indent-line))
+       ))))
+  
+;; *************** electric-functions ***************
+
+(defun bison-electric-colon (arg)
+  "If the colon <:> delineates a production,
+   then insert a semicolon on the next line in the BISON-RULE-SEPARATOR-COLUMN,
+       put the cursor in the BISON-RULE-ENUMERATION-COLUMN for the beginning
+       of the rule
+   else just run self-insert-command
+A colon delineates a production by the fact that it is immediately preceded by
+a word(alphanumerics or '_''s), and there is no previous white space.
+"
+  (interactive "P")
+
+  (self-insert-command (prefix-numeric-value arg))
+  (if (and bison-electric-colon-v
+          (not bison-all-electricity-off))
+      (if (and (= bison--grammar-rules-section (bison--section-p))
+              (bison--production-p)
+              (not (bison--within-started-production-p)))
+         (progn
+           (save-excursion             ; put in a closing semicolon
+             (newline)
+             (indent-to-column bison-rule-separator-column)
+             (insert ";"))
+           (save-excursion             ; remove opening whitespace
+             (if (re-search-backward
+                  "\\s "
+                  (save-excursion (beginning-of-line) (point))
+                  t)
+                 (just-no-space)))
+           (if (not (< (current-column) bison-rule-enumeration-column))
+               (newline))
+           (indent-to-column bison-rule-enumeration-column)))
+    ))
+
+(defun bison-electric-pipe (arg)
+  "If the pipe <|> is used as a rule separator within a production,
+   then move it into BISON-RULE-SEPARATOR-COLUMN
+       indent to BISON-RULE-ENUMERATION-COLUMN on the same line
+   else just run self-insert-command
+"
+  (interactive "P")
+
+  (if (and bison-electric-pipe-v
+          (not bison-all-electricity-off)
+          (= bison--grammar-rules-section (bison--section-p))
+          (line-of-whitespace-p)
+          )
+      (progn
+       (beginning-of-line)
+       (just-no-space)
+       (indent-to-column bison-rule-separator-column)
+       (self-insert-command (prefix-numeric-value arg))
+       (indent-to-column bison-rule-enumeration-column)
+       )
+    (self-insert-command (prefix-numeric-value arg))))
+       
+(defun bison-electric-open-brace (arg)
+  "used for the opening brace of a C action definition for production rules,
+if there is only whitespace before \(point\), then put open-brace in
+bison-rule-enumeration-column"
+  (interactive "P")
+
+  (if (and bison-electric-open-brace-v
+          (not bison-all-electricity-off))
+      (let ((section (bison--section-p)))
+       (cond ((and (= section bison--grammar-rules-section)
+                   (not (bison--within-braced-c-expression-p section))
+                   (not (previous-non-ws-p)))
+              (if (not (= (current-column) bison-rule-enumeration-column))
+                  (progn
+                    (just-no-space)
+                    (indent-to-column bison-rule-enumeration-column))))
+             ((and (= section bison--bison-decls-section)
+                   (not (bison--within-braced-c-expression-p section))
+                   (not (previous-non-ws-p)))
+              (if (not (= (current-column) 0))
+                  (progn
+                    (just-no-space)
+                    (indent-to-column 0)))))))
+
+  (self-insert-command (prefix-numeric-value arg)))
+    
+  
+(defun bison-electric-close-brace (arg)
+  "If the close-brace \"}\" is used as the c-declarations section closer
+in \"%}\", then make sure the \"%}\" indents to the beginning of the line"
+  (interactive "P")
+
+  (self-insert-command (prefix-numeric-value arg))
+
+  (if (and bison-electric-close-brace-v
+          (not bison-all-electricity-off))
+      (cond ((search-backward "%}" (- (point) 2) t)
+            (if (= (bison--section-p) bison--c-decls-section)
+                (progn
+                  (just-no-space)
+                  (forward-char 2))    ; for "%}"
+              (forward-char 1)))
+           )))
+
+(defun bison-electric-semicolon (arg)
+  "if the semicolon is used to end a production, then place it in 
+bison-rule-separator-column
+
+a semicolon is deemed to be used for ending a production if it is not found
+within braces
+
+this is just self-insert-command as i have yet to write the actual
+bison-electric-semicolon function yet
+"
+  (interactive "P")
+
+  (self-insert-command (prefix-numeric-value arg)))
+
+(defun bison-electric-percent (arg)
+  "if the percent is a declarer in the bison declaration's section,
+then put it in the 0 column
+"
+  (interactive "P")
+
+  (if (and bison-electric-percent-v
+          (not bison-all-electricity-off))
+      (let ((section (bison--section-p)))
+       (if (and (= section bison--bison-decls-section)
+                (not (bison--within-braced-c-expression-p section))
+                (not (previous-non-ws-p))
+                (not (= (current-column) 0)))
+           (just-no-space))))
+  
+  (self-insert-command (prefix-numeric-value arg)))
+
+(defun bison-electric-less-than (arg)
+  "if the less-than is a type declarer opener for tokens in the bison
+declaration section, then put it in the bison-decl-type-column column
+"
+  (interactive "P")
+
+  (if (and bison-electric-less-than-v
+          (not bison-all-electricity-off))
+      (if (and (= (bison--section-p) bison--bison-decls-section)
+              (bison--bison-decl-opener-p
+               (save-excursion (beginning-of-line) (point))
+               (point)))
+         (progn
+           (just-no-space)
+           (indent-to-column bison-decl-type-column))))
+             
+  (self-insert-command (prefix-numeric-value arg)))
+
+(defun bison-electric-greater-than (arg)
+  "if the greater-than is a type declarer closer for tokens in the bison
+declaration section, then indent to bison-decl-token-column
+"
+  (interactive "P")
+
+  (self-insert-command (prefix-numeric-value arg))
+
+  (if (and bison-electric-greater-than-v
+          (not bison-all-electricity-off))
+      (let ((current-pt (point))
+           (bol (save-excursion (beginning-of-line) (point))))
+       (if (and (= (bison--section-p) bison--bison-decls-section)
+                (bison--bison-decl-opener-p bol (point)))
+           (if (search-backward "<" bol t)
+               (if (re-search-forward
+                    (concat "<" bison--word-constituent-re "+>")
+                    current-pt t)
+                   (if (not (following-non-ws-p))
+                       (progn
+                         (just-no-space)
+                         (indent-to-column bison-decl-token-column)))))))))
+
+;(defun bison-electric-semicolon (arg)
+;  "if the semicolon is used to end a production, then place it in 
+;bison-rule-separator-column
+
+;a semicolon is deemed to be used for ending a production if it is not found
+;within braces
+;"
+;  (interactive "P")
+;  (if (and (not (bison--within-braced-c-expression-p))
+;         (line-of-whitespace-p)
+;         (
+;      (progn
+;      (just-no-space)                 ;; remove extraneous whitespace
+;      (indent-to-column bison-rule-separator-column)))
+
+;  (self-insert-command (prefix-numeric-value arg)))
+
+;; *************** other ***************
+
+;(defun bison--confirm-productions-closed ()
+;  (save-excursion
+;    (goto-char (point-max))
+;    (if (re-search-forward "^%%" nil t)
+
+
+(provide 'bison-mode)
+
+;; *************** end of code ***************



reply via email to

[Prev in Thread] Current Thread [Next in Thread]