X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/8d9ea7b12a87167bbe07b1ca0efc76f19f242f3a..1a9203d09eb108a7c9d3b79c20783c36e938a634:/lisp/progmodes/ebnf2ps.el diff --git a/lisp/progmodes/ebnf2ps.el b/lisp/progmodes/ebnf2ps.el index b1e5344883..1d2f8d630e 100644 --- a/lisp/progmodes/ebnf2ps.el +++ b/lisp/progmodes/ebnf2ps.el @@ -1,12 +1,14 @@ -;;; ebnf2ps --- Translate an EBNF to a syntatic chart on PostScript +;;; ebnf2ps.el --- translate an EBNF to a syntactic chart on PostScript -;; Copyright (C) 1999, 2000 Free Software Foundation, Inc. +;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 +;; Free Software Foundation, Inc. -;; Author: Vinicius Jose Latorre -;; Maintainer: Vinicius Jose Latorre -;; Keywords: wp, ebnf, PostScript -;; Time-stamp: <99/12/11 21:41:24 vinicius> -;; Version: 3.1 +;; Author: Vinicius Jose Latorre +;; Maintainer: Vinicius Jose Latorre +;; Time-stamp: <2004/11/19 22:30:34 vinicius> +;; Keywords: wp, ebnf, PostScript +;; Version: 4.2 +;; X-URL: http://www.cpqd.com.br/~vinicius/emacs/ ;; This file is part of GNU Emacs. @@ -25,14 +27,14 @@ ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. -(defconst ebnf-version "3.1" - "ebnf2ps.el, v 3.1 <99/12/11 vinicius> +(defconst ebnf-version "4.2" + "ebnf2ps.el, v 4.2 <2004/04/04 vinicius> Vinicius's last change version. When reporting bugs, please also report the version of Emacs, if any, that ebnf2ps was running with. Please send all bug fixes and enhancements to - Vinicius Jose Latorre . + Vinicius Jose Latorre . ") @@ -43,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. @@ -67,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 @@ -105,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 "directory", "file", "buffer" or "region" in the command name +;; determines how much of the buffer is printed: +;; +;; directory - Read files in the directory and print them. ;; -;; The word "buffer" or "region" in the command name determines how much of the -;; buffer is printed: +;; file - Read file and print it. ;; -;; buffer - Print the entire buffer. +;; buffer - Print the entire buffer. ;; -;; region - Print just the current region. +;; 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 @@ -163,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) @@ -179,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 @@ -203,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 @@ -220,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. ;; @@ -257,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 `.'). @@ -271,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"). @@ -283,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'. @@ -321,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. @@ -332,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 @@ -354,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. ;; @@ -362,9 +436,9 @@ Please send all bug fixes and enhancements to ;; ;; ;[EPS open a new EPS file. The EPS file name has the form: ;; .eps -;; where is given by variable `ebnf-eps-prefix' and -;; is the string given by ;[ action comment, this string is mapped -;; to form a valid file name (see documentation for +;; where is given by variable `ebnf-eps-prefix' and +;; 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. @@ -406,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. ;; ;< @@ -417,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; @@ -479,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 @@ -521,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. @@ -542,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. @@ -550,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. @@ -559,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. @@ -604,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. ;; @@ -625,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: ;; @@ -691,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'. @@ -723,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 @@ -927,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] @@ -982,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... ;; @@ -990,34 +1088,44 @@ Please send all bug fixes and enhancements to ;; Acknowledgements ;; ---------------- ;; +;; Thanks to Drew Adams 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 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")) - +(and (string< ps-print-version "5.2.3") + (error "`ebnf2ps' requires `ps-print' package version 5.2.3 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)) - -(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))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1029,12 +1137,14 @@ Please send all bug fixes and enhancements to (defgroup postscript nil "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) @@ -1043,6 +1153,7 @@ Please send all bug fixes and enhancements to "Special customization" :prefix "ebnf-" :tag "Special" + :version "20" :group 'ebnf2ps) @@ -1050,6 +1161,7 @@ Please send all bug fixes and enhancements to "Except customization" :prefix "ebnf-" :tag "Except" + :version "20" :group 'ebnf2ps) @@ -1057,6 +1169,7 @@ Please send all bug fixes and enhancements to "Repeat customization" :prefix "ebnf-" :tag "Repeat" + :version "20" :group 'ebnf2ps) @@ -1064,6 +1177,7 @@ Please send all bug fixes and enhancements to "Terminal customization" :prefix "ebnf-" :tag "Terminal" + :version "20" :group 'ebnf2ps) @@ -1071,6 +1185,7 @@ Please send all bug fixes and enhancements to "Non-Terminal customization" :prefix "ebnf-" :tag "Non-Terminal" + :version "20" :group 'ebnf2ps) @@ -1078,6 +1193,7 @@ Please send all bug fixes and enhancements to "Production customization" :prefix "ebnf-" :tag "Production" + :version "20" :group 'ebnf2ps) @@ -1085,6 +1201,7 @@ Please send all bug fixes and enhancements to "Shapes customization" :prefix "ebnf-" :tag "Shape" + :version "20" :group 'ebnf2ps) @@ -1092,13 +1209,15 @@ Please send all bug fixes and enhancements to "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) @@ -1106,12 +1225,14 @@ Please send all bug fixes and enhancements to "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) @@ -1120,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) @@ -1128,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) @@ -1136,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) @@ -1149,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. @@ -1170,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) @@ -1179,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) @@ -1218,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) @@ -1227,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) @@ -1266,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) @@ -1275,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) @@ -1314,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) @@ -1323,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. @@ -1356,6 +1515,7 @@ Valid values are: (const :tag "Ascending" ascending) (const :tag "Descending" descending) (other :tag "No Sort" nil)) + :version "20" :group 'ebnf-production) @@ -1398,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) @@ -1419,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) @@ -1442,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) @@ -1494,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) @@ -1511,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: @@ -1539,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) @@ -1573,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\"). @@ -1585,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 ?\; @@ -1596,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 ?. @@ -1604,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 @@ -1617,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 @@ -1626,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 @@ -1644,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 @@ -1655,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--" @@ -1663,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) @@ -1671,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) @@ -1678,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) @@ -1686,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) @@ -1706,6 +1916,7 @@ special." It is intended to help PostScript programmers in debugging." :type 'boolean + :version "20" :group 'ebnf2ps) @@ -1721,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) @@ -1729,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 @@ -1738,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: @@ -1757,15 +1978,31 @@ 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) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; 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.") + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Customization @@ -1782,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 @@ -1800,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) @@ -1808,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. @@ -1821,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." @@ -1829,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: @@ -1853,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: @@ -1878,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)) @@ -1901,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 @@ -1928,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 @@ -1943,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 @@ -1950,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 @@ -1981,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) @@ -1996,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 @@ -2003,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)) @@ -2022,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 @@ -2049,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 @@ -2064,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 @@ -2071,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) @@ -2081,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) @@ -2108,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) @@ -2123,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 @@ -2131,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)) @@ -2140,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 @@ -2148,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)...) -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. +Where: -Don't handle this variable directly. Use functions `ebnf-insert-style' and -`ebnf-merge-style'.") +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. + + 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. + +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'.") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -2174,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) @@ -2185,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)) @@ -2208,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) @@ -2222,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)) @@ -2243,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)) @@ -2264,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))) @@ -2274,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) @@ -2317,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'.") @@ -2484,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 @@ -3188,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 @@ -3569,7 +4012,7 @@ end /#ebnf2ps#end{showpage #ebnf2ps#save restore end}def -%%EndPrologue +%%EndProlog " "EBNF EPS begin") @@ -3598,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)) @@ -3614,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 @@ -3729,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) @@ -3833,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) @@ -3926,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)) @@ -4119,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) @@ -4148,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 @@ -4155,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 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) @@ -4272,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") @@ -4281,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)) @@ -4365,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 () @@ -4564,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 - "") - )) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Adjusting dimensions @@ -4637,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)))) @@ -4899,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 @@ -4914,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) @@ -4928,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)) @@ -5005,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 "Illegal %s: missing `%c'" kind eos-char) (forward-char) (1- (point)))))) @@ -5030,7 +5517,7 @@ 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) @@ -5082,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)) @@ -5105,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 @@ -5161,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)) @@ -5217,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) @@ -5239,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) @@ -5286,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))) + )) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Variables used by parsers @@ -5296,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.") @@ -5304,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.") @@ -5322,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.") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -5337,5 +5861,5 @@ Otherwise, it is treated as an empty string." (provide 'ebnf2ps) - +;;; arch-tag: 148bc8af-5398-468b-b922-eeb7afef3e4f ;;; ebnf2ps.el ends here