* hl-line.el (hl-line): New face.
[bpt/emacs.git] / lisp / progmodes / ebnf2ps.el
index db9ed4a..bce4381 100644 (file)
@@ -1,39 +1,42 @@
-;;; ebnf2ps --- Translate an EBNF to a syntatic chart on PostScript
+;;; ebnf2ps.el --- translate an EBNF to a syntactic chart on PostScript
 
-;; Copyright (C) 1999 Vinicius Jose Latorre
+;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+;; Free Software Foundation, Inc.
 
-;; Author:     Vinicius Jose Latorre <vinicius@cpqd.com.br>
-;; Maintainer: Vinicius Jose Latorre <vinicius@cpqd.com.br>
-;; Keywords:   wp, ebnf, PostScript
-;; Time-stamp: <99/12/11 21:41:24 vinicius>
-;; Version:    3.1
+;; Author: Vinicius Jose Latorre <viniciusjl@ig.com.br>
+;; Maintainer: Vinicius Jose Latorre <viniciusjl@ig.com.br>
+;; Time-stamp: <2005-09-18 07:27:20 deego>
+;; Keywords: wp, ebnf, PostScript
+;; Version: 4.2
+;; X-URL: http://www.cpqd.com.br/~vinicius/emacs/
 
-(defconst ebnf-version "3.1"
-  "ebnf2ps.el, v 3.1 <99/12/11 vinicius>
+;; This file is part of GNU Emacs.
 
-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>.
-")
-
-;; This file is *NOT* (yet?) part of GNU Emacs.
-
-;; This program is free software; you can redistribute it and/or modify
+;; GNU Emacs 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, or (at your option)
 ;; any later version.
 
-;; This program is distributed in the hope that it will be useful,
+;; GNU Emacs 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.
 
 ;; You should have received a copy of the GNU General Public License
 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+(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 Jose Latorre <viniciusjl@ig.com.br>.
+")
+
 
 ;;; Commentary:
 
@@ -42,14 +45,15 @@ Please send all bug fixes and enhancements to
 ;; Introduction
 ;; ------------
 ;;
-;; This package translates an EBNF to a syntatic chart on PostScript.
+;; This package translates an EBNF to a syntactic chart on PostScript.
 ;;
 ;; To use ebnf2ps, insert in your ~/.emacs:
 ;;
 ;;        (require 'ebnf2ps)
 ;;
-;; ebnf2ps uses ps-print package (version 3.05.1 or later), so see ps-print to
-;; know how to set options like landscape printing, page headings, margins, etc.
+;; ebnf2ps uses ps-print package (version 5.2.3 or later), so see ps-print to
+;; know how to set options like landscape printing, page headings, margins,
+;; etc.
 ;;
 ;; NOTE: ps-print zebra stripes and line number options doesn't have effect on
 ;;       ebnf2ps, they behave as it's turned off.
@@ -66,32 +70,38 @@ Please send all bug fixes and enhancements to
 ;; Using ebnf2ps
 ;; -------------
 ;;
-;; ebnf2ps provides six commands for generating PostScript syntatic chart images
-;; of Emacs buffers:
-;;
-;;        ebnf-print-buffer
-;;        ebnf-print-region
-;;        ebnf-spool-buffer
-;;        ebnf-spool-region
-;;        ebnf-eps-buffer
-;;        ebnf-eps-region
+;; 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-spool-directory
+;;     ebnf-spool-file
+;;     ebnf-spool-buffer
+;;     ebnf-spool-region
+;;     ebnf-eps-directory
+;;     ebnf-eps-file
+;;     ebnf-eps-buffer
+;;     ebnf-eps-region
 ;;
 ;; These commands all perform essentially the same function: they generate
-;; PostScript syntatic chart images suitable for printing on a PostScript
+;; PostScript syntactic chart images suitable for printing on a PostScript
 ;; printer or displaying with GhostScript.  These commands are collectively
 ;; referred to as "ebnf- commands".
 ;;
 ;; The word "print", "spool" and "eps" in the command name determines when the
 ;; PostScript image is sent to the printer (or file):
 ;;
-;;        print  - The PostScript image is immediately sent to the printer;
+;;     print  - The PostScript image is immediately sent to the printer;
 ;;
-;;        spool  - The PostScript image is saved temporarily in an Emacs buffer.
-;;                 Many images may be spooled locally before printing them.  To
-;;                 send the spooled images to the printer, use the command
-;;                 `ebnf-despool'.
+;;     spool  - The PostScript image is saved temporarily in an Emacs buffer.
+;;              Many images may be spooled locally before printing them.  To
+;;              send the spooled images to the printer, use the command
+;;              `ebnf-despool'.
 ;;
-;;        eps    - The PostScript image is immediately sent to a EPS file.
+;;     eps    - The PostScript image is immediately sent to a EPS file.
 ;;
 ;; The spooling mechanism is the same as used by ps-print and was designed for
 ;; printing lots of small files to save paper that would otherwise be wasted on
@@ -104,28 +114,33 @@ Please send all bug fixes and enhancements to
 ;; won't accidentally quit from Emacs while you have unprinted PostScript
 ;; waiting in the spool buffer.  If you do attempt to exit with spooled
 ;; PostScript, you'll be asked if you want to print it, and if you decline,
-;; 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:
 ;;
-;;        ebnf-print-buffer  - translate and print the entire buffer, and send
-;;                             it immediately to the printer.
+;;     ebnf-print-buffer  - translate and print the entire buffer, and send it
+;;                          immediately to the printer.
 ;;
-;;        ebnf-spool-region  - translate and print just the current region, and
-;;                             spool the image in Emacs to send to the printer
-;;                             later.
+;;     ebnf-spool-region  - translate and print just the current region, and
+;;                          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
@@ -162,9 +177,36 @@ Please send all bug fixes and enhancements to
 ;;   (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
 ;; -----------
 ;;
+;; 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)
@@ -178,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)
-;;    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
@@ -202,7 +247,7 @@ Please send all bug fixes and enhancements to
 ;;
 ;;    exception = repeat [ "-" repeat].         ;; exception
 ;;
-;;    repeat = [ integer "*" ] term.            ;; repetition
+;;    repeat = [ integer "*" [ integer ]] term. ;; repetition
 ;;
 ;;    term = factor
 ;;         | [factor] "+"                       ;; one-or-more
@@ -219,15 +264,31 @@ Please send all bug fixes and enhancements to
 ;;           | "{" body [ "||" body ] "}"       ;; zero-or-more
 ;;           .
 ;;
-;;    non_terminal = "[A-Za-z\\240-\\377][!#%&'*-,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]\\)+".
+;;    ;; 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]+".
+;;    ;; that is, an integer is a sequence of one or more decimal digits.
 ;;
 ;;    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.
 ;;
@@ -256,8 +317,8 @@ Please send all bug fixes and enhancements to
 ;;    Logical  Expression              non-terminal
 ;;    "("  OR  AND  "XOR"  ")"         terminal
 ;;
-;; The line comment is controlled by `ebnf-lex-comment-char'.  The default value
-;; is ?\; (character `;').
+;; The line comment is controlled by `ebnf-lex-comment-char'.  The default
+;; value is ?\; (character `;').
 ;;
 ;; The end of production is controlled by `ebnf-lex-eop-char'.  The default
 ;; value is ?. (character `.').
@@ -270,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'.
 ;;
+;;    `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").
@@ -282,6 +347,14 @@ Please send all bug fixes and enhancements to
 ;;                     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'.
@@ -320,7 +393,7 @@ Please send all bug fixes and enhancements to
 ;;    6.  A = B | .                ==>   A = [B].
 ;;    7.  A =   | B .              ==>   A = [B].
 ;;
-;; factoration:
+;; factorization:
 ;;    8.  A = B C | B D.           ==>   A = B (C | D).
 ;;    9.  A = C B | D B.           ==>   A = (C | D) B.
 ;;    10. A = B C E | B D E.       ==>   A = B (C | D) E.
@@ -331,8 +404,8 @@ Please send all bug fixes and enhancements to
 ;; Form Feed
 ;; ---------
 ;;
-;; You may use form feed (^L \014) to force a production to start on a new page,
-;; for example:
+;; You may use form feed (^L \014) to force a production to start on a new
+;; page, for example:
 ;;
 ;;    a) A = B | C.
 ;;      ^L
@@ -353,6 +426,8 @@ Please send all bug fixes and enhancements to
 ;;
 ;; 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.
 ;;
@@ -361,9 +436,9 @@ Please send all bug fixes and enhancements to
 ;;
 ;;    ;[EPS    open a new EPS file.  The EPS file name has the form:
 ;;                     <PREFIX><NAME>.eps
-;;             where <PREFIX> is given by variable `ebnf-eps-prefix' and <NAME>
-;;             is the string given by ;[ action comment, this string is mapped
-;;             to form a valid file name (see documentation for
+;;             where <PREFIX> is given by variable `ebnf-eps-prefix' and
+;;             <NAME> is the string given by ;[ action comment, this string is
+;;             mapped to form a valid file name (see documentation for
 ;;             `ebnf-eps-buffer' or `ebnf-eps-region').
 ;;             It has effect only during `ebnf-eps-buffer' or
 ;;             `ebnf-eps-region' execution.
@@ -405,7 +480,8 @@ Please send all bug fixes and enhancements to
 ;; Note that if ascending production sort is used, the productions A and B will
 ;; be drawn in the same line instead of C and B.
 ;;
-;; If consecutive actions occur, only the last one takes effect, so if you have:
+;; If consecutive actions occur, only the last one takes effect, so if you
+;; have:
 ;;
 ;;    A = X.
 ;;    ;<
@@ -416,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.
 ;;
-;; 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;
@@ -478,16 +554,23 @@ Please send all bug fixes and enhancements to
 ;;
 ;; `ebnf-setup' returns the current setup.
 ;;
-;; `ebnf-syntax-buffer' does a syntatic analysis of your EBNF in the current
+;; `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-region' does a syntatic analysis of your EBNF in the current
+;; `ebnf-syntax-region' does a syntactic analysis of your EBNF in the current
 ;; region.
 ;;
 ;; `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
@@ -520,8 +603,8 @@ Please send all bug fixes and enhancements to
 ;; `ebnf-production-horizontal-space'  Specify horizontal space in points
 ;;                                     between productions.
 ;;
-;; `ebnf-production-vertical-space'    Specify vertical space in points between
-;;                                     productions.
+;; `ebnf-production-vertical-space'    Specify vertical space in points
+;;                                     between productions.
 ;;
 ;; `ebnf-justify-sequence'             Specify justification of terms in a
 ;;                                     sequence inside alternatives.
@@ -541,6 +624,9 @@ Please send all bug fixes and enhancements to
 ;;
 ;; `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.
@@ -549,8 +635,8 @@ Please send all bug fixes and enhancements to
 ;;
 ;; `ebnf-non-terminal-shape'           Specify non-terminal box shape.
 ;;
-;; `ebnf-non-terminal-shadow'          Non-nil means non-terminal box will have
-;;                                     a shadow.
+;; `ebnf-non-terminal-shadow'          Non-nil means non-terminal box will
+;;                                     have a shadow.
 ;;
 ;; `ebnf-non-terminal-border-width'    Specify border width for non-terminal
 ;;                                     box.
@@ -558,6 +644,9 @@ Please send all bug fixes and enhancements to
 ;; `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.
@@ -603,15 +692,16 @@ Please send all bug fixes and enhancements to
 ;;
 ;; `ebnf-line-color'                   Specify flow line color.
 ;;
-;; `ebnf-user-arrow'                   Specify a user arrow shape (a PostScript
-;;                                     code).
+;; `ebnf-user-arrow'                   Specify a sexp for user arrow shape (a
+;;                                     PostScript code).
 ;;
 ;; `ebnf-debug-ps'                     Non-nil means to generate PostScript
 ;;                                     debug procedures.
 ;;
 ;; `ebnf-lex-comment-char'             Specify the line comment character.
 ;;
-;; `ebnf-lex-eop-char'                 Specify the end of production character.
+;; `ebnf-lex-eop-char'                 Specify the end of production
+;;                                     character.
 ;;
 ;; `ebnf-syntax'                       Specify syntax to be recognized.
 ;;
@@ -624,16 +714,22 @@ Please send all bug fixes and enhancements to
 ;;                                     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-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-optimize'                     Non-nil means optimize syntatic chart of
-;;                                     rules.
+;; `ebnf-optimize'                     Non-nil means optimize syntactic chart
+;;                                     of rules.
 ;;
 ;; To set the above options you may:
 ;;
@@ -690,24 +786,27 @@ Please send all bug fixes and enhancements to
 ;; `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-apply-style'  Set STYLE to current style.
+;; `ebnf-apply-style'  Set STYLE as the 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.
 ;;
-;; 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
+;; 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
 ;; unmodified.
 ;;
 ;; See documentation for `ebnf-style-database'.
@@ -722,8 +821,8 @@ Please send all bug fixes and enhancements to
 ;;    font height      is given by:
 ;;                     (terminal font height + non-terminal font height) / 2
 ;;
-;;    entry            is the vertical position used to know where it should be
-;;                     drawn the flow line in the current element.
+;;    entry            is the vertical position used to know where it should
+;;                     be drawn the flow line in the current element.
 ;;
 ;;
 ;;    * SPECIAL, TERMINAL and NON-TERMINAL
@@ -926,16 +1025,16 @@ Please send all bug fixes and enhancements to
 ;; Internal Structures
 ;; -------------------
 ;;
-;; ebnf2ps has two passes.  The first pass does a lexical and syntatic analysis
+;; ebnf2ps has two passes.  The first pass does a lexical and syntactic analysis
 ;; of current buffer and generates an intermediate representation.  The second
-;; pass uses the intermediate representation to generate the PostScript syntatic
-;; chart.
+;; pass uses the intermediate representation to generate the PostScript
+;; syntactic chart.
 ;;
 ;; The intermediate representation is a list of vectors, the vector element
-;; represents a syntatic chart element.  Below is a vector representation for
-;; each syntatic chart element.
+;; represents a syntactic chart element.  Below is a vector representation for
+;; each syntactic chart element.
 ;;
-;; [production   WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH NAME    PRODUCTION ACTION]
+;; [production   WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH NAME   PRODUCTION ACTION]
 ;; [alternative  WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH LIST]
 ;; [sequence     WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH LIST]
 ;; [terminal     WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH NAME    DEFAULT]
@@ -981,7 +1080,7 @@ Please send all bug fixes and enhancements to
 ;; Things To Change
 ;; ----------------
 ;;
-;; . Handle situations when syntatic chart is out of paper.
+;; . Handle situations when syntactic chart is out of paper.
 ;; . Use other alphabet than ascii.
 ;; . Optimizations...
 ;;
@@ -989,34 +1088,44 @@ Please send all bug fixes and enhancements to
 ;; 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.
 ;;
 ;;
 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
-;;; code:
+;;; Code:
 
 
 (require 'ps-print)
 
-(and (string< ps-print-version "3.05.1")
-     (error "`ebnf2ps' requires `ps-print' package version 3.05.1 or later"))
-
-
-;; temporary fix for ps-print
-(or (fboundp 'set-buffer-multibyte)
-    (defun set-buffer-multibyte (arg)
-      (setq enable-multibyte-characters arg)))
-
-(or (fboundp 'string-as-unibyte)
-    (defun string-as-unibyte (arg) arg))
+(and (string< ps-print-version "5.2.3")
+     (error "`ebnf2ps' requires `ps-print' package version 5.2.3 or later"))
 
-(or (fboundp 'string-as-multibyte)
-    (defun string-as-multibyte (arg) arg))
 
-(or (fboundp 'charset-after)
-    (defun charset-after (&optional arg)
-      (char-charset (char-after arg))))
+;; to avoid gripes with Emacs 20
+(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
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1026,91 +1135,104 @@ Please send all bug fixes and enhancements to
 ;;; Interface to the command system
 
 (defgroup postscript nil
-  "PostScript Group"
+  "PostScript Group."
   :tag "PostScript"
+  :version "20"
   :group 'emacs)
 
 
 (defgroup ebnf2ps nil
-  "Translate an EBNF to a syntatic chart on PostScript"
+  "Translate an EBNF to a syntactic chart on PostScript."
   :prefix "ebnf-"
+  :version "20"
   :group 'wp
   :group 'postscript)
 
 
 (defgroup ebnf-special nil
-  "Special customization"
+  "Special customization."
   :prefix "ebnf-"
   :tag "Special"
+  :version "20"
   :group 'ebnf2ps)
 
 
 (defgroup ebnf-except nil
-  "Except customization"
+  "Except customization."
   :prefix "ebnf-"
   :tag "Except"
+  :version "20"
   :group 'ebnf2ps)
 
 
 (defgroup ebnf-repeat nil
-  "Repeat customization"
+  "Repeat customization."
   :prefix "ebnf-"
   :tag "Repeat"
+  :version "20"
   :group 'ebnf2ps)
 
 
 (defgroup ebnf-terminal nil
-  "Terminal customization"
+  "Terminal customization."
   :prefix "ebnf-"
   :tag "Terminal"
+  :version "20"
   :group 'ebnf2ps)
 
 
 (defgroup ebnf-non-terminal nil
-  "Non-Terminal customization"
+  "Non-Terminal customization."
   :prefix "ebnf-"
   :tag "Non-Terminal"
+  :version "20"
   :group 'ebnf2ps)
 
 
 (defgroup ebnf-production nil
-  "Production customization"
+  "Production customization."
   :prefix "ebnf-"
   :tag "Production"
+  :version "20"
   :group 'ebnf2ps)
 
 
 (defgroup ebnf-shape nil
-  "Shapes customization"
+  "Shapes customization."
   :prefix "ebnf-"
   :tag "Shape"
+  :version "20"
   :group 'ebnf2ps)
 
 
 (defgroup ebnf-displacement nil
-  "Displacement customization"
+  "Displacement customization."
   :prefix "ebnf-"
   :tag "Displacement"
+  :version "20"
   :group 'ebnf2ps)
 
 
-(defgroup ebnf-syntatic nil
-  "Syntatic customization"
+(defgroup ebnf-syntactic nil
+  "Syntactic customization."
   :prefix "ebnf-"
-  :tag "Syntatic"
+  :tag "Syntactic"
+  :version "20"
   :group 'ebnf2ps)
 
 
 (defgroup ebnf-optimization nil
-  "Optimization customization"
+  "Optimization customization."
   :prefix "ebnf-"
   :tag "Optimization"
+  :version "20"
   :group 'ebnf2ps)
 
 
 (defcustom ebnf-horizontal-orientation nil
   "*Non-nil means productions are drawn horizontally."
   :type 'boolean
+  :version "20"
   :group 'ebnf-displacement)
 
 
@@ -1119,6 +1241,7 @@ Please send all bug fixes and enhancements to
 
 It is only used when `ebnf-horizontal-orientation' is non-nil."
   :type 'boolean
+  :version "20"
   :group 'ebnf-displacement)
 
 
@@ -1127,6 +1250,7 @@ It is only used when `ebnf-horizontal-orientation' is non-nil."
 
 Value less or equal to zero forces ebnf2ps to set a proper default value."
   :type 'number
+  :version "20"
   :group 'ebnf-displacement)
 
 
@@ -1135,6 +1259,7 @@ Value less or equal to zero forces ebnf2ps to set a proper default value."
 
 Value less or equal to zero forces ebnf2ps to set a proper default value."
   :type 'number
+  :version "20"
   :group 'ebnf-displacement)
 
 
@@ -1148,9 +1273,17 @@ Valid values are:
    any other value     centralize"
   :type '(radio :tag "Sequence Justification"
                (const left) (const right) (other :tag "center" center))
+  :version "20"
   :group 'ebnf-displacement)
 
 
+(defcustom ebnf-special-show-delimiter t
+  "*Non-nil means special delimiter (character `?') is shown."
+  :type 'boolean
+  :version "20"
+  :group 'ebnf-special)
+
+
 (defcustom ebnf-special-font '(7 Courier "Black" "Gray95" bold italic)
   "*Specify special font.
 
@@ -1169,6 +1302,7 @@ See documentation for `ebnf-production-font'."
                               (const underline) (const strikeout)
                               (const overline)  (const shadow)
                               (const box)       (const outline))))
+  :version "20"
   :group 'ebnf-special)
 
 
@@ -1178,24 +1312,28 @@ See documentation for `ebnf-production-font'."
 See documentation for `ebnf-non-terminal-shape'."
   :type '(radio :tag "Special Shape"
                (const miter) (const round) (const bevel))
+  :version "20"
   :group 'ebnf-special)
 
 
 (defcustom ebnf-special-shadow nil
   "*Non-nil means special box will have a shadow."
   :type 'boolean
+  :version "20"
   :group 'ebnf-special)
 
 
 (defcustom ebnf-special-border-width 0.5
   "*Specify border width for special box."
   :type 'number
+  :version "20"
   :group 'ebnf-special)
 
 
 (defcustom ebnf-special-border-color "Black"
   "*Specify border color for special box."
   :type 'string
+  :version "20"
   :group 'ebnf-special)
 
 
@@ -1217,6 +1355,7 @@ See documentation for `ebnf-production-font'."
                               (const underline) (const strikeout)
                               (const overline)  (const shadow)
                               (const box)       (const outline))))
+  :version "20"
   :group 'ebnf-except)
 
 
@@ -1226,24 +1365,28 @@ See documentation for `ebnf-production-font'."
 See documentation for `ebnf-non-terminal-shape'."
   :type '(radio :tag "Except Shape"
                (const miter) (const round) (const bevel))
+  :version "20"
   :group 'ebnf-except)
 
 
 (defcustom ebnf-except-shadow nil
   "*Non-nil means except box will have a shadow."
   :type 'boolean
+  :version "20"
   :group 'ebnf-except)
 
 
 (defcustom ebnf-except-border-width 0.25
   "*Specify border width for except box."
   :type 'number
+  :version "20"
   :group 'ebnf-except)
 
 
 (defcustom ebnf-except-border-color "Black"
   "*Specify border color for except box."
   :type 'string
+  :version "20"
   :group 'ebnf-except)
 
 
@@ -1265,6 +1408,7 @@ See documentation for `ebnf-production-font'."
                               (const underline) (const strikeout)
                               (const overline)  (const shadow)
                               (const box)       (const outline))))
+  :version "20"
   :group 'ebnf-repeat)
 
 
@@ -1274,24 +1418,28 @@ See documentation for `ebnf-production-font'."
 See documentation for `ebnf-non-terminal-shape'."
   :type '(radio :tag "Repeat Shape"
                (const miter) (const round) (const bevel))
+  :version "20"
   :group 'ebnf-repeat)
 
 
 (defcustom ebnf-repeat-shadow nil
   "*Non-nil means repeat box will have a shadow."
   :type 'boolean
+  :version "20"
   :group 'ebnf-repeat)
 
 
 (defcustom ebnf-repeat-border-width 0.0
   "*Specify border width for repeat box."
   :type 'number
+  :version "20"
   :group 'ebnf-repeat)
 
 
 (defcustom ebnf-repeat-border-color "Black"
   "*Specify border color for repeat box."
   :type 'string
+  :version "20"
   :group 'ebnf-repeat)
 
 
@@ -1313,6 +1461,7 @@ See documentation for `ebnf-production-font'."
                               (const underline) (const strikeout)
                               (const overline)  (const shadow)
                               (const box)       (const outline))))
+  :version "20"
   :group 'ebnf-terminal)
 
 
@@ -1322,27 +1471,38 @@ See documentation for `ebnf-production-font'."
 See documentation for `ebnf-non-terminal-shape'."
   :type '(radio :tag "Terminal Shape"
                (const miter) (const round) (const bevel))
+  :version "20"
   :group 'ebnf-terminal)
 
 
 (defcustom ebnf-terminal-shadow nil
   "*Non-nil means terminal box will have a shadow."
   :type 'boolean
+  :version "20"
   :group 'ebnf-terminal)
 
 
 (defcustom ebnf-terminal-border-width 1.0
   "*Specify border width for terminal box."
   :type 'number
+  :version "20"
   :group 'ebnf-terminal)
 
 
 (defcustom ebnf-terminal-border-color "Black"
   "*Specify border color for terminal box."
   :type 'string
+  :version "20"
   :group 'ebnf-terminal)
 
 
+(defcustom ebnf-production-name-p t
+  "*Non-nil means production name will be printed."
+  :type 'boolean
+  :version "20"
+  :group 'ebnf-production)
+
+
 (defcustom ebnf-sort-production nil
   "*Specify how productions are sorted.
 
@@ -1355,6 +1515,7 @@ Valid values are:
                (const :tag "Ascending" ascending)
                (const :tag "Descending" descending)
                (other :tag "No Sort" nil))
+  :version "20"
   :group 'ebnf-production)
 
 
@@ -1397,6 +1558,7 @@ See `ps-font-info-database' for valid font name."
                               (const underline) (const strikeout)
                               (const overline)  (const shadow)
                               (const box)       (const outline))))
+  :version "20"
   :group 'ebnf-production)
 
 
@@ -1418,6 +1580,7 @@ See documentation for `ebnf-production-font'."
                               (const underline) (const strikeout)
                               (const overline)  (const shadow)
                               (const box)       (const outline))))
+  :version "20"
   :group 'ebnf-non-terminal)
 
 
@@ -1441,24 +1604,28 @@ Valid values are:
 Any other value is treated as `miter'."
   :type '(radio :tag "Non-Terminal Shape"
                (const miter) (const round) (const bevel))
+  :version "20"
   :group 'ebnf-non-terminal)
 
 
 (defcustom ebnf-non-terminal-shadow nil
   "*Non-nil means non-terminal box will have a shadow."
   :type 'boolean
+  :version "20"
   :group 'ebnf-non-terminal)
 
 
 (defcustom ebnf-non-terminal-border-width 1.0
   "*Specify border width for non-terminal box."
   :type 'number
+  :version "20"
   :group 'ebnf-non-terminal)
 
 
 (defcustom ebnf-non-terminal-border-color "Black"
   "*Specify border color for non-terminal box."
   :type 'string
+  :version "20"
   :group 'ebnf-non-terminal)
 
 
@@ -1493,14 +1660,29 @@ 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"
-               (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))
+  :version "20"
   :group 'ebnf-shape)
 
 
@@ -1510,13 +1692,15 @@ Any other value is treated as `none'."
 See documentation for `ebnf-non-terminal-shape'."
   :type '(radio :tag "Chart Flow Shape"
                (const miter) (const round) (const bevel))
+  :version "20"
   :group 'ebnf-shape)
 
 
 (defcustom ebnf-user-arrow nil
-  "*Specify a user arrow shape (a PostScript code).
+  "*Specify a sexp for user arrow shape (a PostScript code).
 
-PostScript code should draw a right arrow.
+When evaluated, the sexp should return nil or a string containing PostScript
+code.  PostScript code should draw a right arrow.
 
 The anatomy of a right arrow is:
 
@@ -1538,25 +1722,17 @@ The anatomy of a right arrow is:
    :               } hT2  }
    :.......................
 
-Where `hT', `hT2' and `hT4' are predefined PostScript variable names that can be
-used to generate your own arrow.  As these variables are used along PostScript
-execution, *DON'T* modify the values of them.  Instead, copy the values, if you
-need to modify them.
+Where `hT', `hT2' and `hT4' are predefined PostScript variable names that can
+be used to generate your own arrow.  As these variables are used along
+PostScript execution, *DON'T* modify the values of them.  Instead, copy the
+values, if you need to modify them.
 
 The relation between these variables is: hT = 2 * hT2 = 4 * hT4.
 
 The variable `ebnf-user-arrow' is only used when `ebnf-arrow-shape' is set to
-symbol `user'.
-
-See function `ebnf-user-arrow' for valid values and how values are processed."
-  :type '(radio :tag "User Arrow Shape"
-               (const nil)
-               string
-               symbol
-               (repeat :tag "List"
-                       (radio string
-                              symbol
-                              sexp)))
+symbol `user'."
+  :type '(sexp :tag "User Arrow Shape")
+  :version "20"
   :group 'ebnf-shape)
 
 
@@ -1572,6 +1748,10 @@ Valid values are:
                `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\").
@@ -1584,10 +1764,20 @@ Valid values are:
                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"
-               (const ebnf) (const iso-ebnf) (const yacc))
-  :group 'ebnf-syntatic)
+               (const ebnf) (const abnf)  (const iso-ebnf)
+               (const yacc) (const ebnfx) (const dtd))
+  :version "20"
+  :group 'ebnf-syntactic)
 
 
 (defcustom ebnf-lex-comment-char ?\;
@@ -1595,7 +1785,8 @@ Any other value is treated as `ebnf'."
 
 It's used only when `ebnf-syntax' is `ebnf'."
   :type 'character
-  :group 'ebnf-syntatic)
+  :version "20"
+  :group 'ebnf-syntactic)
 
 
 (defcustom ebnf-lex-eop-char ?.
@@ -1603,7 +1794,8 @@ It's used only when `ebnf-syntax' is `ebnf'."
 
 It's used only when `ebnf-syntax' is `ebnf'."
   :type 'character
-  :group 'ebnf-syntatic)
+  :version "20"
+  :group 'ebnf-syntactic)
 
 
 (defcustom ebnf-terminal-regexp nil
@@ -1616,7 +1808,8 @@ terminal name; terminal name may also be enclosed by `\"'.
 It's used only when `ebnf-syntax' is `ebnf'."
   :type '(radio :tag "Terminal Name"
                (const nil) regexp)
-  :group 'ebnf-syntatic)
+  :version "20"
+  :group 'ebnf-syntactic)
 
 
 (defcustom ebnf-case-fold-search nil
@@ -1625,7 +1818,8 @@ It's used only when `ebnf-syntax' is `ebnf'."
 It's only used when `ebnf-terminal-regexp' is non-nil and when `ebnf-syntax' is
 `ebnf'."
   :type 'boolean
-  :group 'ebnf-syntatic)
+  :version "20"
+  :group 'ebnf-syntactic)
 
 
 (defcustom ebnf-iso-alternative-p nil
@@ -1643,7 +1837,8 @@ This variable affects the following symbol set:
       }    ==>   :)
       ;    ==>   ."
   :type 'boolean
-  :group 'ebnf-syntatic)
+  :version "20"
+  :group 'ebnf-syntactic)
 
 
 (defcustom ebnf-iso-normalize-p nil
@@ -1654,7 +1849,17 @@ single space, so \"A  B   C\" is normalized to  \"A B C\".
 
 It's only used when `ebnf-syntax' is `iso-ebnf'."
   :type 'boolean
-  :group 'ebnf-syntatic)
+  :version "20"
+  :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
+  :version "20"
+  :group 'ebnf2ps)
 
 
 (defcustom ebnf-eps-prefix "ebnf--"
@@ -1662,6 +1867,7 @@ It's only used when `ebnf-syntax' is `iso-ebnf'."
 
 See `ebnf-eps-buffer' and `ebnf-eps-region' commands."
   :type 'string
+  :version "20"
   :group 'ebnf2ps)
 
 
@@ -1670,6 +1876,7 @@ See `ebnf-eps-buffer' and `ebnf-eps-region' commands."
 
 It must be a float between 0.0 (top) and 1.0 (bottom)."
   :type 'number
+  :version "20"
   :group 'ebnf2ps)
 
 
@@ -1677,6 +1884,7 @@ It must be a float between 0.0 (top) and 1.0 (bottom)."
   "*Specify additional border width over default terminal, non-terminal or
 special."
   :type 'number
+  :version "20"
   :group 'ebnf2ps)
 
 
@@ -1685,18 +1893,21 @@ special."
                            (fboundp 'color-instance-rgb-components)) ; XEmacs
   "*Non-nil means use color."
   :type 'boolean
+  :version "20"
   :group 'ebnf2ps)
 
 
 (defcustom ebnf-line-width 1.0
   "*Specify flow line width."
   :type 'number
+  :version "20"
   :group 'ebnf2ps)
 
 
 (defcustom ebnf-line-color "Black"
   "*Specify flow line color."
   :type 'string
+  :version "20"
   :group 'ebnf2ps)
 
 
@@ -1705,6 +1916,7 @@ special."
 
 It is intended to help PostScript programmers in debugging."
   :type 'boolean
+  :version "20"
   :group 'ebnf2ps)
 
 
@@ -1720,6 +1932,14 @@ If it occurs the error message:
 
 when executing ebnf2ps, set `ebnf-use-float-format' to nil."
   :type 'boolean
+  :version "20"
+  :group 'ebnf2ps)
+
+
+(defcustom ebnf-stop-on-error nil
+  "*Non-nil means signal error and stop. Nil means signal error and continue."
+  :type 'boolean
+  :version "20"
   :group 'ebnf2ps)
 
 
@@ -1728,7 +1948,8 @@ when executing ebnf2ps, set `ebnf-use-float-format' to nil."
 
 It's only used when `ebnf-syntax' is `yacc'."
   :type 'boolean
-  :group 'ebnf-syntatic)
+  :version "20"
+  :group 'ebnf-syntactic)
 
 
 (defcustom ebnf-ignore-empty-rule nil
@@ -1737,11 +1958,12 @@ It's only used when `ebnf-syntax' is `yacc'."
 It's interesting to set this variable if your Yacc/Bison grammar has a lot of
 middle action rule."
   :type 'boolean
+  :version "20"
   :group 'ebnf-optimization)
 
 
 (defcustom ebnf-optimize nil
-  "*Non-nil means optimize syntatic chart of rules.
+  "*Non-nil means optimize syntactic chart of rules.
 
 The following optimizations are done:
 
@@ -1756,16 +1978,32 @@ The following optimizations are done:
    6.  A = B | .                ==>   A = [B].
    7.  A =   | B .              ==>   A = [B].
 
-   factoration:
+   factorization:
    8.  A = B C | B D.           ==>   A = B (C | D).
    9.  A = C B | D B.           ==>   A = (C | D) B.
    10. A = B C E | B D E.       ==>   A = B (C | D) E.
 
 The above optimizations are specially useful when `ebnf-syntax' is `yacc'."
   :type 'boolean
+  :version "20"
   :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
 
@@ -1781,9 +2019,37 @@ The above optimizations are specially useful when `ebnf-syntax' is `yacc'."
 ;; 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 syntatic chart image of the buffer.
+  "Generate and print a PostScript syntactic chart image of the buffer.
 
 When called with a numeric prefix argument (C-u), prompts the user for
 the name of a file to save the PostScript image in, instead of sending
@@ -1799,7 +2065,7 @@ number, prompt the user for the name of the file to save in."
 
 ;;;###autoload
 (defun ebnf-print-region (from to &optional filename)
-  "Generate and print a PostScript syntatic chart image of the region.
+  "Generate and print a PostScript syntactic chart image of the region.
 Like `ebnf-print-buffer', but prints just the current region."
   (interactive (list (point) (mark) (ps-print-preprint current-prefix-arg)))
   (run-hooks 'ebnf-hook)
@@ -1807,9 +2073,37 @@ Like `ebnf-print-buffer', but prints just the current region."
       (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 syntatic chart image of the buffer.
+  "Generate and spool a PostScript syntactic chart image of the buffer.
 Like `ebnf-print-buffer' except that the PostScript image is saved in a
 local buffer to be sent to the printer later.
 
@@ -1820,7 +2114,7 @@ Use the command `ebnf-despool' to send the spooled images to the printer."
 
 ;;;###autoload
 (defun ebnf-spool-region (from to)
-  "Generate a PostScript syntatic chart image of the region and spool locally.
+  "Generate a PostScript syntactic chart image of the region and spool locally.
 Like `ebnf-spool-buffer', but spools just the current region.
 
 Use the command `ebnf-despool' to send the spooled images to the printer."
@@ -1828,9 +2122,37 @@ Use the command `ebnf-despool' to send the spooled images to the printer."
   (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 syntatic chart image of the buffer in a EPS file.
+  "Generate a PostScript syntactic chart image of the buffer in a EPS file.
 
 Indeed, for each production is generated a EPS file.
 The EPS file name has the following form:
@@ -1852,7 +2174,7 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
 
 ;;;###autoload
 (defun ebnf-eps-region (from to)
-  "Generate a PostScript syntatic chart image of the region in a EPS file.
+  "Generate a PostScript syntactic chart image of the region in a EPS file.
 
 Indeed, for each production is generated a EPS file.
 The EPS file name has the following form:
@@ -1877,16 +2199,44 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
 (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 syntatic analysis of the current buffer."
+  "Does a syntactic analysis of the current buffer."
   (interactive)
   (ebnf-syntax-region (point-min) (point-max)))
 
 
 ;;;###autoload
 (defun ebnf-syntax-region (from to)
-  "Does a syntatic analysis of a region."
+  "Does a syntactic analysis of a region."
   (interactive "r")
   (ebnf-generate-region from to nil))
 
@@ -1900,7 +2250,10 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
   "Return the current ebnf2ps setup."
   (format
    "
-\(setq ebnf-special-font                %s
+;;; ebnf2ps.el version %s
+
+\(setq ebnf-special-show-delimiter      %S
+      ebnf-special-font                %s
       ebnf-special-shape               %s
       ebnf-special-shadow              %S
       ebnf-special-border-width        %S
@@ -1927,6 +2280,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-production-name-p           %S
       ebnf-sort-production             %s
       ebnf-production-font             %s
       ebnf-arrow-shape                 %s
@@ -1942,6 +2296,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-file-suffix-regexp          %S
       ebnf-eps-prefix                  %S
       ebnf-entry-percentage            %S
       ebnf-color-p                     %S
@@ -1949,10 +2304,15 @@ 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-stop-on-error               %S
       ebnf-yac-ignore-error-recovery   %S
       ebnf-ignore-empty-rule           %S
       ebnf-optimize                    %S)
+
+;;; 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
@@ -1980,6 +2340,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-production-name-p
    (ps-print-quote ebnf-sort-production)
    (ps-print-quote ebnf-production-font)
    (ps-print-quote ebnf-arrow-shape)
@@ -1995,6 +2356,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
+   ebnf-file-suffix-regexp
    ebnf-eps-prefix
    ebnf-entry-percentage
    ebnf-color-p
@@ -2002,6 +2364,7 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
    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))
@@ -2021,7 +2384,8 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
 
 
 (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
@@ -2048,6 +2412,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-production-name-p
     ebnf-sort-production
     ebnf-production-font
     ebnf-arrow-shape
@@ -2063,6 +2428,7 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
     ebnf-syntax
     ebnf-iso-alternative-p
     ebnf-iso-normalize-p
+    ebnf-file-suffix-regexp
     ebnf-eps-prefix
     ebnf-entry-percentage
     ebnf-color-p
@@ -2070,6 +2436,7 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
     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)
@@ -2080,6 +2447,7 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
   '(;; 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)
@@ -2107,6 +2475,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-production-name-p           . t)
       (ebnf-sort-production             . nil)
       (ebnf-production-font             . '(10 Helvetica "Black" "White" bold))
       (ebnf-arrow-shape                 . 'hollow)
@@ -2122,6 +2491,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-file-suffix-regexp          . "\.[Bb][Nn][Ff]$")
       (ebnf-eps-prefix                  . "ebnf--")
       (ebnf-entry-percentage            . 0.5)
       (ebnf-color-p   . (or (fboundp 'x-color-values) ; Emacs
@@ -2130,6 +2500,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-stop-on-error               . nil)
       (ebnf-yac-ignore-error-recovery   . nil)
       (ebnf-ignore-empty-rule           . nil)
       (ebnf-optimize                    . nil))
@@ -2139,6 +2510,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                . ?\;))
+    ;; ABNF default
+    (abnf
+     default
+     (ebnf-syntax                      . 'abnf))
     ;; ISO EBNF default
     (iso-ebnf
      default
@@ -2147,24 +2522,44 @@ WARNING: It's *NOT* asked any confirmation to override an existing file."
     (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:
 
-   (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
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -2173,8 +2568,10 @@ Don't handle this variable directly.  Use functions `ebnf-insert-style' and
 
 ;;;###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)
@@ -2184,10 +2581,29 @@ Don't handle this variable directly.  Use functions `ebnf-insert-style' and
              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)
-  "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))
@@ -2207,10 +2623,12 @@ Don't handle this variable directly.  Use functions `ebnf-insert-style' and
 
 ;;;###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)
@@ -2221,18 +2639,22 @@ It returns the old style symbol."
 (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)
-  "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))
@@ -2242,9 +2664,11 @@ It returns the old style symbol."
 
 ;;;###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))
@@ -2263,7 +2687,7 @@ It returns the old style symbol."
 (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)))
@@ -2273,11 +2697,6 @@ It returns the old style symbol."
 ;; Internal variables
 
 
-(make-local-hook 'ebnf-hook)
-(make-local-hook 'ebnf-production-hook)
-(make-local-hook 'ebnf-page-hook)
-
-
 (defvar ebnf-eps-buffer-name " *EPS*")
 (defvar ebnf-parser-func     nil)
 (defvar ebnf-eps-executing   nil)
@@ -2316,14 +2735,18 @@ documentation.")
 
 
 (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'.")
@@ -2483,19 +2906,39 @@ See documentation for `ebnf-terminal-shape', `ebnf-non-terminal-shape' and
 
 /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
-[{}                                    % 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
@@ -3187,10 +3630,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
- /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
@@ -3568,7 +4012,7 @@ end
 
 /#ebnf2ps#end{showpage #ebnf2ps#save restore end}def
 
-%%EndPrologue
+%%EndProlog
 "
   "EBNF EPS begin")
 
@@ -3597,7 +4041,7 @@ end
 
 (defun ebnf-format-color (format-str color default)
   (let* ((the-color (or color default))
-        (rgb (mapcar 'ps-color-value (ps-color-values the-color))))
+        (rgb (ps-color-scale the-color)))
     (format format-str
            (concat "["
                    (ebnf-format-float (nth 0 rgb) (nth 1 rgb) (nth 2 rgb))
@@ -3613,6 +4057,10 @@ end
           (format ebnf-message-float value)))
 
 
+(defvar ebnf-total 0)
+(defvar ebnf-nprod 0)
+
+
 (defsubst ebnf-message-info (messag)
   (message "%s...%3d%%"
           messag
@@ -3728,7 +4176,8 @@ end
                    prod-name   (ebnf-node-name prod)
                    prod-width  (ebnf-max-width prod)
                    prod-height (ebnf-node-height prod)
-                   horizontal  (memq (ebnf-node-action prod) ebnf-action-list))
+                   horizontal  (memq (ebnf-node-action prod)
+                                     ebnf-action-list))
              ;; generate production in EPS buffer
              (save-excursion
                (set-buffer eps-buffer)
@@ -3812,7 +4261,7 @@ end
              ebnf-eps-max-height prod-height))
        )
       (setq ebnf-eps-prod-width prod-width)
-      (insert-buffer eps-buffer))
+      (insert-buffer-substring eps-buffer))
     (setq prod-list (cdr prod-list))))
 
 
@@ -3832,8 +4281,6 @@ end
 
 (defvar ebnf-tree      nil)
 (defvar ebnf-direction "R")
-(defvar ebnf-total     0)
-(defvar ebnf-nprod     0)
 
 
 (defun ebnf-generate-postscript (from to)
@@ -3925,11 +4372,15 @@ end
 (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)
-             (+ 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))
@@ -4118,6 +4569,47 @@ end
 ;; 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
+;; from \177 to \237).  It seems that version 20.7 has the same problem.
+(defun ebnf-range-regexp (prefix from to)
+  (let (str)
+    (while (<= from to)
+      (setq str  (concat str (char-to-string from))
+           from (1+ from)))
+    (concat prefix str)))
+
+
 (defvar ebnf-map-name
   (let ((map (make-vector 256 ?\_)))
     (mapcar #'(lambda (char)
@@ -4131,7 +4623,7 @@ end
 (defun ebnf-eps-filename (str)
   (let* ((len  (length str))
         (stri 0)
-        (new  (make-string len ?\ )))
+        (new  (make-string len ?\s)))
     (while (< stri len)
       (aset new stri (aref ebnf-map-name (aref str stri)))
       (setq stri (1+ stri)))
@@ -4147,6 +4639,7 @@ end
 (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
@@ -4154,22 +4647,40 @@ end
          (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)
-            (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
-     (the-point
-      (goto-char the-point))
+     ;; error occurred
+     (error-msg
+      (goto-char the-point)
+      (if ebnf-stop-on-error
+         (error error-msg)
+       (message "%s" error-msg)))
+     ;; generated output OK
      (gen-func
       nil)
+     ;; syntax checked OK
      (t
-      (message "EBNF syntatic analysis: NO ERRORS.")))))
+      (message "EBNF syntactic analysis: NO ERRORS.")))))
 
 
 (defun ebnf-parse-and-sort (start)
@@ -4271,8 +4782,19 @@ end
   (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)
+  (ps-printing-region nil nil nil)
   (if ebnf-use-float-format
       (setq ebnf-format-float  "%1.3f"
            ebnf-message-float "%3.2f")
@@ -4280,15 +4802,10 @@ end
          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))
@@ -4364,59 +4881,59 @@ end
           (insert " & ebnf2ps v" ebnf-version)
           ;; insert ebnf settings & engine
           (goto-char (point-max))
-          (search-backward "\n%%EndPrologue\n")
+          (search-backward "\n%%EndProlog\n")
           (ebnf-insert-ebnf-prologue)
           (ps-output "\n")))))
 
 
 (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: " (time-stamp-hh:mm:ss) " " (time-stamp-mon-dd-yyyy)
-     "\n%%Creator: " (user-full-name) " (using ebnf2ps v" ebnf-version ")"
-     "\n%%DocumentNeededResources: font "
-     (or ebnf-fonts-required
-        (setq ebnf-fonts-required
-              (let ((fonts (ps-remove-duplicates
+  (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)))))
-                (concat (car fonts)
-                        (and (cdr fonts) "\n%%+ font ")
-                        (mapconcat 'identity (cdr fonts) "\n%%+ font ")))))
-     "\n%%Pages: 0\n%%EndComments\n\n%%BeginPrologue\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)))
+                                          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 ()
@@ -4563,57 +5080,14 @@ end
                      (ebnf-shape-value ebnf-chart-shape
                                        ebnf-terminal-shape-alist))
              (format "/UserArrow{%s}def\n"
-                     (ebnf-user-arrow ebnf-user-arrow))
+                     (let ((arrow (eval ebnf-user-arrow)))
+                       (if (stringp arrow)
+                           arrow
+                         "")))
              "\n% === end   EBNF settings\n\n"
              (and ebnf-debug-ps ebnf-debug))))
    ebnf-prologue))
 
-
-(defun ebnf-user-arrow (user-arrow)
-  "Return a user arrow shape from USER-ARROW (a PostScript code).
-
-This function is only called when `ebnf-arrow-shape' is set to symbol `user'.
-
-If is a string, should be a PostScript procedure body.
-If is a variable symbol, should contain a string.
-If is a function symbol, it is called and the result is applied recursively.
-If is a cons and car is a function symbol, it is called as:
-   (funcall (car cons) (cdr cons))
-and the result is applied recursively.
-If is a cons and car is not a function symbol, it is applied recursively on
-car and cdr, and the results are concatened as:
-   (concat RESULT-FROM-CAR \" \" RESULT-FROM-CDR)
-If is a list and car is a function symbol, it is called as:
-   (apply (car list) (cdr list))
-and the result is applied recursively.
-If is a list and car is not a function symbol, it is applied recursively on
-each element and the resulting list is concatened as:
-   (mapconcat 'identity RESULTING-LIST \" \")
-Otherwise, it is treated as an empty string."
-  (cond
-   ((null user-arrow)
-    "")
-   ((stringp user-arrow)
-    user-arrow)
-   ((and (symbolp user-arrow) (fboundp user-arrow))
-    (ebnf-user-arrow (funcall user-arrow)))
-   ((and (symbolp user-arrow) (boundp user-arrow))
-    (ebnf-user-arrow (symbol-value user-arrow)))
-   ((consp user-arrow)
-    (if (and (symbolp (car user-arrow)) (fboundp (car user-arrow)))
-       (ebnf-user-arrow (funcall (car user-arrow) (cdr user-arrow)))
-      (concat (ebnf-user-arrow (car user-arrow))
-             " "
-             (ebnf-user-arrow (cdr user-arrow)))))
-   ((listp user-arrow)
-    (if (and (symbolp (car user-arrow))
-            (fboundp (car user-arrow)))
-       (ebnf-user-arrow (apply (car user-arrow) (cdr user-arrow)))
-      (mapconcat 'ebnf-user-arrow user-arrow " ")))
-   (t
-    "")
-   ))
-
 \f
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Adjusting dimensions
@@ -4636,12 +5110,16 @@ Otherwise, it is treated as an empty string."
   (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-line-width
                                    ebnf-horizontal-space))))
 
 
@@ -4898,7 +5376,7 @@ Otherwise, it is treated as an empty string."
 
 ;; [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
@@ -4913,7 +5391,9 @@ Otherwise, it is treated as an empty string."
 ;; [sequence width-fun dim-fun entry height width list]
 (defun ebnf-sequence-width (sequence width)
   (ebnf-node-list sequence
-                 (ebnf-justify-list sequence (ebnf-node-list sequence) width)))
+                 (ebnf-justify-list sequence
+                                    (ebnf-node-list sequence)
+                                    width)))
 
 
 (defun ebnf-justify-list (node seq width)
@@ -4927,7 +5407,10 @@ Otherwise, it is treated as an empty string."
        ;; 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))
@@ -5004,14 +5487,19 @@ Otherwise, it is treated as an empty string."
      (point))))
 
 
+;; replace the range "\240-\377" (see `ebnf-range-regexp').
+(defconst ebnf-8-bit-chars (ebnf-range-regexp "" ?\240 ?\377))
+
+
 (defun ebnf-string (chars eos-char kind)
   (forward-char)
   (buffer-substring-no-properties
    (point)
    (progn
-     (skip-chars-forward (concat chars "\240-\377") ebnf-limit)
+     ;;(skip-chars-forward (concat chars "\240-\377") ebnf-limit)
+     (skip-chars-forward (concat chars ebnf-8-bit-chars) ebnf-limit)
      (if (or (eobp) (/= (following-char) eos-char))
-        (error "Illegal %s: missing `%c'." kind eos-char)
+        (error "Invalid %s: missing `%c'" kind eos-char)
        (forward-char)
        (1- (point))))))
 
@@ -5029,13 +5517,13 @@ Otherwise, it is treated as an empty string."
       (goto-char (+ (point) n 1))))
   (if (= (preceding-char) ?\")
       (1- (point))
-    (error "Missing `\"'.")))
+    (error "Missing `\"'")))
 
 
 (defun ebnf-trim-right (str)
   (let* ((len   (1- (length str)))
         (index len))
-    (while (and (> index 0) (= (aref str index) ?\ ))
+    (while (and (> index 0) (= (aref str index) ?\s))
       (setq index (1- index)))
     (if (= index len)
        str
@@ -5081,10 +5569,11 @@ Otherwise, it is treated as an empty string."
          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))
 
 
@@ -5104,7 +5593,7 @@ Otherwise, it is treated as an empty string."
 
 (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
@@ -5160,14 +5649,25 @@ Otherwise, it is treated as an empty string."
          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
-         (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))
 
 
@@ -5216,7 +5716,8 @@ Otherwise, it is treated as an empty string."
                ;; ( A | B | EMPTY )-  ==> A | B
                ((and (null exception)
                      (eq kind 'ebnf-generate-alternative)
-                     (eq (ebnf-node-kind (car (last (ebnf-node-list element))))
+                     (eq (ebnf-node-kind
+                          (car (last (ebnf-node-list element))))
                          'ebnf-generate-empty))
                 (let ((elt (ebnf-node-list element))
                       bef)
@@ -5238,13 +5739,13 @@ Otherwise, it is treated as an empty string."
                )))))
 
 
-(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)
-         (ebnf-make-repeat times (cdr repeat)))))
+         (ebnf-make-repeat times (cdr repeat) upper))))
 
 
 (defun ebnf-token-optional (body)
@@ -5285,6 +5786,20 @@ Otherwise, it is treated as an empty string."
                                                   (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
@@ -5295,6 +5810,7 @@ Otherwise, it is treated as an empty string."
     ;; 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.")
 
@@ -5303,6 +5819,12 @@ Otherwise, it is treated as an empty string."
 ;; 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.")
 
@@ -5321,14 +5843,17 @@ Otherwise, it is treated as an empty string."
 (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"
-  "Syntatic 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
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -5336,5 +5861,5 @@ Otherwise, it is treated as an empty string."
 
 (provide 'ebnf2ps)
 
-
+;;; arch-tag: 148bc8af-5398-468b-b922-eeb7afef3e4f
 ;;; ebnf2ps.el ends here