]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/ebnf2ps.el
(compilation-mode-map): Bind toggle-next-error-follow-mode.
[gnu-emacs] / lisp / progmodes / ebnf2ps.el
index a069b83b15d01c127337e4b427b6c1ed47908570..e45a7ee510e23e309024e0d1ee8c32cbbd3509ac 100644 (file)
@@ -1,12 +1,13 @@
 ;;; ebnf2ps.el --- translate an EBNF to a syntactic chart on PostScript
 
 ;;; ebnf2ps.el --- translate an EBNF to a syntactic chart on PostScript
 
-;; Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+;; Free Software Foundation, Inc.
 
 
-;; Author: Vinicius Jose Latorre <vinicius@cpqd.com.br>
-;; Maintainer: Vinicius Jose Latorre <vinicius@cpqd.com.br>
+;; Author: Vinicius Jose Latorre <viniciusjl@ig.com.br>
+;; Maintainer: Vinicius Jose Latorre <viniciusjl@ig.com.br>
+;; Time-stamp: <2004/04/04 21:40:30 vinicius>
 ;; Keywords: wp, ebnf, PostScript
 ;; Keywords: wp, ebnf, PostScript
-;; Time-stamp: <2003/08/08 23:09:36 vinicius>
-;; Version: 3.6.1
+;; Version: 4.2
 ;; X-URL: http://www.cpqd.com.br/~vinicius/emacs/
 
 ;; This file is part of GNU Emacs.
 ;; X-URL: http://www.cpqd.com.br/~vinicius/emacs/
 
 ;; This file is part of GNU Emacs.
 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
-(defconst ebnf-version "3.6.1"
-  "ebnf2ps.el, v 3.6.1 <2001/09/24 vinicius>
+(defconst ebnf-version "4.2"
+  "ebnf2ps.el, v 4.2 <2004/04/04 vinicius>
 
 Vinicius's last change version.  When reporting bugs, please also
 report the version of Emacs, if any, that ebnf2ps was running with.
 
 Please send all bug fixes and enhancements to
 
 Vinicius's last change version.  When reporting bugs, please also
 report the version of Emacs, if any, that ebnf2ps was running with.
 
 Please send all bug fixes and enhancements to
-       Vinicius Jose Latorre <vinicius@cpqd.com.br>.
+       Vinicius Jose Latorre <viniciusjl@ig.com.br>.
 ")
 
 
 ")
 
 
@@ -69,13 +70,19 @@ Please send all bug fixes and enhancements to
 ;; Using ebnf2ps
 ;; -------------
 ;;
 ;; Using ebnf2ps
 ;; -------------
 ;;
-;; ebnf2ps provides six commands for generating PostScript syntactic chart
-;; images of Emacs buffers:
+;; ebnf2ps provides the following commands for generating PostScript syntactic
+;; chart images of Emacs buffers:
 ;;
 ;;
+;;     ebnf-print-directory
+;;     ebnf-print-file
 ;;     ebnf-print-buffer
 ;;     ebnf-print-region
 ;;     ebnf-print-buffer
 ;;     ebnf-print-region
+;;     ebnf-spool-directory
+;;     ebnf-spool-file
 ;;     ebnf-spool-buffer
 ;;     ebnf-spool-region
 ;;     ebnf-spool-buffer
 ;;     ebnf-spool-region
+;;     ebnf-eps-directory
+;;     ebnf-eps-file
 ;;     ebnf-eps-buffer
 ;;     ebnf-eps-region
 ;;
 ;;     ebnf-eps-buffer
 ;;     ebnf-eps-region
 ;;
@@ -110,12 +117,16 @@ Please send all bug fixes and enhancements to
 ;; you'll be asked to confirm the exit; this is modeled on the confirmation
 ;; that Emacs uses for modified buffers.
 ;;
 ;; you'll be asked to confirm the exit; this is modeled on the confirmation
 ;; that Emacs uses for modified buffers.
 ;;
-;; The word "buffer" or "region" in the command name determines how much of the
-;; buffer is printed:
+;; The word "directory", "file", "buffer" or "region" in the command name
+;; determines how much of the buffer is printed:
 ;;
 ;;
-;;     buffer  - Print the entire buffer.
+;;     directory  - Read files in the directory and print them.
 ;;
 ;;
-;;     region  - Print just the current region.
+;;     file       - Read file and print it.
+;;
+;;     buffer     - Print the entire buffer.
+;;
+;;     region     - Print just the current region.
 ;;
 ;; Two ebnf- command examples:
 ;;
 ;;
 ;; Two ebnf- command examples:
 ;;
@@ -126,9 +137,10 @@ Please send all bug fixes and enhancements to
 ;;                          spool the image in Emacs to send to the printer
 ;;                          later.
 ;;
 ;;                          spool the image in Emacs to send to the printer
 ;;                          later.
 ;;
-;; Note that `ebnf-eps-buffer' and `ebnf-eps-region' never spool the EPS image,
-;; so they don't use the ps-print spooling mechanism.  See section "Actions in
-;; Comments" for an explanation about EPS file generation.
+;; Note that `ebnf-eps-directory', `ebnf-eps-file', `ebnf-eps-buffer' and
+;; `ebnf-eps-region' never spool the EPS image, so they don't use the ps-print
+;; spooling mechanism.  See section "Actions in Comments" for an explanation
+;; about EPS file generation.
 ;;
 ;;
 ;; Invoking Ebnf2ps
 ;;
 ;;
 ;; Invoking Ebnf2ps
@@ -165,9 +177,36 @@ Please send all bug fixes and enhancements to
 ;;   (global-set-key '(control f22) 'ebnf-despool)
 ;;
 ;;
 ;;   (global-set-key '(control f22) 'ebnf-despool)
 ;;
 ;;
+;; Invoking Ebnf2ps in Batch
+;; -------------------------
+;;
+;; It's possible also to run ebnf2ps in batch, this is useful when, for
+;; example, you have a directory with a lot of files containing the EBNF to be
+;; translated to PostScript.
+;;
+;; To run ebnf2ps in batch type, for example:
+;;
+;;    emacs -batch -l setup-ebnf2ps.el -f ebnf-eps-directory
+;;
+;; Where setup-ebnf2ps.el should be a file containing:
+;;
+;;    ;; set load-path if ebnf2ps isn't installed in your Emacs environment
+;;    (setq load-path (append (list "/dir/of/ebnf2ps") load-path))
+;;    (require 'ebnf2ps)
+;;    ;; insert here your ebnf2ps settings
+;;    (setq ebnf-terminal-shape 'bevel)
+;;    ;; etc.
+;;
+;;
 ;; EBNF Syntax
 ;; -----------
 ;;
 ;; EBNF Syntax
 ;; -----------
 ;;
+;; BNF (Backus Naur Form) notation is defined like languages, and like
+;; languages there are rules about name formation and syntax.  In this section
+;; it's defined a BNF syntax that it's called simply EBNF (Extended BNF).
+;; ebnf2ps package also deal with other BNF notation.  Please, see the variable
+;; `ebnf-syntax' documentation below in this section.
+;;
 ;; The current EBNF that ebnf2ps accepts has the following constructions:
 ;;
 ;;    ;                        comment (until end of line)
 ;; The current EBNF that ebnf2ps accepts has the following constructions:
 ;;
 ;;    ;                        comment (until end of line)
@@ -181,7 +220,10 @@ Please send all bug fixes and enhancements to
 ;;    C D              sequence (C occurs before D)
 ;;    C | D            alternative (C or D occurs)
 ;;    A - B            exception (A excluding B, B without any non-terminal)
 ;;    C D              sequence (C occurs before D)
 ;;    C | D            alternative (C or D occurs)
 ;;    A - B            exception (A excluding B, B without any non-terminal)
-;;    n * A            repetition (A repeats n (integer) times)
+;;    n * A            repetition (A repeats at least n (integer) times)
+;;    n * n A          repetition (A repeats exactly n (integer) times)
+;;    n * m A          repetition (A repeats at least n (integer) and at most
+;;                     m (integer) times)
 ;;    (C)              group (expression C is grouped together)
 ;;    [C]              optional (C may or not occurs)
 ;;    C+               one or more occurrences of C
 ;;    (C)              group (expression C is grouped together)
 ;;    [C]              optional (C may or not occurs)
 ;;    C+               one or more occurrences of C
@@ -205,7 +247,7 @@ Please send all bug fixes and enhancements to
 ;;
 ;;    exception = repeat [ "-" repeat].         ;; exception
 ;;
 ;;
 ;;    exception = repeat [ "-" repeat].         ;; exception
 ;;
-;;    repeat = [ integer "*" ] term.            ;; repetition
+;;    repeat = [ integer "*" [ integer ]] term. ;; repetition
 ;;
 ;;    term = factor
 ;;         | [factor] "+"                       ;; one-or-more
 ;;
 ;;    term = factor
 ;;         | [factor] "+"                       ;; one-or-more
@@ -223,14 +265,30 @@ Please send all bug fixes and enhancements to
 ;;           .
 ;;
 ;;    non_terminal = "[!#%&'*-,0-:<>@-Z\\\\^-z~\\240-\\377]+".
 ;;           .
 ;;
 ;;    non_terminal = "[!#%&'*-,0-:<>@-Z\\\\^-z~\\240-\\377]+".
+;;    ;; that is, a valid non_terminal accepts decimal digits, letters (upper
+;;    ;; and lower), 8-bit accentuated characters,
+;;    ;; "!", "#", "%", "&", "'", "*", "+", ",", ":",
+;;    ;; "<", ">", "@", "\", "^", "_", "`" and "~".
 ;;
 ;;    terminal = "\\([^\"\\]\\|\\\\[ -~\\240-\\377]\\)+".
 ;;
 ;;    terminal = "\\([^\"\\]\\|\\\\[ -~\\240-\\377]\\)+".
+;;    ;; that is, a valid terminal accepts any printable character (including
+;;    ;; 8-bit accentuated characters) except `"', as `"' is used to delimit a
+;;    ;; terminal.  Also, accepts escaped characters, that is, a character
+;;    ;; pair starting with `\' followed by a printable character, for
+;;    ;; example: \", \\. 
 ;;
 ;;
-;;    special = "[^?\\n\\000-\\010\\016-\\037\\177-\\237]*".
+;;    special = "[^?\\000-\\010\\012-\\037\\177-\\237]*".
+;;    ;; that is, a valid special accepts any printable character (including
+;;    ;; 8-bit accentuated characters) and tabs except `?', as `?' is used to
+;;    ;; delimit a special.
 ;;
 ;;    integer = "[0-9]+".
 ;;
 ;;    integer = "[0-9]+".
+;;    ;; that is, an integer is a sequence of one or more decimal digits.
 ;;
 ;;    comment = ";" "[^\\n\\000-\\010\\016-\\037\\177-\\237]*" "\\n".
 ;;
 ;;    comment = ";" "[^\\n\\000-\\010\\016-\\037\\177-\\237]*" "\\n".
+;;    ;; that is, a comment starts with the character `;' and terminates at end
+;;    ;; of line.  Also, it only accepts printable characters (including 8-bit
+;;    ;; accentuated characters) and tabs.
 ;;
 ;; Try to use the above EBNF to test ebnf2ps.
 ;;
 ;;
 ;; Try to use the above EBNF to test ebnf2ps.
 ;;
@@ -273,6 +331,10 @@ Please send all bug fixes and enhancements to
 ;;                     `ebnf-terminal-regexp', `ebnf-case-fold-search',
 ;;                     `ebnf-lex-comment-char' and `ebnf-lex-eop-char'.
 ;;
 ;;                     `ebnf-terminal-regexp', `ebnf-case-fold-search',
 ;;                     `ebnf-lex-comment-char' and `ebnf-lex-eop-char'.
 ;;
+;;    `abnf'           ebnf2ps recognizes the syntax described in the URL:
+;;                     `http://www.ietf.org/rfc/rfc2234.txt'
+;;                     ("Augmented BNF for Syntax Specifications: ABNF").
+;;
 ;;    `iso-ebnf'       ebnf2ps recognizes the syntax described in the URL:
 ;;                     `http://www.cl.cam.ac.uk/~mgk25/iso-ebnf.html'
 ;;                     ("International Standard of the ISO EBNF Notation").
 ;;    `iso-ebnf'       ebnf2ps recognizes the syntax described in the URL:
 ;;                     `http://www.cl.cam.ac.uk/~mgk25/iso-ebnf.html'
 ;;                     ("International Standard of the ISO EBNF Notation").
@@ -285,6 +347,14 @@ Please send all bug fixes and enhancements to
 ;;                     setting:
 ;;                     `ebnf-yac-ignore-error-recovery'.
 ;;
 ;;                     setting:
 ;;                     `ebnf-yac-ignore-error-recovery'.
 ;;
+;;    `ebnfx'          ebnf2ps recognizes the syntax described in the URL:
+;;                  `http://www.w3.org/TR/2004/REC-xml-20040204/#sec-notation'
+;;                  ("Extensible Markup Language (XML) 1.0 (Third Edition)")
+;;
+;;    `dtd'            ebnf2ps recognizes the syntax described in the URL:
+;;                     `http://www.w3.org/TR/2004/REC-xml-20040204/'
+;;                  ("Extensible Markup Language (XML) 1.0 (Third Edition)")
+;;
 ;; Any other value is treated as `ebnf'.
 ;;
 ;; The default value is `ebnf'.
 ;; Any other value is treated as `ebnf'.
 ;;
 ;; The default value is `ebnf'.
@@ -356,6 +426,8 @@ Please send all bug fixes and enhancements to
 ;;
 ;; ebnf2ps accepts the following actions in comments:
 ;;
 ;;
 ;; ebnf2ps accepts the following actions in comments:
 ;;
+;;    ;^       same as form feed.  See section Form Feed above.
+;;
 ;;    ;>       the next production starts in the same line as the current one.
 ;;             It is useful when `ebnf-horizontal-orientation' is nil.
 ;;
 ;;    ;>       the next production starts in the same line as the current one.
 ;;             It is useful when `ebnf-horizontal-orientation' is nil.
 ;;
@@ -420,8 +492,8 @@ Please send all bug fixes and enhancements to
 ;; Only the ;> will take effect, that is, A and B will be drawn in the same
 ;; line.
 ;;
 ;; Only the ;> will take effect, that is, A and B will be drawn in the same
 ;; line.
 ;;
-;; In ISO EBNF the above actions are specified as (*>*), (*<*), (*[EPS*) and
-;; (*]EPS*).  The first example above should be written:
+;; In ISO EBNF the above actions are specified as (*^*), (*>*), (*<*), (*[EPS*)
+;; and (*]EPS*).  The first example above should be written:
 ;;
 ;;    A = t;
 ;;    C = x;
 ;;
 ;;    A = t;
 ;;    C = x;
@@ -482,6 +554,12 @@ Please send all bug fixes and enhancements to
 ;;
 ;; `ebnf-setup' returns the current setup.
 ;;
 ;;
 ;; `ebnf-setup' returns the current setup.
 ;;
+;; `ebnf-syntax-directory' does a syntactic analysis of your EBNF files in the
+;; given directory.
+;;
+;; `ebnf-syntax-file' does a syntactic analysis of your EBNF in the given
+;; file.
+;;
 ;; `ebnf-syntax-buffer' does a syntactic analysis of your EBNF in the current
 ;; buffer.
 ;;
 ;; `ebnf-syntax-buffer' does a syntactic analysis of your EBNF in the current
 ;; buffer.
 ;;
@@ -490,8 +568,9 @@ Please send all bug fixes and enhancements to
 ;;
 ;; `ebnf-customize' activates a customization buffer for ebnf2ps options.
 ;;
 ;;
 ;; `ebnf-customize' activates a customization buffer for ebnf2ps options.
 ;;
-;; `ebnf-syntax-buffer', `ebnf-syntax-region' and `ebnf-customize' can be bound
-;; to keys in the same way as `ebnf-' commands.
+;; `ebnf-syntax-directory', `ebnf-syntax-file', `ebnf-syntax-buffer',
+;; `ebnf-syntax-region' and `ebnf-customize' can be bound to keys in the same
+;; way as `ebnf-' commands.
 ;;
 ;;
 ;; Hooks
 ;;
 ;;
 ;; Hooks
@@ -545,6 +624,9 @@ Please send all bug fixes and enhancements to
 ;;
 ;; `ebnf-terminal-border-color'                Specify border color for terminal box.
 ;;
 ;;
 ;; `ebnf-terminal-border-color'                Specify border color for terminal box.
 ;;
+;; `ebnf-production-name-p'            Non-nil means production name will be
+;;                                     printed.
+;;
 ;; `ebnf-sort-production'              Specify how productions are sorted.
 ;;
 ;; `ebnf-production-font'              Specify production font.
 ;; `ebnf-sort-production'              Specify how productions are sorted.
 ;;
 ;; `ebnf-production-font'              Specify production font.
@@ -562,6 +644,9 @@ Please send all bug fixes and enhancements to
 ;; `ebnf-non-terminal-border-color'    Specify border color for non-terminal
 ;;                                     box.
 ;;
 ;; `ebnf-non-terminal-border-color'    Specify border color for non-terminal
 ;;                                     box.
 ;;
+;; `ebnf-special-show-delimiter'       Non-nil means special delimiter
+;;                                     (character `?') is shown.
+;;
 ;; `ebnf-special-font'                 Specify special font.
 ;;
 ;; `ebnf-special-shape'                        Specify special box shape.
 ;; `ebnf-special-font'                 Specify special font.
 ;;
 ;; `ebnf-special-shape'                        Specify special box shape.
@@ -629,10 +714,16 @@ Please send all bug fixes and enhancements to
 ;;                                     default terminal, non-terminal or
 ;;                                     special.
 ;;
 ;;                                     default terminal, non-terminal or
 ;;                                     special.
 ;;
+;; `ebnf-file-suffix-regexp'           Specify file name suffix that contains
+;;                                     EBNF.
+;;
 ;; `ebnf-eps-prefix'                   Specify EPS prefix file name.
 ;;
 ;; `ebnf-use-float-format'             Non-nil means use `%f' float format.
 ;;
 ;; `ebnf-eps-prefix'                   Specify EPS prefix file name.
 ;;
 ;; `ebnf-use-float-format'             Non-nil means use `%f' float format.
 ;;
+;; `ebnf-stop-on-error'                        Non-nil means signal error and stop.
+;;                                     Nil means signal error and continue.
+;;
 ;; `ebnf-yac-ignore-error-recovery'    Non-nil means ignore error recovery.
 ;;
 ;; `ebnf-ignore-empty-rule'            Non-nil means ignore empty rules.
 ;; `ebnf-yac-ignore-error-recovery'    Non-nil means ignore error recovery.
 ;;
 ;; `ebnf-ignore-empty-rule'            Non-nil means ignore empty rules.
@@ -695,21 +786,24 @@ Please send all bug fixes and enhancements to
 ;; `ebnf-insert-style' Insert a new style NAME with inheritance INHERITS and
 ;;                     values VALUES.
 ;;
 ;; `ebnf-insert-style' Insert a new style NAME with inheritance INHERITS and
 ;;                     values VALUES.
 ;;
+;; `ebnf-delete-style' Delete style NAME.
+;;
 ;; `ebnf-merge-style'  Merge values of style NAME with style VALUES.
 ;;
 ;; `ebnf-merge-style'  Merge values of style NAME with style VALUES.
 ;;
-;; `ebnf-apply-style'  Set STYLE to current style.
+;; `ebnf-apply-style'  Set STYLE as the current style.
 ;;
 ;; `ebnf-reset-style'  Reset current style.
 ;;
 ;;
 ;; `ebnf-reset-style'  Reset current style.
 ;;
-;; `ebnf-push-style'   Push the current style and set STYLE to current style.
+;; `ebnf-push-style'   Push the current style and set STYLE as the current
+;;                     style. 
 ;;
 ;;
-;; `ebnf-pop-style'    Pop a style and set it to current style.
+;; `ebnf-pop-style'    Pop a style and set it as the current style.
 ;;
 ;;
-;; These commands helps to put together a lot of variable settings in a group
+;; These commands help to put together a lot of variable settings in a group
 ;; and name this group.  So when you wish to apply these settings it's only
 ;; needed to give the name.
 ;;
 ;; and name this group.  So when you wish to apply these settings it's only
 ;; needed to give the name.
 ;;
-;; There is also a notion of simple inheritance of style; so if you declare
+;; There is also a notion of simple inheritance of style; so, if you declare
 ;; that a style A inherits from a style B, all settings of B is applied first
 ;; and then the settings of A is applied.  This is useful when you wish to
 ;; modify some aspects of an existing style, but at same time wish to keep it
 ;; that a style A inherits from a style B, all settings of B is applied first
 ;; and then the settings of A is applied.  This is useful when you wish to
 ;; modify some aspects of an existing style, but at same time wish to keep it
@@ -994,6 +1088,17 @@ Please send all bug fixes and enhancements to
 ;; Acknowledgements
 ;; ----------------
 ;;
 ;; Acknowledgements
 ;; ----------------
 ;;
+;; Thanks to Drew Adams <drew.adams@oracle.com> for suggestions:
+;;    - `ebnf-production-name-p', `ebnf-stop-on-error',
+;;     `ebnf-file-suffix-regexp'and `ebnf-special-show-delimiter' variables.
+;;    - `ebnf-delete-style', `ebnf-eps-file' and `ebnf-eps-directory'
+;;     commands.
+;;    - some docs fix.
+;;
+;; Thanks to Matthew K. Junker <junker@alum.mit.edu> for the suggestion to deal
+;; with some Bison features (%right, %left and %prec pragmas).  His suggestion
+;; was extended to deal with %nonassoc pragma too.
+;;
 ;; Thanks to all who emailed comments.
 ;;
 ;;
 ;; Thanks to all who emailed comments.
 ;;
 ;;
@@ -1007,6 +1112,22 @@ Please send all bug fixes and enhancements to
 (and (string< ps-print-version "5.2.3")
      (error "`ebnf2ps' requires `ps-print' package version 5.2.3 or later"))
 
 (and (string< ps-print-version "5.2.3")
      (error "`ebnf2ps' requires `ps-print' package version 5.2.3 or later"))
 
+
+;; to avoid gripes with Emacs 20
+(eval-and-compile
+  (or (fboundp 'assq-delete-all)
+      (defun assq-delete-all (key alist)
+       "Delete from ALIST all elements whose car is KEY.
+Return the modified alist.
+Elements of ALIST that are not conses are ignored."
+       (let ((tail alist))
+         (while tail
+           (if (and (consp (car tail))
+                    (eq (car (car tail)) key))
+               (setq alist (delq (car tail) alist)))
+           (setq tail (cdr tail)))
+         alist))))
+
 \f
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; User Variables:
 \f
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; User Variables:
@@ -1140,6 +1261,12 @@ Valid values are:
   :group 'ebnf-displacement)
 
 
   :group 'ebnf-displacement)
 
 
+(defcustom ebnf-special-show-delimiter t
+  "*Non-nil means special delimiter (character `?') is shown."
+  :type 'boolean
+  :group 'ebnf-special)
+
+
 (defcustom ebnf-special-font '(7 Courier "Black" "Gray95" bold italic)
   "*Specify special font.
 
 (defcustom ebnf-special-font '(7 Courier "Black" "Gray95" bold italic)
   "*Specify special font.
 
@@ -1332,6 +1459,12 @@ See documentation for `ebnf-non-terminal-shape'."
   :group 'ebnf-terminal)
 
 
   :group 'ebnf-terminal)
 
 
+(defcustom ebnf-production-name-p t
+  "*Non-nil means production name will be printed."
+  :type 'boolean
+  :group 'ebnf-production)
+
+
 (defcustom ebnf-sort-production nil
   "*Specify how productions are sorted.
 
 (defcustom ebnf-sort-production nil
   "*Specify how productions are sorted.
 
@@ -1482,14 +1615,28 @@ Valid values are:
                                                  |*
                                                  *
 
                                                  |*
                                                  *
 
+   `semi-up-hollow'               `semi-up-full'
+                 *                               *
+                 |*                              |*
+                 | *                             |X*
+               ==+==*                          ==+==*
+
+   `semi-down-hollow'             `semi-down-full'
+               ==+==*                          ==+==*
+                 | *                             |X*
+                 |*                              |*
+                 *                               *
+
    `user'      See also documentation for variable `ebnf-user-arrow'.
 
 Any other value is treated as `none'."
   :type '(radio :tag "Arrow Shape"
    `user'      See also documentation for variable `ebnf-user-arrow'.
 
 Any other value is treated as `none'."
   :type '(radio :tag "Arrow Shape"
-               (const none)        (const semi-up)
-               (const semi-down)   (const simple)
-               (const transparent) (const hollow)
-               (const full)        (const user))
+               (const none)             (const semi-up)
+               (const semi-down)        (const simple)
+               (const transparent)      (const hollow)
+               (const full)             (const semi-up-hollow)
+               (const semi-down-hollow) (const semi-up-full)
+               (const semi-down-full)   (const user))
   :group 'ebnf-shape)
 
 
   :group 'ebnf-shape)
 
 
@@ -1553,6 +1700,10 @@ Valid values are:
                `ebnf-terminal-regexp', `ebnf-case-fold-search',
                `ebnf-lex-comment-char' and `ebnf-lex-eop-char'.
 
                `ebnf-terminal-regexp', `ebnf-case-fold-search',
                `ebnf-lex-comment-char' and `ebnf-lex-eop-char'.
 
+   `abnf'      ebnf2ps recognizes the syntax described in the URL:
+               `http://www.ietf.org/rfc/rfc2234.txt'
+               (\"Augmented BNF for Syntax Specifications: ABNF\").
+
    `iso-ebnf'  ebnf2ps recognizes the syntax described in the URL:
                `http://www.cl.cam.ac.uk/~mgk25/iso-ebnf.html'
                (\"International Standard of the ISO EBNF Notation\").
    `iso-ebnf'  ebnf2ps recognizes the syntax described in the URL:
                `http://www.cl.cam.ac.uk/~mgk25/iso-ebnf.html'
                (\"International Standard of the ISO EBNF Notation\").
@@ -1565,9 +1716,18 @@ Valid values are:
                setting:
                `ebnf-yac-ignore-error-recovery'.
 
                setting:
                `ebnf-yac-ignore-error-recovery'.
 
+   `ebnfx'     ebnf2ps recognizes the syntax described in the URL:
+               `http://www.w3.org/TR/2004/REC-xml-20040204/#sec-notation'
+               (\"Extensible Markup Language (XML) 1.0 (Third Edition)\")
+
+   `dtd'       ebnf2ps recognizes the syntax described in the URL:
+               `http://www.w3.org/TR/2004/REC-xml-20040204/'
+               (\"Extensible Markup Language (XML) 1.0 (Third Edition)\")
+
 Any other value is treated as `ebnf'."
   :type '(radio :tag "Syntax"
 Any other value is treated as `ebnf'."
   :type '(radio :tag "Syntax"
-               (const ebnf) (const iso-ebnf) (const yacc))
+               (const ebnf) (const abnf)  (const iso-ebnf)
+               (const yacc) (const ebnfx) (const dtd))
   :group 'ebnf-syntactic)
 
 
   :group 'ebnf-syntactic)
 
 
@@ -1638,6 +1798,14 @@ It's only used when `ebnf-syntax' is `iso-ebnf'."
   :group 'ebnf-syntactic)
 
 
   :group 'ebnf-syntactic)
 
 
+(defcustom ebnf-file-suffix-regexp "\.[Bb][Nn][Ff]$"
+  "*Specify file name suffix that contains EBNF.
+
+See `ebnf-eps-directory' command."
+  :type 'regexp
+  :group 'ebnf2ps)
+
+
 (defcustom ebnf-eps-prefix "ebnf--"
   "*Specify EPS prefix file name.
 
 (defcustom ebnf-eps-prefix "ebnf--"
   "*Specify EPS prefix file name.
 
@@ -1704,6 +1872,12 @@ when executing ebnf2ps, set `ebnf-use-float-format' to nil."
   :group 'ebnf2ps)
 
 
   :group 'ebnf2ps)
 
 
+(defcustom ebnf-stop-on-error nil
+  "*Non-nil means signal error and stop. Nil means signal error and continue."
+  :type 'boolean
+  :group 'ebnf2ps)
+
+
 (defcustom ebnf-yac-ignore-error-recovery nil
   "*Non-nil means ignore error recovery.
 
 (defcustom ebnf-yac-ignore-error-recovery nil
   "*Non-nil means ignore error recovery.
 
@@ -1746,6 +1920,21 @@ The above optimizations are specially useful when `ebnf-syntax' is `yacc'."
   :type 'boolean
   :group 'ebnf-optimization)
 
   :type 'boolean
   :group 'ebnf-optimization)
 
+\f
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; To make this file smaller, some commands go in a separate file.
+;; But autoload them here to make the separation invisible.
+;; Autoload is here to avoid compilation gripes.
+
+(autoload 'ebnf-eliminate-empty-rules "ebnf-otz"
+  "Eliminate empty rules.")
+
+(autoload 'ebnf-optimize              "ebnf-otz"
+  "Syntactic chart optimizer.")
+
+(autoload 'ebnf-otz-initialize        "ebnf-otz"
+  "Initialize optimizer.")
+
 \f
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Customization
 \f
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Customization
@@ -1762,6 +1951,34 @@ The above optimizations are specially useful when `ebnf-syntax' is `yacc'."
 ;; User commands
 
 
 ;; User commands
 
 
+;;;###autoload
+(defun ebnf-print-directory (&optional directory)
+  "Generate and print a PostScript syntactic chart image of DIRECTORY.
+
+If DIRECTORY is nil, it's used `default-directory'.
+
+The files in DIRECTORY that matches `ebnf-file-suffix-regexp' (which see) are
+processed.
+
+See also `ebnf-print-buffer'."
+  (interactive
+   (list (read-file-name "Directory containing EBNF files (print): "
+                        nil default-directory)))
+  (ebnf-directory 'ebnf-print-buffer directory))
+
+
+;;;###autoload
+(defun ebnf-print-file (file &optional do-not-kill-buffer-when-done)
+  "Generate and print a PostScript syntactic chart image of the file FILE.
+
+If optional arg DO-NOT-KILL-BUFFER-WHEN-DONE is non-nil, the buffer isn't
+killed after process termination.
+
+See also `ebnf-print-buffer'."
+  (interactive "fEBNF file to generate PostScript and print from: ")
+  (ebnf-file 'ebnf-print-buffer file do-not-kill-buffer-when-done))
+
+
 ;;;###autoload
 (defun ebnf-print-buffer (&optional filename)
   "Generate and print a PostScript syntactic chart image of the buffer.
 ;;;###autoload
 (defun ebnf-print-buffer (&optional filename)
   "Generate and print a PostScript syntactic chart image of the buffer.
@@ -1788,6 +2005,34 @@ Like `ebnf-print-buffer', but prints just the current region."
       (ps-do-despool filename)))
 
 
       (ps-do-despool filename)))
 
 
+;;;###autoload
+(defun ebnf-spool-directory (&optional directory)
+  "Generate and spool a PostScript syntactic chart image of DIRECTORY.
+
+If DIRECTORY is nil, it's used `default-directory'.
+
+The files in DIRECTORY that matches `ebnf-file-suffix-regexp' (which see) are
+processed.
+
+See also `ebnf-spool-buffer'."
+  (interactive
+   (list (read-file-name "Directory containing EBNF files (spool): "
+                        nil default-directory)))
+  (ebnf-directory 'ebnf-spool-buffer directory))
+
+
+;;;###autoload
+(defun ebnf-spool-file (file &optional do-not-kill-buffer-when-done)
+  "Generate and spool a PostScript syntactic chart image of the file FILE.
+
+If optional arg DO-NOT-KILL-BUFFER-WHEN-DONE is non-nil, the buffer isn't
+killed after process termination.
+
+See also `ebnf-spool-buffer'."
+  (interactive "fEBNF file to generate PostScript and spool from: ")
+  (ebnf-file 'ebnf-spool-buffer file do-not-kill-buffer-when-done))
+
+
 ;;;###autoload
 (defun ebnf-spool-buffer ()
   "Generate and spool a PostScript syntactic chart image of the buffer.
 ;;;###autoload
 (defun ebnf-spool-buffer ()
   "Generate and spool a PostScript syntactic chart image of the buffer.
@@ -1809,6 +2054,34 @@ Use the command `ebnf-despool' to send the spooled images to the printer."
   (ebnf-generate-region from to 'ebnf-generate))
 
 
   (ebnf-generate-region from to 'ebnf-generate))
 
 
+;;;###autoload
+(defun ebnf-eps-directory (&optional directory)
+  "Generate EPS files from EBNF files in DIRECTORY.
+
+If DIRECTORY is nil, it's used `default-directory'.
+
+The files in DIRECTORY that matches `ebnf-file-suffix-regexp' (which see) are
+processed.
+
+See also `ebnf-eps-buffer'."
+  (interactive
+   (list (read-file-name "Directory containing EBNF files (EPS): "
+                        nil default-directory)))
+  (ebnf-directory 'ebnf-eps-buffer directory))
+
+
+;;;###autoload
+(defun ebnf-eps-file (file &optional do-not-kill-buffer-when-done)
+  "Generate an EPS file from EBNF file FILE.
+
+If optional arg DO-NOT-KILL-BUFFER-WHEN-DONE is non-nil, the buffer isn't
+killed after EPS generation.
+
+See also `ebnf-eps-buffer'."
+  (interactive "fEBNF file to generate EPS file from: ")
+  (ebnf-file 'ebnf-eps-buffer file do-not-kill-buffer-when-done))
+
+
 ;;;###autoload
 (defun ebnf-eps-buffer ()
   "Generate a PostScript syntactic chart image of the buffer in a EPS file.
 ;;;###autoload
 (defun ebnf-eps-buffer ()
   "Generate a PostScript syntactic chart image of the buffer in a EPS file.
@@ -1858,6 +2131,34 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
 (defalias 'ebnf-despool 'ps-despool)
 
 
 (defalias 'ebnf-despool 'ps-despool)
 
 
+;;;###autoload
+(defun ebnf-syntax-directory (&optional directory)
+  "Does a syntactic analysis of the files in DIRECTORY.
+
+If DIRECTORY is nil, it's used `default-directory'.
+
+The files in DIRECTORY that matches `ebnf-file-suffix-regexp' (which see) are
+processed.
+
+See also `ebnf-syntax-buffer'."
+  (interactive
+   (list (read-file-name "Directory containing EBNF files (syntax): "
+                        nil default-directory)))
+  (ebnf-directory 'ebnf-syntax-buffer directory))
+
+
+;;;###autoload
+(defun ebnf-syntax-file (file &optional do-not-kill-buffer-when-done)
+  "Does a syntactic analysis of the FILE.
+
+If optional arg DO-NOT-KILL-BUFFER-WHEN-DONE is non-nil, the buffer isn't
+killed after syntax checking.
+
+See also `ebnf-syntax-buffer'."
+  (interactive "fEBNF file to check syntax: ")
+  (ebnf-file 'ebnf-syntax-buffer file do-not-kill-buffer-when-done))
+
+
 ;;;###autoload
 (defun ebnf-syntax-buffer ()
   "Does a syntactic analysis of the current buffer."
 ;;;###autoload
 (defun ebnf-syntax-buffer ()
   "Does a syntactic analysis of the current buffer."
@@ -1883,7 +2184,8 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
    "
 ;;; ebnf2ps.el version %s
 
    "
 ;;; ebnf2ps.el version %s
 
-\(setq ebnf-special-font                %s
+\(setq ebnf-special-show-delimiter      %S
+      ebnf-special-font                %s
       ebnf-special-shape               %s
       ebnf-special-shadow              %S
       ebnf-special-border-width        %S
       ebnf-special-shape               %s
       ebnf-special-shadow              %S
       ebnf-special-border-width        %S
@@ -1910,6 +2212,7 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
       ebnf-non-terminal-shadow         %S
       ebnf-non-terminal-border-width   %S
       ebnf-non-terminal-border-color   %S
       ebnf-non-terminal-shadow         %S
       ebnf-non-terminal-border-width   %S
       ebnf-non-terminal-border-color   %S
+      ebnf-production-name-p           %S
       ebnf-sort-production             %s
       ebnf-production-font             %s
       ebnf-arrow-shape                 %s
       ebnf-sort-production             %s
       ebnf-production-font             %s
       ebnf-arrow-shape                 %s
@@ -1925,6 +2228,7 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
       ebnf-syntax                      %s
       ebnf-iso-alternative-p           %S
       ebnf-iso-normalize-p             %S
       ebnf-syntax                      %s
       ebnf-iso-alternative-p           %S
       ebnf-iso-normalize-p             %S
+      ebnf-file-suffix-regexp          %S
       ebnf-eps-prefix                  %S
       ebnf-entry-percentage            %S
       ebnf-color-p                     %S
       ebnf-eps-prefix                  %S
       ebnf-entry-percentage            %S
       ebnf-color-p                     %S
@@ -1932,6 +2236,7 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
       ebnf-line-color                  %S
       ebnf-debug-ps                    %S
       ebnf-use-float-format            %S
       ebnf-line-color                  %S
       ebnf-debug-ps                    %S
       ebnf-use-float-format            %S
+      ebnf-stop-on-error               %S
       ebnf-yac-ignore-error-recovery   %S
       ebnf-ignore-empty-rule           %S
       ebnf-optimize                    %S)
       ebnf-yac-ignore-error-recovery   %S
       ebnf-ignore-empty-rule           %S
       ebnf-optimize                    %S)
@@ -1939,6 +2244,7 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
 ;;; ebnf2ps.el - end of settings
 "
    ebnf-version
 ;;; ebnf2ps.el - end of settings
 "
    ebnf-version
+   ebnf-special-show-delimiter
    (ps-print-quote ebnf-special-font)
    (ps-print-quote ebnf-special-shape)
    ebnf-special-shadow
    (ps-print-quote ebnf-special-font)
    (ps-print-quote ebnf-special-shape)
    ebnf-special-shadow
@@ -1966,6 +2272,7 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
    ebnf-non-terminal-shadow
    ebnf-non-terminal-border-width
    ebnf-non-terminal-border-color
    ebnf-non-terminal-shadow
    ebnf-non-terminal-border-width
    ebnf-non-terminal-border-color
+   ebnf-production-name-p
    (ps-print-quote ebnf-sort-production)
    (ps-print-quote ebnf-production-font)
    (ps-print-quote ebnf-arrow-shape)
    (ps-print-quote ebnf-sort-production)
    (ps-print-quote ebnf-production-font)
    (ps-print-quote ebnf-arrow-shape)
@@ -1981,6 +2288,7 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
    (ps-print-quote ebnf-syntax)
    ebnf-iso-alternative-p
    ebnf-iso-normalize-p
    (ps-print-quote ebnf-syntax)
    ebnf-iso-alternative-p
    ebnf-iso-normalize-p
+   ebnf-file-suffix-regexp
    ebnf-eps-prefix
    ebnf-entry-percentage
    ebnf-color-p
    ebnf-eps-prefix
    ebnf-entry-percentage
    ebnf-color-p
@@ -1988,6 +2296,7 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
    ebnf-line-color
    ebnf-debug-ps
    ebnf-use-float-format
    ebnf-line-color
    ebnf-debug-ps
    ebnf-use-float-format
+   ebnf-stop-on-error
    ebnf-yac-ignore-error-recovery
    ebnf-ignore-empty-rule
    ebnf-optimize))
    ebnf-yac-ignore-error-recovery
    ebnf-ignore-empty-rule
    ebnf-optimize))
@@ -2007,7 +2316,8 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
 
 
 (defconst ebnf-style-custom-list
 
 
 (defconst ebnf-style-custom-list
-  '(ebnf-special-font
+  '(ebnf-special-show-delimiter
+    ebnf-special-font
     ebnf-special-shape
     ebnf-special-shadow
     ebnf-special-border-width
     ebnf-special-shape
     ebnf-special-shadow
     ebnf-special-border-width
@@ -2034,6 +2344,7 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
     ebnf-non-terminal-shadow
     ebnf-non-terminal-border-width
     ebnf-non-terminal-border-color
     ebnf-non-terminal-shadow
     ebnf-non-terminal-border-width
     ebnf-non-terminal-border-color
+    ebnf-production-name-p
     ebnf-sort-production
     ebnf-production-font
     ebnf-arrow-shape
     ebnf-sort-production
     ebnf-production-font
     ebnf-arrow-shape
@@ -2049,6 +2360,7 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
     ebnf-syntax
     ebnf-iso-alternative-p
     ebnf-iso-normalize-p
     ebnf-syntax
     ebnf-iso-alternative-p
     ebnf-iso-normalize-p
+    ebnf-file-suffix-regexp
     ebnf-eps-prefix
     ebnf-entry-percentage
     ebnf-color-p
     ebnf-eps-prefix
     ebnf-entry-percentage
     ebnf-color-p
@@ -2056,6 +2368,7 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
     ebnf-line-color
     ebnf-debug-ps
     ebnf-use-float-format
     ebnf-line-color
     ebnf-debug-ps
     ebnf-use-float-format
+    ebnf-stop-on-error
     ebnf-yac-ignore-error-recovery
     ebnf-ignore-empty-rule
     ebnf-optimize)
     ebnf-yac-ignore-error-recovery
     ebnf-ignore-empty-rule
     ebnf-optimize)
@@ -2066,6 +2379,7 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
   '(;; EBNF default
     (default
       nil
   '(;; EBNF default
     (default
       nil
+      (ebnf-special-show-delimiter      . t)
       (ebnf-special-font          . '(7 Courier "Black" "Gray95" bold italic))
       (ebnf-special-shape               . 'bevel)
       (ebnf-special-shadow              . nil)
       (ebnf-special-font          . '(7 Courier "Black" "Gray95" bold italic))
       (ebnf-special-shape               . 'bevel)
       (ebnf-special-shadow              . nil)
@@ -2093,6 +2407,7 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
       (ebnf-non-terminal-shadow         . nil)
       (ebnf-non-terminal-border-width   . 1.0)
       (ebnf-non-terminal-border-color   . "Black")
       (ebnf-non-terminal-shadow         . nil)
       (ebnf-non-terminal-border-width   . 1.0)
       (ebnf-non-terminal-border-color   . "Black")
+      (ebnf-production-name-p           . t)
       (ebnf-sort-production             . nil)
       (ebnf-production-font             . '(10 Helvetica "Black" "White" bold))
       (ebnf-arrow-shape                 . 'hollow)
       (ebnf-sort-production             . nil)
       (ebnf-production-font             . '(10 Helvetica "Black" "White" bold))
       (ebnf-arrow-shape                 . 'hollow)
@@ -2108,6 +2423,7 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
       (ebnf-syntax                      . 'ebnf)
       (ebnf-iso-alternative-p           . nil)
       (ebnf-iso-normalize-p             . nil)
       (ebnf-syntax                      . 'ebnf)
       (ebnf-iso-alternative-p           . nil)
       (ebnf-iso-normalize-p             . nil)
+      (ebnf-file-suffix-regexp          . "\.[Bb][Nn][Ff]$")
       (ebnf-eps-prefix                  . "ebnf--")
       (ebnf-entry-percentage            . 0.5)
       (ebnf-color-p   . (or (fboundp 'x-color-values) ; Emacs
       (ebnf-eps-prefix                  . "ebnf--")
       (ebnf-entry-percentage            . 0.5)
       (ebnf-color-p   . (or (fboundp 'x-color-values) ; Emacs
@@ -2116,6 +2432,7 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
       (ebnf-line-color                  . "Black")
       (ebnf-debug-ps                    . nil)
       (ebnf-use-float-format            . t)
       (ebnf-line-color                  . "Black")
       (ebnf-debug-ps                    . nil)
       (ebnf-use-float-format            . t)
+      (ebnf-stop-on-error               . nil)
       (ebnf-yac-ignore-error-recovery   . nil)
       (ebnf-ignore-empty-rule           . nil)
       (ebnf-optimize                    . nil))
       (ebnf-yac-ignore-error-recovery   . nil)
       (ebnf-ignore-empty-rule           . nil)
       (ebnf-optimize                    . nil))
@@ -2125,6 +2442,10 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
      (ebnf-justify-sequence            . 'left)
      (ebnf-lex-comment-char            . ?\#)
      (ebnf-lex-eop-char                . ?\;))
      (ebnf-justify-sequence            . 'left)
      (ebnf-lex-comment-char            . ?\#)
      (ebnf-lex-eop-char                . ?\;))
+    ;; ABNF default
+    (abnf
+     default
+     (ebnf-syntax                      . 'abnf))
     ;; ISO EBNF default
     (iso-ebnf
      default
     ;; ISO EBNF default
     (iso-ebnf
      default
@@ -2133,24 +2454,44 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
     (yacc
      default
      (ebnf-syntax                      . 'yacc))
     (yacc
      default
      (ebnf-syntax                      . 'yacc))
+    ;; ebnfx default
+    (ebnfx
+     default
+     (ebnf-syntax                      . 'ebnfx))
+    ;; dtd default
+    (dtd
+     default
+     (ebnf-syntax                      . 'dtd))
     )
   "Style database.
 
 Each element has the following form:
 
     )
   "Style database.
 
 Each element has the following form:
 
-   (CUSTOM INHERITS (VAR . VALUE)...)
+   (NAME INHERITS (VAR . VALUE)...)
+
+Where:
+
+NAME           is a symbol name style.
+
+INHERITS       is a symbol name style from which the current style inherits
+               the context.  If INHERITS is nil, means that there is no
+               inheritance.
 
 
-CUSTOM is a symbol name style.
-INHERITS is a symbol name style from which the current style inherits the
-context.  If INHERITS is nil, means that there is no inheritance.
-VAR is a valid ebnf2ps symbol custom variable.  See `ebnf-style-custom-list'
-for valid symbol variable.
-VALUE is a sexp which it'll be evaluated to set the value to VAR.  So, don't
-forget to quote symbols and constant lists.  See `default' style for an
-example.
+               This is a simple inheritance of style; so if you declare that a
+               style A inherits from a style B, all settings of B is applied
+               first and then the settings of A is applied.  This is useful
+               when you wish to modify some aspects of an existing style, but
+               at same time wish to keep it unmodified.
 
 
-Don't handle this variable directly.  Use functions `ebnf-insert-style' and
-`ebnf-merge-style'.")
+VAR            is a valid ebnf2ps symbol custom variable.
+               See `ebnf-style-custom-list' for valid symbol variable.
+
+VALUE          is a sexp which it'll be evaluated to set the value to VAR.
+               So, don't forget to quote symbols and constant lists.
+               See `default' style for an example.
+
+Don't handle this variable directly.  Use functions `ebnf-insert-style',
+`ebnf-delete-style' and `ebnf-merge-style'.")
 
 \f
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 \f
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -2159,8 +2500,10 @@ Don't handle this variable directly.  Use functions `ebnf-insert-style' and
 
 ;;;###autoload
 (defun ebnf-insert-style (name inherits &rest values)
 
 ;;;###autoload
 (defun ebnf-insert-style (name inherits &rest values)
-  "Insert a new style NAME with inheritance INHERITS and values VALUES."
-  (interactive)
+  "Insert a new style NAME with inheritance INHERITS and values VALUES.
+
+See `ebnf-style-database' documentation."
+  (interactive "SStyle name: \nSStyle inherits from: \nXStyle values: ")
   (and (assoc name ebnf-style-database)
        (error "Style name already exists: %s" name))
   (or (assoc inherits ebnf-style-database)
   (and (assoc name ebnf-style-database)
        (error "Style name already exists: %s" name))
   (or (assoc inherits ebnf-style-database)
@@ -2170,10 +2513,29 @@ Don't handle this variable directly.  Use functions `ebnf-insert-style' and
              ebnf-style-database)))
 
 
              ebnf-style-database)))
 
 
+;;;###autoload
+(defun ebnf-delete-style (name)
+  "Delete style NAME.
+
+See `ebnf-style-database' documentation."
+  (interactive "SDelete style name: ")
+  (or (assoc name ebnf-style-database)
+      (error "Style name doesn't exist: %s" name))
+  (let ((db ebnf-style-database))
+    (while db
+      (and (eq (nth 1 (car db)) name)
+          (error "Style name `%s' is inherited by `%s' style"
+                 name (nth 0 (car db))))
+      (setq db (cdr db))))
+  (setq ebnf-style-database (assq-delete-all name ebnf-style-database)))
+
+
 ;;;###autoload
 (defun ebnf-merge-style (name &rest values)
 ;;;###autoload
 (defun ebnf-merge-style (name &rest values)
-  "Merge values of style NAME with style VALUES."
-  (interactive)
+  "Merge values of style NAME with style VALUES.
+
+See `ebnf-style-database' documentation."
+  (interactive "SStyle name: \nXStyle values: ")
   (let ((style (or (assoc name ebnf-style-database)
                   (error "Style name does'nt exist: %s" name)))
        (merge (ebnf-check-style-values values))
   (let ((style (or (assoc name ebnf-style-database)
                   (error "Style name does'nt exist: %s" name)))
        (merge (ebnf-check-style-values values))
@@ -2193,10 +2555,12 @@ Don't handle this variable directly.  Use functions `ebnf-insert-style' and
 
 ;;;###autoload
 (defun ebnf-apply-style (style)
 
 ;;;###autoload
 (defun ebnf-apply-style (style)
-  "Set STYLE to current style.
+  "Set STYLE as the current style.
 
 
-It returns the old style symbol."
-  (interactive)
+It returns the old style symbol.
+
+See `ebnf-style-database' documentation."
+  (interactive "SApply style: ")
   (prog1
       ebnf-current-style
     (and (ebnf-apply-style1 style)
   (prog1
       ebnf-current-style
     (and (ebnf-apply-style1 style)
@@ -2207,18 +2571,22 @@ It returns the old style symbol."
 (defun ebnf-reset-style (&optional style)
   "Reset current style.
 
 (defun ebnf-reset-style (&optional style)
   "Reset current style.
 
-It returns the old style symbol."
-  (interactive)
+It returns the old style symbol.
+
+See `ebnf-style-database' documentation."
+  (interactive "SReset style: ")
   (setq ebnf-stack-style nil)
   (ebnf-apply-style (or style 'default)))
 
 
 ;;;###autoload
 (defun ebnf-push-style (&optional style)
   (setq ebnf-stack-style nil)
   (ebnf-apply-style (or style 'default)))
 
 
 ;;;###autoload
 (defun ebnf-push-style (&optional style)
-  "Push the current style and set STYLE to current style.
+  "Push the current style and set STYLE as the current style.
 
 
-It returns the old style symbol."
-  (interactive)
+It returns the old style symbol.
+
+See `ebnf-style-database' documentation."
+  (interactive "SPush style: ")
   (prog1
       ebnf-current-style
     (setq ebnf-stack-style (cons ebnf-current-style ebnf-stack-style))
   (prog1
       ebnf-current-style
     (setq ebnf-stack-style (cons ebnf-current-style ebnf-stack-style))
@@ -2228,9 +2596,11 @@ It returns the old style symbol."
 
 ;;;###autoload
 (defun ebnf-pop-style ()
 
 ;;;###autoload
 (defun ebnf-pop-style ()
-  "Pop a style and set it to current style.
+  "Pop a style and set it as the current style.
 
 
-It returns the old style symbol."
+It returns the old style symbol.
+
+See `ebnf-style-database' documentation."
   (interactive)
   (prog1
       (ebnf-apply-style (car ebnf-stack-style))
   (interactive)
   (prog1
       (ebnf-apply-style (car ebnf-stack-style))
@@ -2249,7 +2619,7 @@ It returns the old style symbol."
 (defun ebnf-check-style-values (values)
   (let (style)
     (while values
 (defun ebnf-check-style-values (values)
   (let (style)
     (while values
-      (and (memq (car values) ebnf-style-custom-list)
+      (and (memq (caar values) ebnf-style-custom-list)
           (setq style (cons (car values) style)))
       (setq values (cdr values)))
     (nreverse style)))
           (setq style (cons (car values) style)))
       (setq values (cdr values)))
     (nreverse style)))
@@ -2297,14 +2667,18 @@ documentation.")
 
 
 (defconst ebnf-arrow-shape-alist
 
 
 (defconst ebnf-arrow-shape-alist
-  '((none        . 0)
-    (semi-up     . 1)
-    (semi-down   . 2)
-    (simple      . 3)
-    (transparent . 4)
-    (hollow      . 5)
-    (full        . 6)
-    (user        . 7))
+  '((none             . 0)
+    (semi-up          . 1)
+    (semi-down        . 2)
+    (simple           . 3)
+    (transparent      . 4)
+    (hollow           . 5)
+    (full             . 6)
+    (semi-up-hollow   . 7)
+    (semi-up-full     . 8)
+    (semi-down-hollow . 9)
+    (semi-down-full   . 10)
+    (user             . 11))
   "Alist associating values for `ebnf-arrow-shape'.
 
 See documentation for `ebnf-arrow-shape'.")
   "Alist associating values for `ebnf-arrow-shape'.
 
 See documentation for `ebnf-arrow-shape'.")
@@ -2464,19 +2838,39 @@ See documentation for `ebnf-terminal-shape', `ebnf-non-terminal-shape' and
 
 /ArrowPath{c newpath moveto Arrow closepath}bind def
 
 
 /ArrowPath{c newpath moveto Arrow closepath}bind def
 
+/UpPath
+{c newpath moveto
+ hT2 neg 0   rmoveto
+ 0       hT4 rlineto
+ hT2 hT4 neg rlineto
+ closepath
+}bind def
+
+/DownPath
+{c newpath moveto
+ hT2 neg 0   rmoveto
+ 0   hT4 neg rlineto
+ hT2     hT4 rlineto
+ closepath
+}bind def
+
 %>Right Arrow: RA
 %    \\
 % *---+
 %    /
 /RA-vector
 %>Right Arrow: RA
 %    \\
 % *---+
 %    /
 /RA-vector
-[{}                                    % 0 - none
- {hT2 neg hT4 rlineto}                 % 1 - semi-up
- {Down}                                        % 2 - semi-down
- {Arrow}                               % 3 - simple
- {Gstroke ArrowPath}                   % 4 - transparent
- {Gstroke ArrowPath 1 FillGray}                % 5 - hollow
- {Gstroke ArrowPath LineColor FillRGB} % 6 - full
- {Gstroke gsave UserArrow grestore}    % 7 - user
+[{}                                    % 0  - none
+ {hT2 neg hT4 rlineto}                 % 1  - semi-up
+ {Down}                                        % 2  - semi-down
+ {Arrow}                               % 3  - simple
+ {Gstroke ArrowPath}                   % 4  - transparent
+ {Gstroke ArrowPath 1 FillGray}                % 5  - hollow
+ {Gstroke ArrowPath LineColor FillRGB} % 6  - full
+ {Gstroke UpPath 1 FillGray}           % 7  - semi-up-hollow
+ {Gstroke UpPath LineColor FillRGB}    % 8  - semi-up-full
+ {Gstroke DownPath 1 FillGray}         % 9  - semi-down-hollow
+ {Gstroke DownPath LineColor FillRGB}  % 10 - semi-down-full
+ {Gstroke gsave UserArrow grestore}    % 11 - user
 ]def
 
 /RA
 ]def
 
 /RA
@@ -3168,10 +3562,11 @@ See documentation for `ebnf-terminal-shape', `ebnf-non-terminal-shape' and
 {xyp
  neg yp add /yw exch def
  xp add T sub /xw exch def
 {xyp
  neg yp add /yw exch def
  xp add T sub /xw exch def
- /Effect EffectP def
- /fP F ForegroundP SetRGB BackgroundP aload pop true BG S
- /Effect 0 def
- ( :) S false BG
+ dup length 0 gt       % empty string ==> no production name
+ {/Effect EffectP def
+  /fP F ForegroundP SetRGB BackgroundP aload pop true BG S
+  /Effect 0 def
+  ( :) S false BG}if
  xw yw moveto
  hT EL RA
  xp yw moveto
  xw yw moveto
  hT EL RA
  xp yw moveto
@@ -3909,11 +4304,15 @@ end
 (defun ebnf-generate-production (production)
   (ebnf-message-info "Generating")
   (run-hooks 'ebnf-production-hook)
 (defun ebnf-generate-production (production)
   (ebnf-message-info "Generating")
   (run-hooks 'ebnf-production-hook)
-  (ps-output-string (ebnf-node-name production))
+  (ps-output-string (if ebnf-production-name-p
+                       (ebnf-node-name production)
+                     ""))
   (ps-output " "
             (ebnf-format-float
              (ebnf-node-width production)
   (ps-output " "
             (ebnf-format-float
              (ebnf-node-width production)
-             (+ ebnf-basic-height
+             (+ (if ebnf-production-name-p
+                    ebnf-basic-height
+                  0.0)
                 (ebnf-node-entry (ebnf-node-production production))))
             " BOP\n")
   (ebnf-node-generation (ebnf-node-production production))
                 (ebnf-node-entry (ebnf-node-production production))))
             " BOP\n")
   (ebnf-node-generation (ebnf-node-production production))
@@ -4102,6 +4501,35 @@ end
 ;; Internal functions
 
 
 ;; Internal functions
 
 
+(defun ebnf-directory (fun &optional directory)
+  "Process files in DIRECTORY applying function FUN on each file.
+
+If DIRECTORY is nil, it's used `default-directory'.
+
+The files in DIRECTORY that matches `ebnf-file-suffix-regexp' (which see) are
+processed."
+  (let ((files (directory-files (or directory default-directory)
+                               t ebnf-file-suffix-regexp)))
+    (while files
+      (set-buffer (find-file-noselect (car files)))
+      (funcall fun)
+      (setq buffer-backed-up t)                    ; Do not back it up.
+      (save-buffer)                        ; Just save new version.
+      (kill-buffer (current-buffer))
+      (setq files (cdr files)))))
+
+
+(defun ebnf-file (fun file &optional do-not-kill-buffer-when-done)
+  "Process file FILE applying function FUN.
+
+If optional arg DO-NOT-KILL-BUFFER-WHEN-DONE is non-nil, the buffer isn't
+killed after process termination."
+  (set-buffer (find-file-noselect file))
+  (funcall fun)
+  (or do-not-kill-buffer-when-done
+      (kill-buffer (current-buffer))))
+
+
 ;; function `ebnf-range-regexp' is used to avoid a bug of `skip-chars-forward'
 ;; on version 20.4.1, that is, it doesn't accept ranges like "\240-\377" (or
 ;; "\177-\237"), but it accepts the character sequence from \240 to \377 (or
 ;; function `ebnf-range-regexp' is used to avoid a bug of `skip-chars-forward'
 ;; on version 20.4.1, that is, it doesn't accept ranges like "\240-\377" (or
 ;; "\177-\237"), but it accepts the character sequence from \240 to \377 (or
@@ -4143,6 +4571,7 @@ end
 (defun ebnf-generate-region (from to gen-func)
   (run-hooks 'ebnf-hook)
   (let ((ebnf-limit (max from to))
 (defun ebnf-generate-region (from to gen-func)
   (run-hooks 'ebnf-hook)
   (let ((ebnf-limit (max from to))
+       (error-msg "SYNTAX")
        the-point)
     (save-excursion
       (save-restriction
        the-point)
     (save-excursion
       (save-restriction
@@ -4150,20 +4579,38 @@ end
          (condition-case data
              (let ((tree (ebnf-parse-and-sort (min from to))))
                (when gen-func
          (condition-case data
              (let ((tree (ebnf-parse-and-sort (min from to))))
                (when gen-func
-                 (funcall gen-func
-                          (ebnf-dimensions
-                           (ebnf-optimize
-                            (ebnf-eliminate-empty-rules tree))))))
+                 (setq error-msg "EMPTY RULES"
+                       tree      (ebnf-eliminate-empty-rules tree))
+                 (setq error-msg "OPTMIZE"
+                       tree      (ebnf-optimize tree))
+                 (setq error-msg "DIMENSIONS"
+                       tree      (ebnf-dimensions tree))
+                 (setq error-msg "GENERATION")
+                 (funcall gen-func tree))
+               (setq error-msg nil))   ; here it's ok
            ;; handler
            ((quit error)
             (ding)
            ;; handler
            ((quit error)
             (ding)
-            (setq the-point (max (1- (point)) (point-min)))
-            (message (error-message-string data)))))))
+            (setq the-point (max (1- (point)) (point-min))
+                  error-msg (concat error-msg ": "
+                                    (error-message-string data)
+                                    ", "
+                                    (and (string= error-msg "SYNTAX")
+                                         (format "at position %d "
+                                                 the-point))
+                                    (format "in buffer \"%s\"."
+                                            (buffer-name)))))))))
     (cond
     (cond
-     (the-point
-      (goto-char the-point))
+     ;; error occurred
+     (error-msg
+      (goto-char the-point)
+      (if ebnf-stop-on-error
+         (error error-msg)
+       (message error-msg)))
+     ;; generated output OK
      (gen-func
       nil)
      (gen-func
       nil)
+     ;; syntax checked OK
      (t
       (message "EBNF syntactic analysis: NO ERRORS.")))))
 
      (t
       (message "EBNF syntactic analysis: NO ERRORS.")))))
 
@@ -4267,6 +4714,17 @@ end
   (ebnf-font-select font 'line-height))
 
 
   (ebnf-font-select font 'line-height))
 
 
+(defconst ebnf-syntax-alist
+  ;; 0.syntax  1.parser         2.initializer
+  '((iso-ebnf  ebnf-iso-parser  ebnf-iso-initialize)
+    (yacc      ebnf-yac-parser  ebnf-yac-initialize)
+    (abnf      ebnf-abn-parser  ebnf-abn-initialize)
+    (ebnf      ebnf-bnf-parser  ebnf-bnf-initialize)
+    (ebnfx     ebnf-ebx-parser  ebnf-ebx-initialize)
+    (dtd       ebnf-dtd-parser  ebnf-dtd-initialize))
+  "Alist associating ebnf syntax with a parser and a initializer.")
+
+
 (defun ebnf-begin-job ()
   (ps-printing-region nil nil nil)
   (if ebnf-use-float-format
 (defun ebnf-begin-job ()
   (ps-printing-region nil nil nil)
   (if ebnf-use-float-format
@@ -4276,15 +4734,10 @@ end
          ebnf-message-float "%s"))
   (ebnf-otz-initialize)
   ;; to avoid compilation gripes when calling autoloaded functions
          ebnf-message-float "%s"))
   (ebnf-otz-initialize)
   ;; to avoid compilation gripes when calling autoloaded functions
-  (funcall (cond ((eq ebnf-syntax 'iso-ebnf)
-                 (setq ebnf-parser-func 'ebnf-iso-parser)
-                 'ebnf-iso-initialize)
-                ((eq ebnf-syntax 'yacc)
-                 (setq ebnf-parser-func 'ebnf-yac-parser)
-                 'ebnf-yac-initialize)
-                (t
-                 (setq ebnf-parser-func 'ebnf-bnf-parser)
-                 'ebnf-bnf-initialize)))
+  (let ((init (or (assoc ebnf-syntax ebnf-syntax-alist)
+                 (assoc 'ebnf ebnf-syntax-alist))))
+    (setq ebnf-parser-func (nth 1 init))
+    (funcall (nth 2 init)))
   (and ebnf-terminal-regexp            ; ensures that it's a string or nil
        (not (stringp ebnf-terminal-regexp))
        (setq ebnf-terminal-regexp nil))
   (and ebnf-terminal-regexp            ; ensures that it's a string or nil
        (not (stringp ebnf-terminal-regexp))
        (setq ebnf-terminal-regexp nil))
@@ -4366,52 +4819,53 @@ end
 
 
 (defun ebnf-eps-finish-and-write (buffer filename)
 
 
 (defun ebnf-eps-finish-and-write (buffer filename)
-  (save-excursion
-    (set-buffer buffer)
-    (setq ebnf-eps-upper-x (max ebnf-eps-upper-x ebnf-eps-max-width)
-         ebnf-eps-upper-y (if (zerop ebnf-eps-upper-y)
-                              ebnf-eps-max-height
-                            (+ ebnf-eps-upper-y
-                               ebnf-production-vertical-space
-                               ebnf-eps-max-height)))
-    ;; prologue
-    (goto-char (point-min))
-    (insert
-     "%!PS-Adobe-3.0 EPSF-3.0"
-     "\n%%BoundingBox: 0 0 "
-     (format "%d %d" (1+ ebnf-eps-upper-x) (1+ ebnf-eps-upper-y))
-     "\n%%Title: " filename
-     "\n%%CreationDate: " (format-time-string "%T %b %d %Y")
-     "\n%%Creator: " (user-full-name) " (using ebnf2ps v" ebnf-version ")"
-     "\n%%DocumentNeededResources: font "
-     (or ebnf-fonts-required
-        (setq ebnf-fonts-required
-              (mapconcat 'identity
-                         (ps-remove-duplicates
-                          (mapcar 'ebnf-font-name-select
-                                  (list ebnf-production-font
-                                        ebnf-terminal-font
-                                        ebnf-non-terminal-font
-                                        ebnf-special-font
-                                        ebnf-except-font
-                                        ebnf-repeat-font)))
-                         "\n%%+ font ")))
-     "\n%%Pages: 0\n%%EndComments\n\n%%BeginProlog\n"
-     ebnf-eps-prologue)
-    (ebnf-insert-ebnf-prologue)
-    (insert ebnf-eps-begin
-           "\n0 " (ebnf-format-float
-                   (- ebnf-eps-upper-y (* ebnf-font-height-P 0.7)))
-           " #ebnf2ps#begin\n")
-    ;; epilogue
-    (goto-char (point-max))
-    (insert ebnf-eps-end)
-    ;; write file
-    (message "Saving...")
-    (setq filename (expand-file-name filename))
-    (let ((coding-system-for-write 'raw-text-unix))
-      (write-region (point-min) (point-max) filename))
-    (message "Wrote %s" filename)))
+  (when (buffer-modified-p buffer)
+    (save-excursion
+      (set-buffer buffer)
+      (setq ebnf-eps-upper-x (max ebnf-eps-upper-x ebnf-eps-max-width)
+           ebnf-eps-upper-y (if (zerop ebnf-eps-upper-y)
+                                ebnf-eps-max-height
+                              (+ ebnf-eps-upper-y
+                                 ebnf-production-vertical-space
+                                 ebnf-eps-max-height)))
+      ;; prologue
+      (goto-char (point-min))
+      (insert
+       "%!PS-Adobe-3.0 EPSF-3.0"
+       "\n%%BoundingBox: 0 0 "
+       (format "%d %d" (1+ ebnf-eps-upper-x) (1+ ebnf-eps-upper-y))
+       "\n%%Title: " filename
+       "\n%%CreationDate: " (format-time-string "%T %b %d %Y")
+       "\n%%Creator: " (user-full-name) " (using ebnf2ps v" ebnf-version ")"
+       "\n%%DocumentNeededResources: font "
+       (or ebnf-fonts-required
+          (setq ebnf-fonts-required
+                (mapconcat 'identity
+                           (ps-remove-duplicates
+                            (mapcar 'ebnf-font-name-select
+                                    (list ebnf-production-font
+                                          ebnf-terminal-font
+                                          ebnf-non-terminal-font
+                                          ebnf-special-font
+                                          ebnf-except-font
+                                          ebnf-repeat-font)))
+                           "\n%%+ font ")))
+       "\n%%Pages: 0\n%%EndComments\n\n%%BeginProlog\n"
+       ebnf-eps-prologue)
+      (ebnf-insert-ebnf-prologue)
+      (insert ebnf-eps-begin
+             "\n0 " (ebnf-format-float
+                     (- ebnf-eps-upper-y (* ebnf-font-height-P 0.7)))
+             " #ebnf2ps#begin\n")
+      ;; epilogue
+      (goto-char (point-max))
+      (insert ebnf-eps-end)
+      ;; write file
+      (message "Saving...")
+      (setq filename (expand-file-name filename))
+      (let ((coding-system-for-write 'raw-text-unix))
+       (write-region (point-min) (point-max) filename))
+      (message "Wrote %s" filename))))
 
 
 (defun ebnf-insert-ebnf-prologue ()
 
 
 (defun ebnf-insert-ebnf-prologue ()
@@ -4588,12 +5042,16 @@ end
   (ebnf-message-info "Calculating dimensions")
   (ebnf-node-dimension-func (ebnf-node-production production))
   (let* ((prod   (ebnf-node-production production))
   (ebnf-message-info "Calculating dimensions")
   (ebnf-node-dimension-func (ebnf-node-production production))
   (let* ((prod   (ebnf-node-production production))
-        (height (+ ebnf-font-height-P
+        (height (+ (if ebnf-production-name-p
+                       ebnf-font-height-P
+                     0.0)
+                   ebnf-line-width ebnf-line-width
                    ebnf-basic-height
                    (ebnf-node-height prod))))
     (ebnf-node-entry  production height)
     (ebnf-node-height production height)
     (ebnf-node-width  production (+ (ebnf-node-width prod)
                    ebnf-basic-height
                    (ebnf-node-height prod))))
     (ebnf-node-entry  production height)
     (ebnf-node-height production height)
     (ebnf-node-width  production (+ (ebnf-node-width prod)
+                                   ebnf-line-width
                                    ebnf-horizontal-space))))
 
 
                                    ebnf-horizontal-space))))
 
 
@@ -4850,7 +5308,7 @@ end
 
 ;; [one-or-more  width-fun dim-fun entry height width element separator]
 ;; [zero-or-more width-fun dim-fun entry height width element separator]
 
 ;; [one-or-more  width-fun dim-fun entry height width element separator]
 ;; [zero-or-more width-fun dim-fun entry height width element separator]
-(defun ebnf-list-width (or-more width)
+(defun ebnf-element-width (or-more width)
   (setq width (- width ebnf-horizontal-space))
   (ebnf-node-list or-more
                  (ebnf-justify-list or-more
   (setq width (- width ebnf-horizontal-space))
   (ebnf-node-list or-more
                  (ebnf-justify-list or-more
@@ -4881,7 +5339,10 @@ end
        ;; right justify terms
        ((eq ebnf-justify-sequence 'right)
        (ebnf-justify node seq seq-width width nil))
        ;; right justify terms
        ((eq ebnf-justify-sequence 'right)
        (ebnf-justify node seq seq-width width nil))
-       ;; centralize terms
+       ;; centralize terms -- element
+       ((vectorp seq)
+       (ebnf-adjust-width seq width))
+       ;; centralize terms -- list
        (t
        (let ((the-width (/ (- width seq-width) (length seq)))
              (lis seq))
        (t
        (let ((the-width (/ (- width seq-width) (length seq)))
              (lis seq))
@@ -5040,10 +5501,11 @@ end
          0.0
          0.0
          (let ((len (length name)))
          0.0
          0.0
          (let ((len (length name)))
-           (cond ((> len 2) name)
-                 ((= len 2) (concat " " name))
-                 ((= len 1) (concat " " name " "))
-                 (t         "   ")))
+           (cond ((> len 3) name)
+                 ((= len 3) (concat name " "))
+                 ((= len 2) (concat " " name " "))
+                 ((= len 1) (concat " " name "  "))
+                 (t         "    ")))
          ebnf-default-p))
 
 
          ebnf-default-p))
 
 
@@ -5063,7 +5525,7 @@ end
 
 (defun ebnf-make-or-more1 (gen-func dim-func list-part sep-part)
   (vector gen-func
 
 (defun ebnf-make-or-more1 (gen-func dim-func list-part sep-part)
   (vector gen-func
-         'ebnf-list-width
+         'ebnf-element-width
          dim-func
          0.0
          0.0
          dim-func
          0.0
          0.0
@@ -5119,14 +5581,25 @@ end
          exception))
 
 
          exception))
 
 
-(defun ebnf-make-repeat (times primary)
+(defun ebnf-make-repeat (times primary &optional upper)
   (vector 'ebnf-generate-repeat
          'ignore
          'ebnf-repeat-dimension
          0.0
          0.0
          0.0
   (vector 'ebnf-generate-repeat
          'ignore
          'ebnf-repeat-dimension
          0.0
          0.0
          0.0
-         (concat times " *")
+         (cond ((and times upper)      ; L * U, L * L
+                (if (string= times upper)
+                    (if (string= times "")
+                        " * "
+                      times)
+                  (concat times " * " upper)))
+               (times                  ; L *
+                (concat times " *"))
+               (upper                  ; * U
+                (concat "* " upper))
+               (t                      ; *
+                " * "))
          primary))
 
 
          primary))
 
 
@@ -5198,13 +5671,13 @@ end
                )))))
 
 
                )))))
 
 
-(defun ebnf-token-repeat (times repeat)
+(defun ebnf-token-repeat (times repeat &optional upper)
   (if (null (cdr repeat))
       ;; n * EMPTY ==> EMPTY
       repeat
     ;; n * term
     (cons (car repeat)
   (if (null (cdr repeat))
       ;; n * EMPTY ==> EMPTY
       repeat
     ;; n * term
     (cons (car repeat)
-         (ebnf-make-repeat times (cdr repeat)))))
+         (ebnf-make-repeat times (cdr repeat) upper))))
 
 
 (defun ebnf-token-optional (body)
 
 
 (defun ebnf-token-optional (body)
@@ -5245,6 +5718,20 @@ end
                                                   (cons seq body)
                                                 body))))))))
 
                                                   (cons seq body)
                                                 body))))))))
 
+
+(defun ebnf-token-sequence (sequence)
+  (cond
+   ;; null sequence
+   ((null sequence)
+    (ebnf-make-empty))
+   ;; sequence with only one element
+   ((= (length sequence) 1)
+    (car sequence))
+   ;; a real sequence
+   (t
+    (ebnf-make-sequence (nreverse sequence)))
+   ))
+
 \f
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Variables used by parsers
 \f
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Variables used by parsers
@@ -5255,6 +5742,7 @@ end
     ;; Override special comment character:
     (aset table ?< 'newline)
     (aset table ?> 'keep-line)
     ;; Override special comment character:
     (aset table ?< 'newline)
     (aset table ?> 'keep-line)
+    (aset table ?^ 'form-feed)
     table)
   "Vector used to map characters to a special comment token.")
 
     table)
   "Vector used to map characters to a special comment token.")
 
@@ -5263,6 +5751,12 @@ end
 ;; To make this file smaller, some commands go in a separate file.
 ;; But autoload them here to make the separation invisible.
 
 ;; To make this file smaller, some commands go in a separate file.
 ;; But autoload them here to make the separation invisible.
 
+(autoload 'ebnf-abn-parser            "ebnf-abn"
+  "ABNF parser.")
+
+(autoload 'ebnf-abn-initialize        "ebnf-abn"
+  "Initialize ABNF token table.")
+
 (autoload 'ebnf-bnf-parser            "ebnf-bnf"
   "EBNF parser.")
 
 (autoload 'ebnf-bnf-parser            "ebnf-bnf"
   "EBNF parser.")
 
@@ -5281,14 +5775,17 @@ end
 (autoload 'ebnf-yac-initialize        "ebnf-yac"
   "Initializations for Yacc/Bison parser.")
 
 (autoload 'ebnf-yac-initialize        "ebnf-yac"
   "Initializations for Yacc/Bison parser.")
 
-(autoload 'ebnf-eliminate-empty-rules "ebnf-otz"
-  "Eliminate empty rules.")
+(autoload 'ebnf-ebx-parser            "ebnf-ebx"
+  "EBNFX parser.")
 
 
-(autoload 'ebnf-optimize              "ebnf-otz"
-  "Syntactic chart optimizer.")
+(autoload 'ebnf-ebx-initialize        "ebnf-ebx"
+  "Initializations for EBNFX parser.")
 
 
-(autoload 'ebnf-otz-initialize        "ebnf-otz"
-  "Initialize optimizer.")
+(autoload 'ebnf-dtd-parser            "ebnf-dtd"
+  "DTD parser.")
+
+(autoload 'ebnf-dtd-initialize        "ebnf-dtd"
+  "Initializations for DTD parser.")
 
 \f
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 \f
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;