27451
|
1 ;;; ebnf2ps --- Translate an EBNF to a syntatic chart on PostScript
|
|
2
|
27539
|
3 ;; Copyright (C) 1999, 2000 Free Software Foundation, Inc.
|
27451
|
4
|
|
5 ;; Author: Vinicius Jose Latorre <vinicius@cpqd.com.br>
|
|
6 ;; Maintainer: Vinicius Jose Latorre <vinicius@cpqd.com.br>
|
|
7 ;; Keywords: wp, ebnf, PostScript
|
|
8 ;; Time-stamp: <99/12/11 21:41:24 vinicius>
|
|
9 ;; Version: 3.1
|
|
10
|
27539
|
11 ;; This file is part of GNU Emacs.
|
|
12
|
|
13 ;; GNU Emacs is free software; you can redistribute it and/or modify
|
|
14 ;; it under the terms of the GNU General Public License as published by
|
|
15 ;; the Free Software Foundation; either version 2, or (at your option)
|
|
16 ;; any later version.
|
|
17
|
|
18 ;; GNU Emacs is distributed in the hope that it will be useful,
|
|
19 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
21 ;; GNU General Public License for more details.
|
|
22
|
|
23 ;; You should have received a copy of the GNU General Public License
|
|
24 ;; along with GNU Emacs; see the file COPYING. If not, write to the
|
|
25 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
26 ;; Boston, MA 02111-1307, USA.
|
|
27
|
27451
|
28 (defconst ebnf-version "3.1"
|
|
29 "ebnf2ps.el, v 3.1 <99/12/11 vinicius>
|
|
30
|
|
31 Vinicius's last change version. When reporting bugs, please also
|
|
32 report the version of Emacs, if any, that ebnf2ps was running with.
|
|
33
|
|
34 Please send all bug fixes and enhancements to
|
|
35 Vinicius Jose Latorre <vinicius@cpqd.com.br>.
|
|
36 ")
|
|
37
|
|
38
|
|
39 ;;; Commentary:
|
|
40
|
|
41 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
42 ;;
|
|
43 ;; Introduction
|
|
44 ;; ------------
|
|
45 ;;
|
|
46 ;; This package translates an EBNF to a syntatic chart on PostScript.
|
|
47 ;;
|
|
48 ;; To use ebnf2ps, insert in your ~/.emacs:
|
|
49 ;;
|
|
50 ;; (require 'ebnf2ps)
|
|
51 ;;
|
|
52 ;; ebnf2ps uses ps-print package (version 3.05.1 or later), so see ps-print to
|
|
53 ;; know how to set options like landscape printing, page headings, margins, etc.
|
|
54 ;;
|
|
55 ;; NOTE: ps-print zebra stripes and line number options doesn't have effect on
|
|
56 ;; ebnf2ps, they behave as it's turned off.
|
|
57 ;;
|
|
58 ;; For good performance, be sure to byte-compile ebnf2ps.el, e.g.
|
|
59 ;;
|
|
60 ;; M-x byte-compile-file <give the path to ebnf2ps.el when prompted>
|
|
61 ;;
|
|
62 ;; This will generate ebnf2ps.elc, which will be loaded instead of ebnf2ps.el.
|
|
63 ;;
|
|
64 ;; ebnf2ps was tested with GNU Emacs 20.4.1.
|
|
65 ;;
|
|
66 ;;
|
|
67 ;; Using ebnf2ps
|
|
68 ;; -------------
|
|
69 ;;
|
|
70 ;; ebnf2ps provides six commands for generating PostScript syntatic chart images
|
|
71 ;; of Emacs buffers:
|
|
72 ;;
|
|
73 ;; ebnf-print-buffer
|
|
74 ;; ebnf-print-region
|
|
75 ;; ebnf-spool-buffer
|
|
76 ;; ebnf-spool-region
|
|
77 ;; ebnf-eps-buffer
|
|
78 ;; ebnf-eps-region
|
|
79 ;;
|
|
80 ;; These commands all perform essentially the same function: they generate
|
|
81 ;; PostScript syntatic chart images suitable for printing on a PostScript
|
|
82 ;; printer or displaying with GhostScript. These commands are collectively
|
|
83 ;; referred to as "ebnf- commands".
|
|
84 ;;
|
|
85 ;; The word "print", "spool" and "eps" in the command name determines when the
|
|
86 ;; PostScript image is sent to the printer (or file):
|
|
87 ;;
|
|
88 ;; print - The PostScript image is immediately sent to the printer;
|
|
89 ;;
|
|
90 ;; spool - The PostScript image is saved temporarily in an Emacs buffer.
|
|
91 ;; Many images may be spooled locally before printing them. To
|
|
92 ;; send the spooled images to the printer, use the command
|
|
93 ;; `ebnf-despool'.
|
|
94 ;;
|
|
95 ;; eps - The PostScript image is immediately sent to a EPS file.
|
|
96 ;;
|
|
97 ;; The spooling mechanism is the same as used by ps-print and was designed for
|
|
98 ;; printing lots of small files to save paper that would otherwise be wasted on
|
|
99 ;; banner pages, and to make it easier to find your output at the printer (it's
|
|
100 ;; easier to pick up one 50-page printout than to find 50 single-page
|
|
101 ;; printouts). As ebnf2ps and ps-print use the same Emacs buffer to spool
|
|
102 ;; images, you can intermix the spooling of ebnf2ps and ps-print images.
|
|
103 ;;
|
|
104 ;; ebnf2ps use the same hook of ps-print in the `kill-emacs-hook' so that you
|
|
105 ;; won't accidentally quit from Emacs while you have unprinted PostScript
|
|
106 ;; waiting in the spool buffer. If you do attempt to exit with spooled
|
|
107 ;; PostScript, you'll be asked if you want to print it, and if you decline,
|
|
108 ;; you'll be asked to confirm the exit; this is modeled on the confirmation that
|
|
109 ;; Emacs uses for modified buffers.
|
|
110 ;;
|
|
111 ;; The word "buffer" or "region" in the command name determines how much of the
|
|
112 ;; buffer is printed:
|
|
113 ;;
|
|
114 ;; buffer - Print the entire buffer.
|
|
115 ;;
|
|
116 ;; region - Print just the current region.
|
|
117 ;;
|
|
118 ;; Two ebnf- command examples:
|
|
119 ;;
|
|
120 ;; ebnf-print-buffer - translate and print the entire buffer, and send
|
|
121 ;; it immediately to the printer.
|
|
122 ;;
|
|
123 ;; ebnf-spool-region - translate and print just the current region, and
|
|
124 ;; spool the image in Emacs to send to the printer
|
|
125 ;; later.
|
|
126 ;;
|
|
127 ;; Note that `ebnf-eps-buffer' and `ebnf-eps-region' never spool the EPS image,
|
|
128 ;; so they don't use the ps-print spooling mechanism. See section "Actions in
|
|
129 ;; Comments" for an explanation about EPS file generation.
|
|
130 ;;
|
|
131 ;;
|
|
132 ;; Invoking Ebnf2ps
|
|
133 ;; ----------------
|
|
134 ;;
|
|
135 ;; To translate and print your buffer, type
|
|
136 ;;
|
|
137 ;; M-x ebnf-print-buffer
|
|
138 ;;
|
|
139 ;; or substitute one of the other four ebnf- commands. The command will
|
|
140 ;; generate the PostScript image and print or spool it as specified. By giving
|
|
141 ;; the command a prefix argument
|
|
142 ;;
|
|
143 ;; C-u M-x ebnf-print-buffer
|
|
144 ;;
|
|
145 ;; it will save the PostScript image to a file instead of sending it to the
|
|
146 ;; printer; you will be prompted for the name of the file to save the image to.
|
|
147 ;; The prefix argument is ignored by the commands that spool their images, but
|
|
148 ;; you may save the spooled images to a file by giving a prefix argument to
|
|
149 ;; `ebnf-despool':
|
|
150 ;;
|
|
151 ;; C-u M-x ebnf-despool
|
|
152 ;;
|
|
153 ;; When invoked this way, `ebnf-despool' will prompt you for the name of the
|
|
154 ;; file to save to.
|
|
155 ;;
|
|
156 ;; The prefix argument is also ignored by `ebnf-eps-buffer' and
|
|
157 ;; `ebnf-eps-region'.
|
|
158 ;;
|
|
159 ;; Any of the `ebnf-' commands can be bound to keys. Here are some examples:
|
|
160 ;;
|
|
161 ;; (global-set-key 'f22 'ebnf-print-buffer) ;f22 is prsc
|
|
162 ;; (global-set-key '(shift f22) 'ebnf-print-region)
|
|
163 ;; (global-set-key '(control f22) 'ebnf-despool)
|
|
164 ;;
|
|
165 ;;
|
|
166 ;; EBNF Syntax
|
|
167 ;; -----------
|
|
168 ;;
|
|
169 ;; The current EBNF that ebnf2ps accepts has the following constructions:
|
|
170 ;;
|
|
171 ;; ; comment (until end of line)
|
|
172 ;; A non-terminal
|
|
173 ;; "C" terminal
|
|
174 ;; ?C? special
|
|
175 ;; $A default non-terminal (see text below)
|
|
176 ;; $"C" default terminal (see text below)
|
|
177 ;; $?C? default special (see text below)
|
|
178 ;; A = B. production (A is the header and B the body)
|
|
179 ;; C D sequence (C occurs before D)
|
|
180 ;; C | D alternative (C or D occurs)
|
|
181 ;; A - B exception (A excluding B, B without any non-terminal)
|
|
182 ;; n * A repetition (A repeats n (integer) times)
|
|
183 ;; (C) group (expression C is grouped together)
|
|
184 ;; [C] optional (C may or not occurs)
|
|
185 ;; C+ one or more occurrences of C
|
|
186 ;; {C}+ one or more occurrences of C
|
|
187 ;; {C}* zero or more occurrences of C
|
|
188 ;; {C} zero or more occurrences of C
|
|
189 ;; C / D equivalent to: C {D C}*
|
|
190 ;; {C || D}+ equivalent to: C {D C}*
|
|
191 ;; {C || D}* equivalent to: [C {D C}*]
|
|
192 ;; {C || D} equivalent to: [C {D C}*]
|
|
193 ;;
|
|
194 ;; The EBNF syntax written using the notation above is:
|
|
195 ;;
|
|
196 ;; EBNF = {production}+.
|
|
197 ;;
|
|
198 ;; production = non_terminal "=" body ".". ;; production
|
|
199 ;;
|
|
200 ;; body = {sequence || "|"}*. ;; alternative
|
|
201 ;;
|
|
202 ;; sequence = {exception}*. ;; sequence
|
|
203 ;;
|
|
204 ;; exception = repeat [ "-" repeat]. ;; exception
|
|
205 ;;
|
|
206 ;; repeat = [ integer "*" ] term. ;; repetition
|
|
207 ;;
|
|
208 ;; term = factor
|
|
209 ;; | [factor] "+" ;; one-or-more
|
|
210 ;; | [factor] "/" [factor] ;; one-or-more
|
|
211 ;; .
|
|
212 ;;
|
|
213 ;; factor = [ "$" ] "\"" terminal "\"" ;; terminal
|
|
214 ;; | [ "$" ] non_terminal ;; non-terminal
|
|
215 ;; | [ "$" ] "?" special "?" ;; special
|
|
216 ;; | "(" body ")" ;; group
|
|
217 ;; | "[" body "]" ;; zero-or-one
|
|
218 ;; | "{" body [ "||" body ] "}+" ;; one-or-more
|
|
219 ;; | "{" body [ "||" body ] "}*" ;; zero-or-more
|
|
220 ;; | "{" body [ "||" body ] "}" ;; zero-or-more
|
|
221 ;; .
|
|
222 ;;
|
|
223 ;; non_terminal = "[A-Za-z\\240-\\377][!#%&'*-,0-:<>@-Z\\^-z~\\240-\\377]*".
|
|
224 ;;
|
|
225 ;; terminal = "\\([^\"\\]\\|\\\\[ -~\\240-\\377]\\)+".
|
|
226 ;;
|
|
227 ;; special = "[^?\\n\\000-\\010\\016-\\037\\177-\\237]*".
|
|
228 ;;
|
|
229 ;; integer = "[0-9]+".
|
|
230 ;;
|
|
231 ;; comment = ";" "[^\\n\\000-\\010\\016-\\037\\177-\\237]*" "\\n".
|
|
232 ;;
|
|
233 ;; Try to use the above EBNF to test ebnf2ps.
|
|
234 ;;
|
|
235 ;; The `default' terminal, non-terminal and special is a way to indicate a
|
|
236 ;; default path in a production. For example, the production:
|
|
237 ;;
|
|
238 ;; X = [ $A ( B | $C ) | D ].
|
|
239 ;;
|
|
240 ;; Indicates that the default meaning for "X" is "A C" if "X" is empty.
|
|
241 ;;
|
|
242 ;; The terminal name is controlled by `ebnf-terminal-regexp' and
|
|
243 ;; `ebnf-case-fold-search', so it's possible to match other kind of terminal
|
|
244 ;; name besides that enclosed by `"'.
|
|
245 ;;
|
|
246 ;; Let's see an example:
|
|
247 ;;
|
|
248 ;; (setq ebnf-terminal-regexp "[A-Z][_A-Z]*") ; upper case name
|
|
249 ;; (setq ebnf-case-fold-search nil) ; exact matching
|
|
250 ;;
|
|
251 ;; If you have the production:
|
|
252 ;;
|
|
253 ;; Logical = "(" Expression ( OR | AND | "XOR" ) Expression ")".
|
|
254 ;;
|
|
255 ;; The names are classified as:
|
|
256 ;;
|
|
257 ;; Logical Expression non-terminal
|
|
258 ;; "(" OR AND "XOR" ")" terminal
|
|
259 ;;
|
|
260 ;; The line comment is controlled by `ebnf-lex-comment-char'. The default value
|
|
261 ;; is ?\; (character `;').
|
|
262 ;;
|
|
263 ;; The end of production is controlled by `ebnf-lex-eop-char'. The default
|
|
264 ;; value is ?. (character `.').
|
|
265 ;;
|
|
266 ;; The variable `ebnf-syntax' specifies which syntax to recognize:
|
|
267 ;;
|
|
268 ;; `ebnf' ebnf2ps recognizes the syntax described above.
|
|
269 ;; The following variables *ONLY* have effect with this
|
|
270 ;; setting:
|
|
271 ;; `ebnf-terminal-regexp', `ebnf-case-fold-search',
|
|
272 ;; `ebnf-lex-comment-char' and `ebnf-lex-eop-char'.
|
|
273 ;;
|
|
274 ;; `iso-ebnf' ebnf2ps recognizes the syntax described in the URL:
|
|
275 ;; `http://www.cl.cam.ac.uk/~mgk25/iso-ebnf.html'
|
|
276 ;; ("International Standard of the ISO EBNF Notation").
|
|
277 ;; The following variables *ONLY* have effect with this
|
|
278 ;; setting:
|
|
279 ;; `ebnf-iso-alternative-p' and `ebnf-iso-normalize-p'.
|
|
280 ;;
|
|
281 ;; `yacc' ebnf2ps recognizes the Yacc/Bison syntax.
|
|
282 ;; The following variable *ONLY* has effect with this
|
|
283 ;; setting:
|
|
284 ;; `ebnf-yac-ignore-error-recovery'.
|
|
285 ;;
|
|
286 ;; Any other value is treated as `ebnf'.
|
|
287 ;;
|
|
288 ;; The default value is `ebnf'.
|
|
289 ;;
|
|
290 ;;
|
|
291 ;; Optimizations
|
|
292 ;; -------------
|
|
293 ;;
|
|
294 ;; The following EBNF optimizations are done:
|
|
295 ;;
|
|
296 ;; [ { A }* ] ==> { A }*
|
|
297 ;; [ { A }+ ] ==> { A }*
|
|
298 ;; [ A ] + ==> { A }*
|
|
299 ;; { A }* + ==> { A }*
|
|
300 ;; { A }+ + ==> { A }+
|
|
301 ;; { A }- ==> { A }+
|
|
302 ;; [ A ]- ==> A
|
|
303 ;; ( A | EMPTY )- ==> A
|
|
304 ;; ( A | B | EMPTY )- ==> A | B
|
|
305 ;; [ A | B ] ==> A | B | EMPTY
|
|
306 ;; n * EMPTY ==> EMPTY
|
|
307 ;; EMPTY + ==> EMPTY
|
|
308 ;; EMPTY / EMPTY ==> EMPTY
|
|
309 ;; EMPTY - A ==> EMPTY
|
|
310 ;;
|
|
311 ;; The following optimizations are done when `ebnf-optimize' is non-nil:
|
|
312 ;;
|
|
313 ;; left recursion:
|
|
314 ;; 1. A = B | A C. ==> A = B {C}*.
|
|
315 ;; 2. A = B | A B. ==> A = {B}+.
|
|
316 ;; 3. A = | A B. ==> A = {B}*.
|
|
317 ;; 4. A = B | A C B. ==> A = {B || C}+.
|
|
318 ;; 5. A = B | D | A C | A E. ==> A = ( B | D ) { C | E }*.
|
|
319 ;;
|
|
320 ;; optional:
|
|
321 ;; 6. A = B | . ==> A = [B].
|
|
322 ;; 7. A = | B . ==> A = [B].
|
|
323 ;;
|
|
324 ;; factoration:
|
|
325 ;; 8. A = B C | B D. ==> A = B (C | D).
|
|
326 ;; 9. A = C B | D B. ==> A = (C | D) B.
|
|
327 ;; 10. A = B C E | B D E. ==> A = B (C | D) E.
|
|
328 ;;
|
|
329 ;; The above optimizations are specially useful when `ebnf-syntax' is `yacc'.
|
|
330 ;;
|
|
331 ;;
|
|
332 ;; Form Feed
|
|
333 ;; ---------
|
|
334 ;;
|
|
335 ;; You may use form feed (^L \014) to force a production to start on a new page,
|
|
336 ;; for example:
|
|
337 ;;
|
|
338 ;; a) A = B | C.
|
|
339 ;; ^L
|
|
340 ;; X = Y | Z.
|
|
341 ;;
|
|
342 ;; b) A = B ^L | C.
|
|
343 ;; X = Y | Z.
|
|
344 ;;
|
|
345 ;; c) A = B ^L^L^L | C.^L
|
|
346 ;; ^L
|
|
347 ;; X = Y | Z.
|
|
348 ;;
|
|
349 ;; In all examples above, only the production X will start on a new page.
|
|
350 ;;
|
|
351 ;;
|
|
352 ;; Actions in Comments
|
|
353 ;; -------------------
|
|
354 ;;
|
|
355 ;; ebnf2ps accepts the following actions in comments:
|
|
356 ;;
|
|
357 ;; ;> the next production starts in the same line as the current one.
|
|
358 ;; It is useful when `ebnf-horizontal-orientation' is nil.
|
|
359 ;;
|
|
360 ;; ;< the next production starts in the next line.
|
|
361 ;; It is useful when `ebnf-horizontal-orientation' is non-nil.
|
|
362 ;;
|
|
363 ;; ;[EPS open a new EPS file. The EPS file name has the form:
|
|
364 ;; <PREFIX><NAME>.eps
|
|
365 ;; where <PREFIX> is given by variable `ebnf-eps-prefix' and <NAME>
|
|
366 ;; is the string given by ;[ action comment, this string is mapped
|
|
367 ;; to form a valid file name (see documentation for
|
|
368 ;; `ebnf-eps-buffer' or `ebnf-eps-region').
|
|
369 ;; It has effect only during `ebnf-eps-buffer' or
|
|
370 ;; `ebnf-eps-region' execution.
|
|
371 ;; It's an error to try to open an already opened EPS file.
|
|
372 ;;
|
|
373 ;; ;]EPS close an opened EPS file.
|
|
374 ;; It has effect only during `ebnf-eps-buffer' or
|
|
375 ;; `ebnf-eps-region' execution.
|
|
376 ;; It's an error to try to close a not opened EPS file.
|
|
377 ;;
|
|
378 ;; So if you have:
|
|
379 ;;
|
|
380 ;; (setq ebnf-horizontal-orientation nil)
|
|
381 ;;
|
|
382 ;; A = t.
|
|
383 ;; C = x.
|
|
384 ;; ;> C and B are drawn in the same line
|
|
385 ;; B = y.
|
|
386 ;; W = v.
|
|
387 ;;
|
|
388 ;; The graphical result is:
|
|
389 ;;
|
|
390 ;; +---+
|
|
391 ;; | A |
|
|
392 ;; +---+
|
|
393 ;;
|
|
394 ;; +---------+ +-----+
|
|
395 ;; | | | |
|
|
396 ;; | C | | |
|
|
397 ;; | | | B |
|
|
398 ;; +---------+ | |
|
|
399 ;; | |
|
|
400 ;; +-----+
|
|
401 ;;
|
|
402 ;; +-----------+
|
|
403 ;; | W |
|
|
404 ;; +-----------+
|
|
405 ;;
|
|
406 ;; Note that if ascending production sort is used, the productions A and B will
|
|
407 ;; be drawn in the same line instead of C and B.
|
|
408 ;;
|
|
409 ;; If consecutive actions occur, only the last one takes effect, so if you have:
|
|
410 ;;
|
|
411 ;; A = X.
|
|
412 ;; ;<
|
|
413 ;; ^L
|
|
414 ;; ;>
|
|
415 ;; B = Y.
|
|
416 ;;
|
|
417 ;; Only the ;> will take effect, that is, A and B will be drawn in the same
|
|
418 ;; line.
|
|
419 ;;
|
|
420 ;; In ISO EBNF the above actions are specified as (*>*), (*<*), (*[EPS*) and
|
|
421 ;; (*]EPS*). The first example above should be written:
|
|
422 ;;
|
|
423 ;; A = t;
|
|
424 ;; C = x;
|
|
425 ;; (*> C and B are drawn in the same line *)
|
|
426 ;; B = y;
|
|
427 ;; W = v;
|
|
428 ;;
|
|
429 ;; For an example of EPS action when executing `ebnf-eps-buffer' or
|
|
430 ;; `ebnf-eps-region':
|
|
431 ;;
|
|
432 ;; Z = B0.
|
|
433 ;; ;[CC
|
|
434 ;; ;[AA
|
|
435 ;; A = B1.
|
|
436 ;; ;[BB
|
|
437 ;; C = B2.
|
|
438 ;; ;]AA
|
|
439 ;; B = B3.
|
|
440 ;; ;]BB
|
|
441 ;; ;]CC
|
|
442 ;; D = B4.
|
|
443 ;; E = B5.
|
|
444 ;; ;[CC
|
|
445 ;; F = B6.
|
|
446 ;; ;]CC
|
|
447 ;; G = B7.
|
|
448 ;;
|
|
449 ;; The following table summarizes the results:
|
|
450 ;;
|
|
451 ;; EPS FILE NAME NO SORT ASCENDING SORT DESCENDING SORT
|
|
452 ;; ebnf--AA.eps A C A C C A
|
|
453 ;; ebnf--BB.eps C B B C C B
|
|
454 ;; ebnf--CC.eps A C B F A B C F F C B A
|
|
455 ;; ebnf--D.eps D D D
|
|
456 ;; ebnf--E.eps E E E
|
|
457 ;; ebnf--G.eps G G G
|
|
458 ;; ebnf--Z.eps Z Z Z
|
|
459 ;;
|
|
460 ;; As you can see if EPS actions is not used, each single production is
|
|
461 ;; generated per EPS file. To avoid overriding EPS files, use names in ;[ that
|
|
462 ;; it's not an existing production name.
|
|
463 ;;
|
|
464 ;; In the following case:
|
|
465 ;;
|
|
466 ;; A = B0.
|
|
467 ;; ;[AA
|
|
468 ;; A = B1.
|
|
469 ;; ;[BB
|
|
470 ;; A = B2.
|
|
471 ;;
|
|
472 ;; The production A is generated in both files ebnf--AA.eps and ebnf--BB.eps.
|
|
473 ;;
|
|
474 ;;
|
|
475 ;; Utilities
|
|
476 ;; ---------
|
|
477 ;;
|
|
478 ;; Some tools are provided to help you.
|
|
479 ;;
|
|
480 ;; `ebnf-setup' returns the current setup.
|
|
481 ;;
|
|
482 ;; `ebnf-syntax-buffer' does a syntatic analysis of your EBNF in the current
|
|
483 ;; buffer.
|
|
484 ;;
|
|
485 ;; `ebnf-syntax-region' does a syntatic analysis of your EBNF in the current
|
|
486 ;; region.
|
|
487 ;;
|
|
488 ;; `ebnf-customize' activates a customization buffer for ebnf2ps options.
|
|
489 ;;
|
|
490 ;; `ebnf-syntax-buffer', `ebnf-syntax-region' and `ebnf-customize' can be bound
|
|
491 ;; to keys in the same way as `ebnf-' commands.
|
|
492 ;;
|
|
493 ;;
|
|
494 ;; Hooks
|
|
495 ;; -----
|
|
496 ;;
|
|
497 ;; ebn2ps has the following hook variables:
|
|
498 ;;
|
|
499 ;; `ebnf-hook'
|
|
500 ;; It is evaluated once before any ebnf2ps process.
|
|
501 ;;
|
|
502 ;; `ebnf-production-hook'
|
|
503 ;; It is evaluated on each beginning of production.
|
|
504 ;;
|
|
505 ;; `ebnf-page-hook'
|
|
506 ;; It is evaluated on each beginning of page.
|
|
507 ;;
|
|
508 ;;
|
|
509 ;; Options
|
|
510 ;; -------
|
|
511 ;;
|
|
512 ;; Below it's shown a brief description of ebnf2ps options, please, see the
|
|
513 ;; options declaration in the code for a long documentation.
|
|
514 ;;
|
|
515 ;; `ebnf-horizontal-orientation' Non-nil means productions are drawn
|
|
516 ;; horizontally.
|
|
517 ;;
|
|
518 ;; `ebnf-horizontal-max-height' Non-nil means to use maximum production
|
|
519 ;; height in horizontal orientation.
|
|
520 ;;
|
|
521 ;; `ebnf-production-horizontal-space' Specify horizontal space in points
|
|
522 ;; between productions.
|
|
523 ;;
|
|
524 ;; `ebnf-production-vertical-space' Specify vertical space in points between
|
|
525 ;; productions.
|
|
526 ;;
|
|
527 ;; `ebnf-justify-sequence' Specify justification of terms in a
|
|
528 ;; sequence inside alternatives.
|
|
529 ;;
|
|
530 ;; `ebnf-terminal-regexp' Specify how it's a terminal name.
|
|
531 ;;
|
|
532 ;; `ebnf-case-fold-search' Non-nil means ignore case on matching.
|
|
533 ;;
|
|
534 ;; `ebnf-terminal-font' Specify terminal font.
|
|
535 ;;
|
|
536 ;; `ebnf-terminal-shape' Specify terminal box shape.
|
|
537 ;;
|
|
538 ;; `ebnf-terminal-shadow' Non-nil means terminal box will have a
|
|
539 ;; shadow.
|
|
540 ;;
|
|
541 ;; `ebnf-terminal-border-width' Specify border width for terminal box.
|
|
542 ;;
|
|
543 ;; `ebnf-terminal-border-color' Specify border color for terminal box.
|
|
544 ;;
|
|
545 ;; `ebnf-sort-production' Specify how productions are sorted.
|
|
546 ;;
|
|
547 ;; `ebnf-production-font' Specify production font.
|
|
548 ;;
|
|
549 ;; `ebnf-non-terminal-font' Specify non-terminal font.
|
|
550 ;;
|
|
551 ;; `ebnf-non-terminal-shape' Specify non-terminal box shape.
|
|
552 ;;
|
|
553 ;; `ebnf-non-terminal-shadow' Non-nil means non-terminal box will have
|
|
554 ;; a shadow.
|
|
555 ;;
|
|
556 ;; `ebnf-non-terminal-border-width' Specify border width for non-terminal
|
|
557 ;; box.
|
|
558 ;;
|
|
559 ;; `ebnf-non-terminal-border-color' Specify border color for non-terminal
|
|
560 ;; box.
|
|
561 ;;
|
|
562 ;; `ebnf-special-font' Specify special font.
|
|
563 ;;
|
|
564 ;; `ebnf-special-shape' Specify special box shape.
|
|
565 ;;
|
|
566 ;; `ebnf-special-shadow' Non-nil means special box will have a
|
|
567 ;; shadow.
|
|
568 ;;
|
|
569 ;; `ebnf-special-border-width' Specify border width for special box.
|
|
570 ;;
|
|
571 ;; `ebnf-special-border-color' Specify border color for special box.
|
|
572 ;;
|
|
573 ;; `ebnf-except-font' Specify except font.
|
|
574 ;;
|
|
575 ;; `ebnf-except-shape' Specify except box shape.
|
|
576 ;;
|
|
577 ;; `ebnf-except-shadow' Non-nil means except box will have a
|
|
578 ;; shadow.
|
|
579 ;;
|
|
580 ;; `ebnf-except-border-width' Specify border width for except box.
|
|
581 ;;
|
|
582 ;; `ebnf-except-border-color' Specify border color for except box.
|
|
583 ;;
|
|
584 ;; `ebnf-repeat-font' Specify repeat font.
|
|
585 ;;
|
|
586 ;; `ebnf-repeat-shape' Specify repeat box shape.
|
|
587 ;;
|
|
588 ;; `ebnf-repeat-shadow' Non-nil means repeat box will have a
|
|
589 ;; shadow.
|
|
590 ;;
|
|
591 ;; `ebnf-repeat-border-width' Specify border width for repeat box.
|
|
592 ;;
|
|
593 ;; `ebnf-repeat-border-color' Specify border color for repeat box.
|
|
594 ;;
|
|
595 ;; `ebnf-entry-percentage' Specify entry height on alternatives.
|
|
596 ;;
|
|
597 ;; `ebnf-arrow-shape' Specify the arrow shape.
|
|
598 ;;
|
|
599 ;; `ebnf-chart-shape' Specify chart flow shape.
|
|
600 ;;
|
|
601 ;; `ebnf-color-p' Non-nil means use color.
|
|
602 ;;
|
|
603 ;; `ebnf-line-width' Specify flow line width.
|
|
604 ;;
|
|
605 ;; `ebnf-line-color' Specify flow line color.
|
|
606 ;;
|
|
607 ;; `ebnf-user-arrow' Specify a user arrow shape (a PostScript
|
|
608 ;; code).
|
|
609 ;;
|
|
610 ;; `ebnf-debug-ps' Non-nil means to generate PostScript
|
|
611 ;; debug procedures.
|
|
612 ;;
|
|
613 ;; `ebnf-lex-comment-char' Specify the line comment character.
|
|
614 ;;
|
|
615 ;; `ebnf-lex-eop-char' Specify the end of production character.
|
|
616 ;;
|
|
617 ;; `ebnf-syntax' Specify syntax to be recognized.
|
|
618 ;;
|
|
619 ;; `ebnf-iso-alternative-p' Non-nil means use alternative ISO EBNF.
|
|
620 ;;
|
|
621 ;; `ebnf-iso-normalize-p' Non-nil means normalize ISO EBNF syntax
|
|
622 ;; names.
|
|
623 ;;
|
|
624 ;; `ebnf-default-width' Specify additional border width over
|
|
625 ;; default terminal, non-terminal or
|
|
626 ;; special.
|
|
627 ;;
|
|
628 ;; `ebnf-eps-prefix' Specify EPS prefix file name.
|
|
629 ;;
|
|
630 ;; `ebnf-use-float-format' Non-nil means use `%f' float format.
|
|
631 ;;
|
|
632 ;; `ebnf-yac-ignore-error-recovery' Non-nil means ignore error recovery.
|
|
633 ;;
|
|
634 ;; `ebnf-ignore-empty-rule' Non-nil means ignore empty rules.
|
|
635 ;;
|
|
636 ;; `ebnf-optimize' Non-nil means optimize syntatic chart of
|
|
637 ;; rules.
|
|
638 ;;
|
|
639 ;; To set the above options you may:
|
|
640 ;;
|
|
641 ;; a) insert the code in your ~/.emacs, like:
|
|
642 ;;
|
|
643 ;; (setq ebnf-terminal-shape 'bevel)
|
|
644 ;;
|
|
645 ;; This way always keep your default settings when you enter a new Emacs
|
|
646 ;; session.
|
|
647 ;;
|
|
648 ;; b) or use `set-variable' in your Emacs session, like:
|
|
649 ;;
|
|
650 ;; M-x set-variable RET ebnf-terminal-shape RET bevel RET
|
|
651 ;;
|
|
652 ;; This way keep your settings only during the current Emacs session.
|
|
653 ;;
|
|
654 ;; c) or use customization, for example:
|
|
655 ;; click on menu-bar *Help* option,
|
|
656 ;; then click on *Customize*,
|
|
657 ;; then click on *Browse Customization Groups*,
|
|
658 ;; expand *PostScript* group,
|
|
659 ;; expand *Ebnf2ps* group
|
|
660 ;; and then customize ebnf2ps options.
|
|
661 ;; Through this way, you may choose if the settings are kept or not when
|
|
662 ;; you leave out the current Emacs session.
|
|
663 ;;
|
|
664 ;; d) or see the option value:
|
|
665 ;;
|
|
666 ;; C-h v ebnf-terminal-shape RET
|
|
667 ;;
|
|
668 ;; and click the *customize* hypertext button.
|
|
669 ;; Through this way, you may choose if the settings are kept or not when
|
|
670 ;; you leave out the current Emacs session.
|
|
671 ;;
|
|
672 ;; e) or invoke:
|
|
673 ;;
|
|
674 ;; M-x ebnf-customize RET
|
|
675 ;;
|
|
676 ;; and then customize ebnf2ps options.
|
|
677 ;; Through this way, you may choose if the settings are kept or not when
|
|
678 ;; you leave out the current Emacs session.
|
|
679 ;;
|
|
680 ;;
|
|
681 ;; Styles
|
|
682 ;; ------
|
|
683 ;;
|
|
684 ;; Sometimes you need to change the EBNF style you are using, for example,
|
|
685 ;; change the shapes and colors. These changes may force you to set some
|
|
686 ;; variables and after use, set back the variables to the old values.
|
|
687 ;;
|
|
688 ;; To help to handle this situation, ebnf2ps has the following commands to
|
|
689 ;; handle styles:
|
|
690 ;;
|
|
691 ;; `ebnf-insert-style' Insert a new style NAME with inheritance INHERITS and
|
|
692 ;; values VALUES.
|
|
693 ;;
|
|
694 ;; `ebnf-merge-style' Merge values of style NAME with style VALUES.
|
|
695 ;;
|
|
696 ;; `ebnf-apply-style' Set STYLE to current style.
|
|
697 ;;
|
|
698 ;; `ebnf-reset-style' Reset current style.
|
|
699 ;;
|
|
700 ;; `ebnf-push-style' Push the current style and set STYLE to current style.
|
|
701 ;;
|
|
702 ;; `ebnf-pop-style' Pop a style and set it to current style.
|
|
703 ;;
|
|
704 ;; These commands helps to put together a lot of variable settings in a group
|
|
705 ;; and name this group. So when you wish to apply these settings it's only
|
|
706 ;; needed to give the name.
|
|
707 ;;
|
|
708 ;; There is also a notion of simple inheritance of style; so if you declare that
|
|
709 ;; a style A inherits from a style B, all settings of B is applied first and
|
|
710 ;; then the settings of A is applied. This is useful when you wish to modify
|
|
711 ;; some aspects of an existing style, but at same time wish to keep it
|
|
712 ;; unmodified.
|
|
713 ;;
|
|
714 ;; See documentation for `ebnf-style-database'.
|
|
715 ;;
|
|
716 ;;
|
|
717 ;; Layout
|
|
718 ;; ------
|
|
719 ;;
|
|
720 ;; Below it is the layout of minimum area to draw each element, and it's used
|
|
721 ;; the following terms:
|
|
722 ;;
|
|
723 ;; font height is given by:
|
|
724 ;; (terminal font height + non-terminal font height) / 2
|
|
725 ;;
|
|
726 ;; entry is the vertical position used to know where it should be
|
|
727 ;; drawn the flow line in the current element.
|
|
728 ;;
|
|
729 ;;
|
|
730 ;; * SPECIAL, TERMINAL and NON-TERMINAL
|
|
731 ;;
|
|
732 ;; +==============+...................................
|
|
733 ;; | | } font height / 2 } entry }
|
|
734 ;; | XXXXXXXX...|....... } }
|
|
735 ;; ====+ XXXXXXXX +==== } text height ...... } height
|
|
736 ;; : | XXXXXXXX...|...:... }
|
|
737 ;; : | : : | : } font height / 2 }
|
|
738 ;; : +==============+...:...............................
|
|
739 ;; : : : : : :
|
|
740 ;; : : : : : :......................
|
|
741 ;; : : : : : } font height }
|
|
742 ;; : : : : :....... }
|
|
743 ;; : : : : } font height / 2 }
|
|
744 ;; : : : :........... }
|
|
745 ;; : : : } text width } width
|
|
746 ;; : : :.................. }
|
|
747 ;; : : } font height / 2 }
|
|
748 ;; : :...................... }
|
|
749 ;; : } font height }
|
|
750 ;; :.............................................
|
|
751 ;;
|
|
752 ;;
|
|
753 ;; * OPTIONAL
|
|
754 ;;
|
|
755 ;; +==========+.....................................
|
|
756 ;; | | } } }
|
|
757 ;; | | } entry } }
|
|
758 ;; | | } } }
|
|
759 ;; ===+===+ +===+===... } element height } height
|
|
760 ;; : \ | | / : } }
|
|
761 ;; : + | | + : } }
|
|
762 ;; : | +==========+.|................. }
|
|
763 ;; : | : : | : } font height }
|
|
764 ;; : +==============+...................................
|
|
765 ;; : : : :
|
|
766 ;; : : : :......................
|
|
767 ;; : : : } font height * 2 }
|
|
768 ;; : : :.......... }
|
|
769 ;; : : } element width } width
|
|
770 ;; : :..................... }
|
|
771 ;; : } font height * 2 }
|
|
772 ;; :...............................................
|
|
773 ;;
|
|
774 ;;
|
|
775 ;; * ALTERNATIVE
|
|
776 ;;
|
|
777 ;; +===+...................................
|
|
778 ;; +==+ A +==+ } A height } }
|
|
779 ;; | +===+..|........ } entry }
|
|
780 ;; + + } font height } }
|
|
781 ;; / +===+...\....... } }
|
|
782 ;; ===+====+ B +====+=== } B height ..... } height
|
|
783 ;; : \ +===+.../....... }
|
|
784 ;; : + + : } font height }
|
|
785 ;; : | +===+..|........ }
|
|
786 ;; : +==+ C +==+ : } C height }
|
|
787 ;; : : +===+...................................
|
|
788 ;; : : : :
|
|
789 ;; : : : :......................
|
|
790 ;; : : : } font height * 2 }
|
|
791 ;; : : :......... }
|
|
792 ;; : : } max width } width
|
|
793 ;; : :................. }
|
|
794 ;; : } font height * 2 }
|
|
795 ;; :..........................................
|
|
796 ;;
|
|
797 ;; NOTES:
|
|
798 ;; 1. An empty alternative has zero of height.
|
|
799 ;;
|
|
800 ;; 2. The variable `ebnf-entry-percentage' is used to determine the
|
|
801 ;; entry point.
|
|
802 ;;
|
|
803 ;;
|
|
804 ;; * ZERO OR MORE
|
|
805 ;;
|
|
806 ;; +===========+...............................
|
|
807 ;; +=+ separator +=+ } separator height }
|
|
808 ;; / +===========+..\........ }
|
|
809 ;; + + } }
|
|
810 ;; | | } font height }
|
|
811 ;; + + } }
|
|
812 ;; \ +===========+../........ } height = entry
|
|
813 ;; +=+ element +=+ } element height }
|
|
814 ;; /: +===========+..\........ }
|
|
815 ;; + : : + } }
|
|
816 ;; + : : + } font height }
|
|
817 ;; / : : \ } }
|
|
818 ;; ==+=======================+==.......................
|
|
819 ;; : : : :
|
|
820 ;; : : : :.......................
|
|
821 ;; : : : } font height * 2 }
|
|
822 ;; : : :......... }
|
|
823 ;; : : } max width } width
|
|
824 ;; : :......................... }
|
|
825 ;; : } font height * 2 }
|
|
826 ;; :...................................................
|
|
827 ;;
|
|
828 ;;
|
|
829 ;; * ONE OR MORE
|
|
830 ;;
|
|
831 ;; +===========+......................................
|
|
832 ;; +=+ separator +=+ } separator height } }
|
|
833 ;; / +===========+..\...... } }
|
|
834 ;; + + } } entry }
|
|
835 ;; | | } font height } } height
|
|
836 ;; + + } } }
|
|
837 ;; \ +===========+../...... } }
|
|
838 ;; ===+=+ element +=+=== } element height .... }
|
|
839 ;; : : +===========+......................................
|
|
840 ;; : : : :
|
|
841 ;; : : : :........................
|
|
842 ;; : : : } font height * 2 }
|
|
843 ;; : : :....... }
|
|
844 ;; : : } max width } width
|
|
845 ;; : :....................... }
|
|
846 ;; : } font height * 2 }
|
|
847 ;; :..............................................
|
|
848 ;;
|
|
849 ;;
|
|
850 ;; * PRODUCTION
|
|
851 ;;
|
|
852 ;; XXXXXX:......................................
|
|
853 ;; XXXXXX: } production font height }
|
|
854 ;; XXXXXX:............ }
|
|
855 ;; } font height }
|
|
856 ;; +======+....... } height = entry
|
|
857 ;; | | } }
|
|
858 ;; ====+ +==== } element height }
|
|
859 ;; : | | : } }
|
|
860 ;; : +======+.................................
|
|
861 ;; : : : :
|
|
862 ;; : : : :......................
|
|
863 ;; : : : } font height * 2 }
|
|
864 ;; : : :....... }
|
|
865 ;; : : } element width } width
|
|
866 ;; : :.............. }
|
|
867 ;; : } font height * 2 }
|
|
868 ;; :.....................................
|
|
869 ;;
|
|
870 ;;
|
|
871 ;; * REPEAT
|
|
872 ;;
|
|
873 ;; +================+...................................
|
|
874 ;; | | } font height / 2 } entry }
|
|
875 ;; | +===+...|....... } }
|
|
876 ;; ====+ N * | X | +==== } X height ......... } height
|
|
877 ;; : | : : +===+...|...:... }
|
|
878 ;; : | : : : : | : } font height / 2 }
|
|
879 ;; : +================+...:...............................
|
|
880 ;; : : : : : : : :
|
|
881 ;; : : : : : : : :......................
|
|
882 ;; : : : : : : : } font height }
|
|
883 ;; : : : : : : :....... }
|
|
884 ;; : : : : : : } font height / 2 }
|
|
885 ;; : : : : : :........... }
|
|
886 ;; : : : : : } X width }
|
|
887 ;; : : : : :............... }
|
|
888 ;; : : : : } font height / 2 } width
|
|
889 ;; : : : :.................. }
|
|
890 ;; : : : } text width }
|
|
891 ;; : : :..................... }
|
|
892 ;; : : } font height / 2 }
|
|
893 ;; : :........................ }
|
|
894 ;; : } font height }
|
|
895 ;; :...............................................
|
|
896 ;;
|
|
897 ;;
|
|
898 ;; * EXCEPT
|
|
899 ;;
|
|
900 ;; +==================+...................................
|
|
901 ;; | | } font height / 2 } entry }
|
|
902 ;; | +===+ +===+...|....... } }
|
|
903 ;; ====+ | X | - | y | +==== } max height ....... } height
|
|
904 ;; : | +===+ +===+...|...:... }
|
|
905 ;; : | : : : : | : } font height / 2 }
|
|
906 ;; : +==================+...:...............................
|
|
907 ;; : : : : : : : :
|
|
908 ;; : : : : : : : :......................
|
|
909 ;; : : : : : : : } font height }
|
|
910 ;; : : : : : : :....... }
|
|
911 ;; : : : : : : } font height / 2 }
|
|
912 ;; : : : : : :........... }
|
|
913 ;; : : : : : } Y width }
|
|
914 ;; : : : : :............... }
|
|
915 ;; : : : : } font height } width
|
|
916 ;; : : : :................... }
|
|
917 ;; : : : } X width }
|
|
918 ;; : : :....................... }
|
|
919 ;; : : } font height / 2 }
|
|
920 ;; : :.......................... }
|
|
921 ;; : } font height }
|
|
922 ;; :.................................................
|
|
923 ;;
|
|
924 ;; NOTE: If Y element is empty, it's draw nothing at Y place.
|
|
925 ;;
|
|
926 ;;
|
|
927 ;; Internal Structures
|
|
928 ;; -------------------
|
|
929 ;;
|
|
930 ;; ebnf2ps has two passes. The first pass does a lexical and syntatic analysis
|
|
931 ;; of current buffer and generates an intermediate representation. The second
|
|
932 ;; pass uses the intermediate representation to generate the PostScript syntatic
|
|
933 ;; chart.
|
|
934 ;;
|
|
935 ;; The intermediate representation is a list of vectors, the vector element
|
|
936 ;; represents a syntatic chart element. Below is a vector representation for
|
|
937 ;; each syntatic chart element.
|
|
938 ;;
|
|
939 ;; [production WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH NAME PRODUCTION ACTION]
|
|
940 ;; [alternative WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH LIST]
|
|
941 ;; [sequence WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH LIST]
|
|
942 ;; [terminal WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH NAME DEFAULT]
|
|
943 ;; [non-terminal WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH NAME DEFAULT]
|
|
944 ;; [special WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH NAME DEFAULT]
|
|
945 ;; [empty WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH]
|
|
946 ;; [optional WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH ELEMENT]
|
|
947 ;; [one-or-more WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH ELEMENT SEPARATOR]
|
|
948 ;; [zero-or-more WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH ELEMENT SEPARATOR]
|
|
949 ;; [repeat WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH TIMES ELEMENT]
|
|
950 ;; [except WIDTH-FUN DIM-FUN ENTRY HEIGHT WIDTH ELEMENT ELEMENT]
|
|
951 ;;
|
|
952 ;; The first vector position is a function symbol used to generate PostScript
|
|
953 ;; for this element.
|
|
954 ;; WIDTH-FUN is a function symbol called to adjust the element width.
|
|
955 ;; DIM-FUN is a function symbol called to set the element dimensions.
|
|
956 ;; ENTRY is the element entry point.
|
|
957 ;; HEIGHT and WIDTH are the element height and width, respectively.
|
|
958 ;; NAME is a string that it's the element name.
|
|
959 ;; DEFAULT is a boolean that indicates if it's a `default' element.
|
|
960 ;; PRODUCTION and ELEMENT are vectors that represents sub-elements of current
|
|
961 ;; one.
|
|
962 ;; LIST is a list of vector that represents the list part for alternatives and
|
|
963 ;; sequences.
|
|
964 ;; SEPARATOR is a vector that represents the sub-element used to separate the
|
|
965 ;; list elements.
|
|
966 ;; TIMES is a string representing the number of times that ELEMENT is repeated
|
|
967 ;; on a repeat construction.
|
|
968 ;; ACTION indicates some action that should be done before production is
|
|
969 ;; generated. The current actions are:
|
|
970 ;;
|
|
971 ;; nil no action.
|
|
972 ;;
|
|
973 ;; form-feed current production starts on a new page.
|
|
974 ;;
|
|
975 ;; newline current production starts on next line, this is useful
|
|
976 ;; when `ebnf-horizontal-orientation' is non-nil.
|
|
977 ;;
|
|
978 ;; keep-line current production continues on the current line, this
|
|
979 ;; is useful when `ebnf-horizontal-orientation' is nil.
|
|
980 ;;
|
|
981 ;;
|
|
982 ;; Things To Change
|
|
983 ;; ----------------
|
|
984 ;;
|
|
985 ;; . Handle situations when syntatic chart is out of paper.
|
|
986 ;; . Use other alphabet than ascii.
|
|
987 ;; . Optimizations...
|
|
988 ;;
|
|
989 ;;
|
|
990 ;; Acknowledgements
|
|
991 ;; ----------------
|
|
992 ;;
|
|
993 ;; Thanks to all who emailed comments.
|
|
994 ;;
|
|
995 ;;
|
|
996 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
997
|
|
998 ;;; code:
|
|
999
|
|
1000
|
|
1001 (require 'ps-print)
|
|
1002
|
|
1003 (and (string< ps-print-version "3.05.1")
|
|
1004 (error "`ebnf2ps' requires `ps-print' package version 3.05.1 or later"))
|
|
1005
|
|
1006
|
|
1007 ;; temporary fix for ps-print
|
|
1008 (or (fboundp 'set-buffer-multibyte)
|
|
1009 (defun set-buffer-multibyte (arg)
|
|
1010 (setq enable-multibyte-characters arg)))
|
|
1011
|
|
1012 (or (fboundp 'string-as-unibyte)
|
|
1013 (defun string-as-unibyte (arg) arg))
|
|
1014
|
|
1015 (or (fboundp 'string-as-multibyte)
|
|
1016 (defun string-as-multibyte (arg) arg))
|
|
1017
|
|
1018 (or (fboundp 'charset-after)
|
|
1019 (defun charset-after (&optional arg)
|
|
1020 (char-charset (char-after arg))))
|
|
1021
|
|
1022
|
|
1023 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1024 ;; User Variables:
|
|
1025
|
|
1026
|
|
1027 ;;; Interface to the command system
|
|
1028
|
|
1029 (defgroup postscript nil
|
|
1030 "PostScript Group"
|
|
1031 :tag "PostScript"
|
|
1032 :group 'emacs)
|
|
1033
|
|
1034
|
|
1035 (defgroup ebnf2ps nil
|
|
1036 "Translate an EBNF to a syntatic chart on PostScript"
|
|
1037 :prefix "ebnf-"
|
|
1038 :group 'wp
|
|
1039 :group 'postscript)
|
|
1040
|
|
1041
|
|
1042 (defgroup ebnf-special nil
|
|
1043 "Special customization"
|
|
1044 :prefix "ebnf-"
|
|
1045 :tag "Special"
|
|
1046 :group 'ebnf2ps)
|
|
1047
|
|
1048
|
|
1049 (defgroup ebnf-except nil
|
|
1050 "Except customization"
|
|
1051 :prefix "ebnf-"
|
|
1052 :tag "Except"
|
|
1053 :group 'ebnf2ps)
|
|
1054
|
|
1055
|
|
1056 (defgroup ebnf-repeat nil
|
|
1057 "Repeat customization"
|
|
1058 :prefix "ebnf-"
|
|
1059 :tag "Repeat"
|
|
1060 :group 'ebnf2ps)
|
|
1061
|
|
1062
|
|
1063 (defgroup ebnf-terminal nil
|
|
1064 "Terminal customization"
|
|
1065 :prefix "ebnf-"
|
|
1066 :tag "Terminal"
|
|
1067 :group 'ebnf2ps)
|
|
1068
|
|
1069
|
|
1070 (defgroup ebnf-non-terminal nil
|
|
1071 "Non-Terminal customization"
|
|
1072 :prefix "ebnf-"
|
|
1073 :tag "Non-Terminal"
|
|
1074 :group 'ebnf2ps)
|
|
1075
|
|
1076
|
|
1077 (defgroup ebnf-production nil
|
|
1078 "Production customization"
|
|
1079 :prefix "ebnf-"
|
|
1080 :tag "Production"
|
|
1081 :group 'ebnf2ps)
|
|
1082
|
|
1083
|
|
1084 (defgroup ebnf-shape nil
|
|
1085 "Shapes customization"
|
|
1086 :prefix "ebnf-"
|
|
1087 :tag "Shape"
|
|
1088 :group 'ebnf2ps)
|
|
1089
|
|
1090
|
|
1091 (defgroup ebnf-displacement nil
|
|
1092 "Displacement customization"
|
|
1093 :prefix "ebnf-"
|
|
1094 :tag "Displacement"
|
|
1095 :group 'ebnf2ps)
|
|
1096
|
|
1097
|
|
1098 (defgroup ebnf-syntatic nil
|
|
1099 "Syntatic customization"
|
|
1100 :prefix "ebnf-"
|
|
1101 :tag "Syntatic"
|
|
1102 :group 'ebnf2ps)
|
|
1103
|
|
1104
|
|
1105 (defgroup ebnf-optimization nil
|
|
1106 "Optimization customization"
|
|
1107 :prefix "ebnf-"
|
|
1108 :tag "Optimization"
|
|
1109 :group 'ebnf2ps)
|
|
1110
|
|
1111
|
|
1112 (defcustom ebnf-horizontal-orientation nil
|
|
1113 "*Non-nil means productions are drawn horizontally."
|
|
1114 :type 'boolean
|
|
1115 :group 'ebnf-displacement)
|
|
1116
|
|
1117
|
|
1118 (defcustom ebnf-horizontal-max-height nil
|
|
1119 "*Non-nil means to use maximum production height in horizontal orientation.
|
|
1120
|
|
1121 It is only used when `ebnf-horizontal-orientation' is non-nil."
|
|
1122 :type 'boolean
|
|
1123 :group 'ebnf-displacement)
|
|
1124
|
|
1125
|
|
1126 (defcustom ebnf-production-horizontal-space 0.0 ; use ebnf2ps default value
|
|
1127 "*Specify horizontal space in points between productions.
|
|
1128
|
|
1129 Value less or equal to zero forces ebnf2ps to set a proper default value."
|
|
1130 :type 'number
|
|
1131 :group 'ebnf-displacement)
|
|
1132
|
|
1133
|
|
1134 (defcustom ebnf-production-vertical-space 0.0 ; use ebnf2ps default value
|
|
1135 "*Specify vertical space in points between productions.
|
|
1136
|
|
1137 Value less or equal to zero forces ebnf2ps to set a proper default value."
|
|
1138 :type 'number
|
|
1139 :group 'ebnf-displacement)
|
|
1140
|
|
1141
|
|
1142 (defcustom ebnf-justify-sequence 'center
|
|
1143 "*Specify justification of terms in a sequence inside alternatives.
|
|
1144
|
|
1145 Valid values are:
|
|
1146
|
|
1147 `left' left justification
|
|
1148 `right' right justification
|
|
1149 any other value centralize"
|
|
1150 :type '(radio :tag "Sequence Justification"
|
|
1151 (const left) (const right) (other :tag "center" center))
|
|
1152 :group 'ebnf-displacement)
|
|
1153
|
|
1154
|
|
1155 (defcustom ebnf-special-font '(7 Courier "Black" "Gray95" bold italic)
|
|
1156 "*Specify special font.
|
|
1157
|
|
1158 See documentation for `ebnf-production-font'."
|
|
1159 :type '(list :tag "Special Font"
|
|
1160 (number :tag "Font Size")
|
|
1161 (symbol :tag "Font Name")
|
|
1162 (choice :tag "Foreground Color"
|
|
1163 (string :tag "Name")
|
|
1164 (other :tag "Default" nil))
|
|
1165 (choice :tag "Background Color"
|
|
1166 (string :tag "Name")
|
|
1167 (other :tag "Default" nil))
|
|
1168 (repeat :tag "Font Attributes" :inline t
|
|
1169 (choice (const bold) (const italic)
|
|
1170 (const underline) (const strikeout)
|
|
1171 (const overline) (const shadow)
|
|
1172 (const box) (const outline))))
|
|
1173 :group 'ebnf-special)
|
|
1174
|
|
1175
|
|
1176 (defcustom ebnf-special-shape 'bevel
|
|
1177 "*Specify special box shape.
|
|
1178
|
|
1179 See documentation for `ebnf-non-terminal-shape'."
|
|
1180 :type '(radio :tag "Special Shape"
|
|
1181 (const miter) (const round) (const bevel))
|
|
1182 :group 'ebnf-special)
|
|
1183
|
|
1184
|
|
1185 (defcustom ebnf-special-shadow nil
|
|
1186 "*Non-nil means special box will have a shadow."
|
|
1187 :type 'boolean
|
|
1188 :group 'ebnf-special)
|
|
1189
|
|
1190
|
|
1191 (defcustom ebnf-special-border-width 0.5
|
|
1192 "*Specify border width for special box."
|
|
1193 :type 'number
|
|
1194 :group 'ebnf-special)
|
|
1195
|
|
1196
|
|
1197 (defcustom ebnf-special-border-color "Black"
|
|
1198 "*Specify border color for special box."
|
|
1199 :type 'string
|
|
1200 :group 'ebnf-special)
|
|
1201
|
|
1202
|
|
1203 (defcustom ebnf-except-font '(7 Courier "Black" "Gray90" bold italic)
|
|
1204 "*Specify except font.
|
|
1205
|
|
1206 See documentation for `ebnf-production-font'."
|
|
1207 :type '(list :tag "Except Font"
|
|
1208 (number :tag "Font Size")
|
|
1209 (symbol :tag "Font Name")
|
|
1210 (choice :tag "Foreground Color"
|
|
1211 (string :tag "Name")
|
|
1212 (other :tag "Default" nil))
|
|
1213 (choice :tag "Background Color"
|
|
1214 (string :tag "Name")
|
|
1215 (other :tag "Default" nil))
|
|
1216 (repeat :tag "Font Attributes" :inline t
|
|
1217 (choice (const bold) (const italic)
|
|
1218 (const underline) (const strikeout)
|
|
1219 (const overline) (const shadow)
|
|
1220 (const box) (const outline))))
|
|
1221 :group 'ebnf-except)
|
|
1222
|
|
1223
|
|
1224 (defcustom ebnf-except-shape 'bevel
|
|
1225 "*Specify except box shape.
|
|
1226
|
|
1227 See documentation for `ebnf-non-terminal-shape'."
|
|
1228 :type '(radio :tag "Except Shape"
|
|
1229 (const miter) (const round) (const bevel))
|
|
1230 :group 'ebnf-except)
|
|
1231
|
|
1232
|
|
1233 (defcustom ebnf-except-shadow nil
|
|
1234 "*Non-nil means except box will have a shadow."
|
|
1235 :type 'boolean
|
|
1236 :group 'ebnf-except)
|
|
1237
|
|
1238
|
|
1239 (defcustom ebnf-except-border-width 0.25
|
|
1240 "*Specify border width for except box."
|
|
1241 :type 'number
|
|
1242 :group 'ebnf-except)
|
|
1243
|
|
1244
|
|
1245 (defcustom ebnf-except-border-color "Black"
|
|
1246 "*Specify border color for except box."
|
|
1247 :type 'string
|
|
1248 :group 'ebnf-except)
|
|
1249
|
|
1250
|
|
1251 (defcustom ebnf-repeat-font '(7 Courier "Black" "Gray85" bold italic)
|
|
1252 "*Specify repeat font.
|
|
1253
|
|
1254 See documentation for `ebnf-production-font'."
|
|
1255 :type '(list :tag "Repeat Font"
|
|
1256 (number :tag "Font Size")
|
|
1257 (symbol :tag "Font Name")
|
|
1258 (choice :tag "Foreground Color"
|
|
1259 (string :tag "Name")
|
|
1260 (other :tag "Default" nil))
|
|
1261 (choice :tag "Background Color"
|
|
1262 (string :tag "Name")
|
|
1263 (other :tag "Default" nil))
|
|
1264 (repeat :tag "Font Attributes" :inline t
|
|
1265 (choice (const bold) (const italic)
|
|
1266 (const underline) (const strikeout)
|
|
1267 (const overline) (const shadow)
|
|
1268 (const box) (const outline))))
|
|
1269 :group 'ebnf-repeat)
|
|
1270
|
|
1271
|
|
1272 (defcustom ebnf-repeat-shape 'bevel
|
|
1273 "*Specify repeat box shape.
|
|
1274
|
|
1275 See documentation for `ebnf-non-terminal-shape'."
|
|
1276 :type '(radio :tag "Repeat Shape"
|
|
1277 (const miter) (const round) (const bevel))
|
|
1278 :group 'ebnf-repeat)
|
|
1279
|
|
1280
|
|
1281 (defcustom ebnf-repeat-shadow nil
|
|
1282 "*Non-nil means repeat box will have a shadow."
|
|
1283 :type 'boolean
|
|
1284 :group 'ebnf-repeat)
|
|
1285
|
|
1286
|
|
1287 (defcustom ebnf-repeat-border-width 0.0
|
|
1288 "*Specify border width for repeat box."
|
|
1289 :type 'number
|
|
1290 :group 'ebnf-repeat)
|
|
1291
|
|
1292
|
|
1293 (defcustom ebnf-repeat-border-color "Black"
|
|
1294 "*Specify border color for repeat box."
|
|
1295 :type 'string
|
|
1296 :group 'ebnf-repeat)
|
|
1297
|
|
1298
|
|
1299 (defcustom ebnf-terminal-font '(7 Courier "Black" "White")
|
|
1300 "*Specify terminal font.
|
|
1301
|
|
1302 See documentation for `ebnf-production-font'."
|
|
1303 :type '(list :tag "Terminal Font"
|
|
1304 (number :tag "Font Size")
|
|
1305 (symbol :tag "Font Name")
|
|
1306 (choice :tag "Foreground Color"
|
|
1307 (string :tag "Name")
|
|
1308 (other :tag "Default" nil))
|
|
1309 (choice :tag "Background Color"
|
|
1310 (string :tag "Name")
|
|
1311 (other :tag "Default" nil))
|
|
1312 (repeat :tag "Font Attributes" :inline t
|
|
1313 (choice (const bold) (const italic)
|
|
1314 (const underline) (const strikeout)
|
|
1315 (const overline) (const shadow)
|
|
1316 (const box) (const outline))))
|
|
1317 :group 'ebnf-terminal)
|
|
1318
|
|
1319
|
|
1320 (defcustom ebnf-terminal-shape 'miter
|
|
1321 "*Specify terminal box shape.
|
|
1322
|
|
1323 See documentation for `ebnf-non-terminal-shape'."
|
|
1324 :type '(radio :tag "Terminal Shape"
|
|
1325 (const miter) (const round) (const bevel))
|
|
1326 :group 'ebnf-terminal)
|
|
1327
|
|
1328
|
|
1329 (defcustom ebnf-terminal-shadow nil
|
|
1330 "*Non-nil means terminal box will have a shadow."
|
|
1331 :type 'boolean
|
|
1332 :group 'ebnf-terminal)
|
|
1333
|
|
1334
|
|
1335 (defcustom ebnf-terminal-border-width 1.0
|
|
1336 "*Specify border width for terminal box."
|
|
1337 :type 'number
|
|
1338 :group 'ebnf-terminal)
|
|
1339
|
|
1340
|
|
1341 (defcustom ebnf-terminal-border-color "Black"
|
|
1342 "*Specify border color for terminal box."
|
|
1343 :type 'string
|
|
1344 :group 'ebnf-terminal)
|
|
1345
|
|
1346
|
|
1347 (defcustom ebnf-sort-production nil
|
|
1348 "*Specify how productions are sorted.
|
|
1349
|
|
1350 Valid values are:
|
|
1351
|
|
1352 nil don't sort productions.
|
|
1353 `ascending' ascending sort.
|
|
1354 any other value descending sort."
|
|
1355 :type '(radio :tag "Production Sort"
|
|
1356 (const :tag "Ascending" ascending)
|
|
1357 (const :tag "Descending" descending)
|
|
1358 (other :tag "No Sort" nil))
|
|
1359 :group 'ebnf-production)
|
|
1360
|
|
1361
|
|
1362 (defcustom ebnf-production-font '(10 Helvetica "Black" "White" bold)
|
|
1363 "*Specify production header font.
|
|
1364
|
|
1365 It is a list with the following form:
|
|
1366
|
|
1367 (SIZE NAME FOREGROUND BACKGROUND ATTRIBUTE...)
|
|
1368
|
|
1369 Where:
|
|
1370 SIZE is the font size.
|
|
1371 NAME is the font name symbol.
|
|
1372 ATTRIBUTE is one of the following symbols:
|
|
1373 bold - use bold font.
|
|
1374 italic - use italic font.
|
|
1375 underline - put a line under text.
|
|
1376 strikeout - like underline, but the line is in middle of text.
|
|
1377 overline - like underline, but the line is over the text.
|
|
1378 shadow - text will have a shadow.
|
|
1379 box - text will be surrounded by a box.
|
|
1380 outline - print characters as hollow outlines.
|
|
1381 FOREGROUND is a foreground string color name; if it's nil, the default color is
|
|
1382 \"Black\".
|
|
1383 BACKGROUND is a background string color name; if it's nil, the default color is
|
|
1384 \"White\".
|
|
1385
|
|
1386 See `ps-font-info-database' for valid font name."
|
|
1387 :type '(list :tag "Production Font"
|
|
1388 (number :tag "Font Size")
|
|
1389 (symbol :tag "Font Name")
|
|
1390 (choice :tag "Foreground Color"
|
|
1391 (string :tag "Name")
|
|
1392 (other :tag "Default" nil))
|
|
1393 (choice :tag "Background Color"
|
|
1394 (string :tag "Name")
|
|
1395 (other :tag "Default" nil))
|
|
1396 (repeat :tag "Font Attributes" :inline t
|
|
1397 (choice (const bold) (const italic)
|
|
1398 (const underline) (const strikeout)
|
|
1399 (const overline) (const shadow)
|
|
1400 (const box) (const outline))))
|
|
1401 :group 'ebnf-production)
|
|
1402
|
|
1403
|
|
1404 (defcustom ebnf-non-terminal-font '(7 Helvetica "Black" "White")
|
|
1405 "*Specify non-terminal font.
|
|
1406
|
|
1407 See documentation for `ebnf-production-font'."
|
|
1408 :type '(list :tag "Non-Terminal Font"
|
|
1409 (number :tag "Font Size")
|
|
1410 (symbol :tag "Font Name")
|
|
1411 (choice :tag "Foreground Color"
|
|
1412 (string :tag "Name")
|
|
1413 (other :tag "Default" nil))
|
|
1414 (choice :tag "Background Color"
|
|
1415 (string :tag "Name")
|
|
1416 (other :tag "Default" nil))
|
|
1417 (repeat :tag "Font Attributes" :inline t
|
|
1418 (choice (const bold) (const italic)
|
|
1419 (const underline) (const strikeout)
|
|
1420 (const overline) (const shadow)
|
|
1421 (const box) (const outline))))
|
|
1422 :group 'ebnf-non-terminal)
|
|
1423
|
|
1424
|
|
1425 (defcustom ebnf-non-terminal-shape 'round
|
|
1426 "*Specify non-terminal box shape.
|
|
1427
|
|
1428 Valid values are:
|
|
1429
|
|
1430 `miter' +-------+
|
|
1431 | |
|
|
1432 +-------+
|
|
1433
|
|
1434 `round' -------
|
|
1435 ( )
|
|
1436 -------
|
|
1437
|
|
1438 `bevel' /-------\\
|
|
1439 | |
|
|
1440 \\-------/
|
|
1441
|
|
1442 Any other value is treated as `miter'."
|
|
1443 :type '(radio :tag "Non-Terminal Shape"
|
|
1444 (const miter) (const round) (const bevel))
|
|
1445 :group 'ebnf-non-terminal)
|
|
1446
|
|
1447
|
|
1448 (defcustom ebnf-non-terminal-shadow nil
|
|
1449 "*Non-nil means non-terminal box will have a shadow."
|
|
1450 :type 'boolean
|
|
1451 :group 'ebnf-non-terminal)
|
|
1452
|
|
1453
|
|
1454 (defcustom ebnf-non-terminal-border-width 1.0
|
|
1455 "*Specify border width for non-terminal box."
|
|
1456 :type 'number
|
|
1457 :group 'ebnf-non-terminal)
|
|
1458
|
|
1459
|
|
1460 (defcustom ebnf-non-terminal-border-color "Black"
|
|
1461 "*Specify border color for non-terminal box."
|
|
1462 :type 'string
|
|
1463 :group 'ebnf-non-terminal)
|
|
1464
|
|
1465
|
|
1466 (defcustom ebnf-arrow-shape 'hollow
|
|
1467 "*Specify the arrow shape.
|
|
1468
|
|
1469 Valid values are:
|
|
1470
|
|
1471 `none' ======
|
|
1472
|
|
1473 `semi-up' * `transparent' *
|
|
1474 * |*
|
|
1475 =====* | *
|
|
1476 ==+==*
|
|
1477 | *
|
|
1478 |*
|
|
1479 *
|
|
1480
|
|
1481 `semi-down' =====* `hollow' *
|
|
1482 * |*
|
|
1483 * | *
|
|
1484 ==+ *
|
|
1485 | *
|
|
1486 |*
|
|
1487 *
|
|
1488
|
|
1489 `simple' * `full' *
|
|
1490 * |*
|
|
1491 =====* |X*
|
|
1492 * ==+XX*
|
|
1493 * |X*
|
|
1494 |*
|
|
1495 *
|
|
1496
|
|
1497 `user' See also documentation for variable `ebnf-user-arrow'.
|
|
1498
|
|
1499 Any other value is treated as `none'."
|
|
1500 :type '(radio :tag "Arrow Shape"
|
|
1501 (const none) (const semi-up)
|
|
1502 (const semi-down) (const simple)
|
|
1503 (const transparent) (const hollow)
|
|
1504 (const full) (const user))
|
|
1505 :group 'ebnf-shape)
|
|
1506
|
|
1507
|
|
1508 (defcustom ebnf-chart-shape 'round
|
|
1509 "*Specify chart flow shape.
|
|
1510
|
|
1511 See documentation for `ebnf-non-terminal-shape'."
|
|
1512 :type '(radio :tag "Chart Flow Shape"
|
|
1513 (const miter) (const round) (const bevel))
|
|
1514 :group 'ebnf-shape)
|
|
1515
|
|
1516
|
|
1517 (defcustom ebnf-user-arrow nil
|
|
1518 "*Specify a user arrow shape (a PostScript code).
|
|
1519
|
|
1520 PostScript code should draw a right arrow.
|
|
1521
|
|
1522 The anatomy of a right arrow is:
|
|
1523
|
|
1524 ...... Initial position
|
|
1525 :
|
|
1526 : *.................
|
|
1527 : | * } }
|
|
1528 : | * } hT4 }
|
|
1529 v | * } }
|
|
1530 ======+======*... } hT2
|
|
1531 : | *: } }
|
|
1532 : | * : } hT4 }
|
|
1533 : | * : } }
|
|
1534 : *.................
|
|
1535 : : :
|
|
1536 : : :..........
|
|
1537 : : } hT2 }
|
|
1538 : :.......... } hT
|
|
1539 : } hT2 }
|
|
1540 :.......................
|
|
1541
|
|
1542 Where `hT', `hT2' and `hT4' are predefined PostScript variable names that can be
|
|
1543 used to generate your own arrow. As these variables are used along PostScript
|
|
1544 execution, *DON'T* modify the values of them. Instead, copy the values, if you
|
|
1545 need to modify them.
|
|
1546
|
|
1547 The relation between these variables is: hT = 2 * hT2 = 4 * hT4.
|
|
1548
|
|
1549 The variable `ebnf-user-arrow' is only used when `ebnf-arrow-shape' is set to
|
|
1550 symbol `user'.
|
|
1551
|
|
1552 See function `ebnf-user-arrow' for valid values and how values are processed."
|
|
1553 :type '(radio :tag "User Arrow Shape"
|
|
1554 (const nil)
|
|
1555 string
|
|
1556 symbol
|
|
1557 (repeat :tag "List"
|
|
1558 (radio string
|
|
1559 symbol
|
|
1560 sexp)))
|
|
1561 :group 'ebnf-shape)
|
|
1562
|
|
1563
|
|
1564 (defcustom ebnf-syntax 'ebnf
|
|
1565 "*Specify syntax to be recognized.
|
|
1566
|
|
1567 Valid values are:
|
|
1568
|
27495
|
1569 `ebnf' ebnf2ps recognizes the syntax described in ebnf2ps
|
|
1570 documentation.
|
27451
|
1571 The following variables *ONLY* have effect with this
|
|
1572 setting:
|
|
1573 `ebnf-terminal-regexp', `ebnf-case-fold-search',
|
|
1574 `ebnf-lex-comment-char' and `ebnf-lex-eop-char'.
|
|
1575
|
|
1576 `iso-ebnf' ebnf2ps recognizes the syntax described in the URL:
|
|
1577 `http://www.cl.cam.ac.uk/~mgk25/iso-ebnf.html'
|
|
1578 (\"International Standard of the ISO EBNF Notation\").
|
|
1579 The following variables *ONLY* have effect with this
|
|
1580 setting:
|
|
1581 `ebnf-iso-alternative-p' and `ebnf-iso-normalize-p'.
|
|
1582
|
|
1583 `yacc' ebnf2ps recognizes the Yacc/Bison syntax.
|
|
1584 The following variable *ONLY* has effect with this
|
|
1585 setting:
|
|
1586 `ebnf-yac-ignore-error-recovery'.
|
|
1587
|
|
1588 Any other value is treated as `ebnf'."
|
|
1589 :type '(radio :tag "Syntax"
|
|
1590 (const ebnf) (const iso-ebnf) (const yacc))
|
|
1591 :group 'ebnf-syntatic)
|
|
1592
|
|
1593
|
|
1594 (defcustom ebnf-lex-comment-char ?\;
|
|
1595 "*Specify the line comment character.
|
|
1596
|
|
1597 It's used only when `ebnf-syntax' is `ebnf'."
|
|
1598 :type 'character
|
|
1599 :group 'ebnf-syntatic)
|
|
1600
|
|
1601
|
|
1602 (defcustom ebnf-lex-eop-char ?.
|
|
1603 "*Specify the end of production character.
|
|
1604
|
|
1605 It's used only when `ebnf-syntax' is `ebnf'."
|
|
1606 :type 'character
|
|
1607 :group 'ebnf-syntatic)
|
|
1608
|
|
1609
|
|
1610 (defcustom ebnf-terminal-regexp nil
|
|
1611 "*Specify how it's a terminal name.
|
|
1612
|
|
1613 If it's nil, the terminal name must be enclosed by `\"'.
|
|
1614 If it's a string, it should be a regexp that it'll be used to determine a
|
|
1615 terminal name; terminal name may also be enclosed by `\"'.
|
|
1616
|
|
1617 It's used only when `ebnf-syntax' is `ebnf'."
|
|
1618 :type '(radio :tag "Terminal Name"
|
|
1619 (const nil) regexp)
|
|
1620 :group 'ebnf-syntatic)
|
|
1621
|
|
1622
|
|
1623 (defcustom ebnf-case-fold-search nil
|
|
1624 "*Non-nil means ignore case on matching.
|
|
1625
|
|
1626 It's only used when `ebnf-terminal-regexp' is non-nil and when `ebnf-syntax' is
|
|
1627 `ebnf'."
|
|
1628 :type 'boolean
|
|
1629 :group 'ebnf-syntatic)
|
|
1630
|
|
1631
|
|
1632 (defcustom ebnf-iso-alternative-p nil
|
|
1633 "*Non-nil means use alternative ISO EBNF.
|
|
1634
|
|
1635 It's only used when `ebnf-syntax' is `iso-ebnf'.
|
|
1636
|
|
1637 This variable affects the following symbol set:
|
|
1638
|
|
1639 STANDARD ALTERNATIVE
|
|
1640 | ==> / or !
|
|
1641 [ ==> (/
|
|
1642 ] ==> /)
|
|
1643 { ==> (:
|
|
1644 } ==> :)
|
|
1645 ; ==> ."
|
|
1646 :type 'boolean
|
|
1647 :group 'ebnf-syntatic)
|
|
1648
|
|
1649
|
|
1650 (defcustom ebnf-iso-normalize-p nil
|
|
1651 "*Non-nil means normalize ISO EBNF syntax names.
|
|
1652
|
|
1653 Normalize a name means that several contiguous spaces inside name become a
|
|
1654 single space, so \"A B C\" is normalized to \"A B C\".
|
|
1655
|
|
1656 It's only used when `ebnf-syntax' is `iso-ebnf'."
|
|
1657 :type 'boolean
|
|
1658 :group 'ebnf-syntatic)
|
|
1659
|
|
1660
|
|
1661 (defcustom ebnf-eps-prefix "ebnf--"
|
|
1662 "*Specify EPS prefix file name.
|
|
1663
|
|
1664 See `ebnf-eps-buffer' and `ebnf-eps-region' commands."
|
|
1665 :type 'string
|
|
1666 :group 'ebnf2ps)
|
|
1667
|
|
1668
|
|
1669 (defcustom ebnf-entry-percentage 0.5 ; middle
|
|
1670 "*Specify entry height on alternatives.
|
|
1671
|
|
1672 It must be a float between 0.0 (top) and 1.0 (bottom)."
|
|
1673 :type 'number
|
|
1674 :group 'ebnf2ps)
|
|
1675
|
|
1676
|
|
1677 (defcustom ebnf-default-width 0.6
|
|
1678 "*Specify additional border width over default terminal, non-terminal or
|
|
1679 special."
|
|
1680 :type 'number
|
|
1681 :group 'ebnf2ps)
|
|
1682
|
|
1683
|
|
1684 ;; Printing color requires x-color-values.
|
|
1685 (defcustom ebnf-color-p (or (fboundp 'x-color-values) ; Emacs
|
|
1686 (fboundp 'color-instance-rgb-components)) ; XEmacs
|
|
1687 "*Non-nil means use color."
|
|
1688 :type 'boolean
|
|
1689 :group 'ebnf2ps)
|
|
1690
|
|
1691
|
|
1692 (defcustom ebnf-line-width 1.0
|
|
1693 "*Specify flow line width."
|
|
1694 :type 'number
|
|
1695 :group 'ebnf2ps)
|
|
1696
|
|
1697
|
|
1698 (defcustom ebnf-line-color "Black"
|
|
1699 "*Specify flow line color."
|
|
1700 :type 'string
|
|
1701 :group 'ebnf2ps)
|
|
1702
|
|
1703
|
|
1704 (defcustom ebnf-debug-ps nil
|
|
1705 "*Non-nil means to generate PostScript debug procedures.
|
|
1706
|
|
1707 It is intended to help PostScript programmers in debugging."
|
|
1708 :type 'boolean
|
|
1709 :group 'ebnf2ps)
|
|
1710
|
|
1711
|
|
1712 (defcustom ebnf-use-float-format t
|
|
1713 "*Non-nil means use `%f' float format.
|
|
1714
|
|
1715 The advantage of using float format is that ebnf2ps generates a little short
|
|
1716 PostScript file.
|
|
1717
|
|
1718 If it occurs the error message:
|
|
1719
|
|
1720 Invalid format operation %f
|
|
1721
|
|
1722 when executing ebnf2ps, set `ebnf-use-float-format' to nil."
|
|
1723 :type 'boolean
|
|
1724 :group 'ebnf2ps)
|
|
1725
|
|
1726
|
|
1727 (defcustom ebnf-yac-ignore-error-recovery nil
|
|
1728 "*Non-nil means ignore error recovery.
|
|
1729
|
|
1730 It's only used when `ebnf-syntax' is `yacc'."
|
|
1731 :type 'boolean
|
|
1732 :group 'ebnf-syntatic)
|
|
1733
|
|
1734
|
|
1735 (defcustom ebnf-ignore-empty-rule nil
|
|
1736 "*Non-nil means ignore empty rules.
|
|
1737
|
|
1738 It's interesting to set this variable if your Yacc/Bison grammar has a lot of
|
|
1739 middle action rule."
|
|
1740 :type 'boolean
|
|
1741 :group 'ebnf-optimization)
|
|
1742
|
|
1743
|
|
1744 (defcustom ebnf-optimize nil
|
|
1745 "*Non-nil means optimize syntatic chart of rules.
|
|
1746
|
|
1747 The following optimizations are done:
|
|
1748
|
|
1749 left recursion:
|
|
1750 1. A = B | A C. ==> A = B {C}*.
|
|
1751 2. A = B | A B. ==> A = {B}+.
|
|
1752 3. A = | A B. ==> A = {B}*.
|
|
1753 4. A = B | A C B. ==> A = {B || C}+.
|
|
1754 5. A = B | D | A C | A E. ==> A = ( B | D ) { C | E }*.
|
|
1755
|
|
1756 optional:
|
|
1757 6. A = B | . ==> A = [B].
|
|
1758 7. A = | B . ==> A = [B].
|
|
1759
|
|
1760 factoration:
|
|
1761 8. A = B C | B D. ==> A = B (C | D).
|
|
1762 9. A = C B | D B. ==> A = (C | D) B.
|
|
1763 10. A = B C E | B D E. ==> A = B (C | D) E.
|
|
1764
|
|
1765 The above optimizations are specially useful when `ebnf-syntax' is `yacc'."
|
|
1766 :type 'boolean
|
|
1767 :group 'ebnf-optimization)
|
|
1768
|
|
1769
|
|
1770 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1771 ;; Customization
|
|
1772
|
|
1773
|
|
1774 ;;;###autoload
|
|
1775 (defun ebnf-customize ()
|
|
1776 "Customization for ebnf group."
|
|
1777 (interactive)
|
|
1778 (customize-group 'ebnf2ps))
|
|
1779
|
|
1780
|
|
1781 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1782 ;; User commands
|
|
1783
|
|
1784
|
|
1785 ;;;###autoload
|
|
1786 (defun ebnf-print-buffer (&optional filename)
|
|
1787 "Generate and print a PostScript syntatic chart image of the buffer.
|
|
1788
|
|
1789 When called with a numeric prefix argument (C-u), prompts the user for
|
|
1790 the name of a file to save the PostScript image in, instead of sending
|
|
1791 it to the printer.
|
|
1792
|
|
1793 More specifically, the FILENAME argument is treated as follows: if it
|
|
1794 is nil, send the image to the printer. If FILENAME is a string, save
|
|
1795 the PostScript image in a file with that name. If FILENAME is a
|
|
1796 number, prompt the user for the name of the file to save in."
|
|
1797 (interactive (list (ps-print-preprint current-prefix-arg)))
|
|
1798 (ebnf-print-region (point-min) (point-max) filename))
|
|
1799
|
|
1800
|
|
1801 ;;;###autoload
|
|
1802 (defun ebnf-print-region (from to &optional filename)
|
|
1803 "Generate and print a PostScript syntatic chart image of the region.
|
|
1804 Like `ebnf-print-buffer', but prints just the current region."
|
|
1805 (interactive (list (point) (mark) (ps-print-preprint current-prefix-arg)))
|
|
1806 (run-hooks 'ebnf-hook)
|
|
1807 (or (ebnf-spool-region from to)
|
|
1808 (ps-do-despool filename)))
|
|
1809
|
|
1810
|
|
1811 ;;;###autoload
|
|
1812 (defun ebnf-spool-buffer ()
|
|
1813 "Generate and spool a PostScript syntatic chart image of the buffer.
|
|
1814 Like `ebnf-print-buffer' except that the PostScript image is saved in a
|
|
1815 local buffer to be sent to the printer later.
|
|
1816
|
|
1817 Use the command `ebnf-despool' to send the spooled images to the printer."
|
|
1818 (interactive)
|
|
1819 (ebnf-spool-region (point-min) (point-max)))
|
|
1820
|
|
1821
|
|
1822 ;;;###autoload
|
|
1823 (defun ebnf-spool-region (from to)
|
|
1824 "Generate a PostScript syntatic chart image of the region and spool locally.
|
|
1825 Like `ebnf-spool-buffer', but spools just the current region.
|
|
1826
|
|
1827 Use the command `ebnf-despool' to send the spooled images to the printer."
|
|
1828 (interactive "r")
|
|
1829 (ebnf-generate-region from to 'ebnf-generate))
|
|
1830
|
|
1831
|
|
1832 ;;;###autoload
|
|
1833 (defun ebnf-eps-buffer ()
|
|
1834 "Generate a PostScript syntatic chart image of the buffer in a EPS file.
|
|
1835
|
|
1836 Indeed, for each production is generated a EPS file.
|
|
1837 The EPS file name has the following form:
|
|
1838
|
|
1839 <PREFIX><PRODUCTION>.eps
|
|
1840
|
|
1841 <PREFIX> is given by variable `ebnf-eps-prefix'.
|
|
1842 The default value is \"ebnf--\".
|
|
1843
|
|
1844 <PRODUCTION> is the production name.
|
|
1845 The production name is mapped to form a valid file name.
|
|
1846 For example, the production name \"A/B + C\" is mapped to
|
|
1847 \"A_B_+_C\" and the EPS file name used is \"ebnf--A_B_+_C.eps\".
|
|
1848
|
|
1849 WARNING: It's *NOT* asked any confirmation to override an existing file."
|
|
1850 (interactive)
|
|
1851 (ebnf-eps-region (point-min) (point-max)))
|
|
1852
|
|
1853
|
|
1854 ;;;###autoload
|
|
1855 (defun ebnf-eps-region (from to)
|
|
1856 "Generate a PostScript syntatic chart image of the region in a EPS file.
|
|
1857
|
|
1858 Indeed, for each production is generated a EPS file.
|
|
1859 The EPS file name has the following form:
|
|
1860
|
|
1861 <PREFIX><PRODUCTION>.eps
|
|
1862
|
|
1863 <PREFIX> is given by variable `ebnf-eps-prefix'.
|
|
1864 The default value is \"ebnf--\".
|
|
1865
|
|
1866 <PRODUCTION> is the production name.
|
|
1867 The production name is mapped to form a valid file name.
|
|
1868 For example, the production name \"A/B + C\" is mapped to
|
|
1869 \"A_B_+_C\" and the EPS file name used is \"ebnf--A_B_+_C.eps\".
|
|
1870
|
|
1871 WARNING: It's *NOT* asked any confirmation to override an existing file."
|
|
1872 (interactive "r")
|
|
1873 (let ((ebnf-eps-executing t))
|
|
1874 (ebnf-generate-region from to 'ebnf-generate-eps)))
|
|
1875
|
|
1876
|
|
1877 ;;;###autoload
|
|
1878 (defalias 'ebnf-despool 'ps-despool)
|
|
1879
|
|
1880
|
|
1881 ;;;###autoload
|
|
1882 (defun ebnf-syntax-buffer ()
|
|
1883 "Does a syntatic analysis of the current buffer."
|
|
1884 (interactive)
|
|
1885 (ebnf-syntax-region (point-min) (point-max)))
|
|
1886
|
|
1887
|
|
1888 ;;;###autoload
|
|
1889 (defun ebnf-syntax-region (from to)
|
|
1890 "Does a syntatic analysis of a region."
|
|
1891 (interactive "r")
|
|
1892 (ebnf-generate-region from to nil))
|
|
1893
|
|
1894
|
|
1895 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1896 ;; Utilities
|
|
1897
|
|
1898
|
|
1899 ;;;###autoload
|
|
1900 (defun ebnf-setup ()
|
|
1901 "Return the current ebnf2ps setup."
|
|
1902 (format
|
|
1903 "
|
|
1904 \(setq ebnf-special-font %s
|
|
1905 ebnf-special-shape %s
|
|
1906 ebnf-special-shadow %S
|
|
1907 ebnf-special-border-width %S
|
|
1908 ebnf-special-border-color %S
|
|
1909 ebnf-except-font %s
|
|
1910 ebnf-except-shape %s
|
|
1911 ebnf-except-shadow %S
|
|
1912 ebnf-except-border-width %S
|
|
1913 ebnf-except-border-color %S
|
|
1914 ebnf-repeat-font %s
|
|
1915 ebnf-repeat-shape %s
|
|
1916 ebnf-repeat-shadow %S
|
|
1917 ebnf-repeat-border-width %S
|
|
1918 ebnf-repeat-border-color %S
|
|
1919 ebnf-terminal-regexp %S
|
|
1920 ebnf-case-fold-search %S
|
|
1921 ebnf-terminal-font %s
|
|
1922 ebnf-terminal-shape %s
|
|
1923 ebnf-terminal-shadow %S
|
|
1924 ebnf-terminal-border-width %S
|
|
1925 ebnf-terminal-border-color %S
|
|
1926 ebnf-non-terminal-font %s
|
|
1927 ebnf-non-terminal-shape %s
|
|
1928 ebnf-non-terminal-shadow %S
|
|
1929 ebnf-non-terminal-border-width %S
|
|
1930 ebnf-non-terminal-border-color %S
|
|
1931 ebnf-sort-production %s
|
|
1932 ebnf-production-font %s
|
|
1933 ebnf-arrow-shape %s
|
|
1934 ebnf-chart-shape %s
|
|
1935 ebnf-user-arrow %s
|
|
1936 ebnf-horizontal-orientation %S
|
|
1937 ebnf-horizontal-max-height %S
|
|
1938 ebnf-production-horizontal-space %S
|
|
1939 ebnf-production-vertical-space %S
|
|
1940 ebnf-justify-sequence %s
|
|
1941 ebnf-lex-comment-char ?\\%03o
|
|
1942 ebnf-lex-eop-char ?\\%03o
|
|
1943 ebnf-syntax %s
|
|
1944 ebnf-iso-alternative-p %S
|
|
1945 ebnf-iso-normalize-p %S
|
|
1946 ebnf-eps-prefix %S
|
|
1947 ebnf-entry-percentage %S
|
|
1948 ebnf-color-p %S
|
|
1949 ebnf-line-width %S
|
|
1950 ebnf-line-color %S
|
|
1951 ebnf-debug-ps %S
|
|
1952 ebnf-use-float-format %S
|
|
1953 ebnf-yac-ignore-error-recovery %S
|
|
1954 ebnf-ignore-empty-rule %S
|
|
1955 ebnf-optimize %S)
|
|
1956 "
|
|
1957 (ps-print-quote ebnf-special-font)
|
|
1958 (ps-print-quote ebnf-special-shape)
|
|
1959 ebnf-special-shadow
|
|
1960 ebnf-special-border-width
|
|
1961 ebnf-special-border-color
|
|
1962 (ps-print-quote ebnf-except-font)
|
|
1963 (ps-print-quote ebnf-except-shape)
|
|
1964 ebnf-except-shadow
|
|
1965 ebnf-except-border-width
|
|
1966 ebnf-except-border-color
|
|
1967 (ps-print-quote ebnf-repeat-font)
|
|
1968 (ps-print-quote ebnf-repeat-shape)
|
|
1969 ebnf-repeat-shadow
|
|
1970 ebnf-repeat-border-width
|
|
1971 ebnf-repeat-border-color
|
|
1972 ebnf-terminal-regexp
|
|
1973 ebnf-case-fold-search
|
|
1974 (ps-print-quote ebnf-terminal-font)
|
|
1975 (ps-print-quote ebnf-terminal-shape)
|
|
1976 ebnf-terminal-shadow
|
|
1977 ebnf-terminal-border-width
|
|
1978 ebnf-terminal-border-color
|
|
1979 (ps-print-quote ebnf-non-terminal-font)
|
|
1980 (ps-print-quote ebnf-non-terminal-shape)
|
|
1981 ebnf-non-terminal-shadow
|
|
1982 ebnf-non-terminal-border-width
|
|
1983 ebnf-non-terminal-border-color
|
|
1984 (ps-print-quote ebnf-sort-production)
|
|
1985 (ps-print-quote ebnf-production-font)
|
|
1986 (ps-print-quote ebnf-arrow-shape)
|
|
1987 (ps-print-quote ebnf-chart-shape)
|
|
1988 (ps-print-quote ebnf-user-arrow)
|
|
1989 ebnf-horizontal-orientation
|
|
1990 ebnf-horizontal-max-height
|
|
1991 ebnf-production-horizontal-space
|
|
1992 ebnf-production-vertical-space
|
|
1993 (ps-print-quote ebnf-justify-sequence)
|
|
1994 ebnf-lex-comment-char
|
|
1995 ebnf-lex-eop-char
|
|
1996 (ps-print-quote ebnf-syntax)
|
|
1997 ebnf-iso-alternative-p
|
|
1998 ebnf-iso-normalize-p
|
|
1999 ebnf-eps-prefix
|
|
2000 ebnf-entry-percentage
|
|
2001 ebnf-color-p
|
|
2002 ebnf-line-width
|
|
2003 ebnf-line-color
|
|
2004 ebnf-debug-ps
|
|
2005 ebnf-use-float-format
|
|
2006 ebnf-yac-ignore-error-recovery
|
|
2007 ebnf-ignore-empty-rule
|
|
2008 ebnf-optimize))
|
|
2009
|
|
2010
|
|
2011 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
2012 ;; Style variables
|
|
2013
|
|
2014
|
|
2015 (defvar ebnf-stack-style nil
|
|
2016 "Used in functions `ebnf-reset-style', `ebnf-push-style' and
|
|
2017 `ebnf-pop-style'.")
|
|
2018
|
|
2019
|
|
2020 (defvar ebnf-current-style 'default
|
|
2021 "Used in functions `ebnf-apply-style' and `ebnf-push-style'.")
|
|
2022
|
|
2023
|
|
2024 (defconst ebnf-style-custom-list
|
|
2025 '(ebnf-special-font
|
|
2026 ebnf-special-shape
|
|
2027 ebnf-special-shadow
|
|
2028 ebnf-special-border-width
|
|
2029 ebnf-special-border-color
|
|
2030 ebnf-except-font
|
|
2031 ebnf-except-shape
|
|
2032 ebnf-except-shadow
|
|
2033 ebnf-except-border-width
|
|
2034 ebnf-except-border-color
|
|
2035 ebnf-repeat-font
|
|
2036 ebnf-repeat-shape
|
|
2037 ebnf-repeat-shadow
|
|
2038 ebnf-repeat-border-width
|
|
2039 ebnf-repeat-border-color
|
|
2040 ebnf-terminal-regexp
|
|
2041 ebnf-case-fold-search
|
|
2042 ebnf-terminal-font
|
|
2043 ebnf-terminal-shape
|
|
2044 ebnf-terminal-shadow
|
|
2045 ebnf-terminal-border-width
|
|
2046 ebnf-terminal-border-color
|
|
2047 ebnf-non-terminal-font
|
|
2048 ebnf-non-terminal-shape
|
|
2049 ebnf-non-terminal-shadow
|
|
2050 ebnf-non-terminal-border-width
|
|
2051 ebnf-non-terminal-border-color
|
|
2052 ebnf-sort-production
|
|
2053 ebnf-production-font
|
|
2054 ebnf-arrow-shape
|
|
2055 ebnf-chart-shape
|
|
2056 ebnf-user-arrow
|
|
2057 ebnf-horizontal-orientation
|
|
2058 ebnf-horizontal-max-height
|
|
2059 ebnf-production-horizontal-space
|
|
2060 ebnf-production-vertical-space
|
|
2061 ebnf-justify-sequence
|
|
2062 ebnf-lex-comment-char
|
|
2063 ebnf-lex-eop-char
|
|
2064 ebnf-syntax
|
|
2065 ebnf-iso-alternative-p
|
|
2066 ebnf-iso-normalize-p
|
|
2067 ebnf-eps-prefix
|
|
2068 ebnf-entry-percentage
|
|
2069 ebnf-color-p
|
|
2070 ebnf-line-width
|
|
2071 ebnf-line-color
|
|
2072 ebnf-debug-ps
|
|
2073 ebnf-use-float-format
|
|
2074 ebnf-yac-ignore-error-recovery
|
|
2075 ebnf-ignore-empty-rule
|
|
2076 ebnf-optimize)
|
|
2077 "List of valid symbol custom variable.")
|
|
2078
|
|
2079
|
|
2080 (defvar ebnf-style-database
|
|
2081 '(;; EBNF default
|
|
2082 (default
|
|
2083 nil
|
|
2084 (ebnf-special-font . '(7 Courier "Black" "Gray95" bold italic))
|
|
2085 (ebnf-special-shape . 'bevel)
|
|
2086 (ebnf-special-shadow . nil)
|
|
2087 (ebnf-special-border-width . 0.5)
|
|
2088 (ebnf-special-border-color . "Black")
|
|
2089 (ebnf-except-font . '(7 Courier "Black" "Gray90" bold italic))
|
|
2090 (ebnf-except-shape . 'bevel)
|
|
2091 (ebnf-except-shadow . nil)
|
|
2092 (ebnf-except-border-width . 0.25)
|
|
2093 (ebnf-except-border-color . "Black")
|
|
2094 (ebnf-repeat-font . '(7 Courier "Black" "Gray85" bold italic))
|
|
2095 (ebnf-repeat-shape . 'bevel)
|
|
2096 (ebnf-repeat-shadow . nil)
|
|
2097 (ebnf-repeat-border-width . 0.0)
|
|
2098 (ebnf-repeat-border-color . "Black")
|
|
2099 (ebnf-terminal-regexp . nil)
|
|
2100 (ebnf-case-fold-search . nil)
|
|
2101 (ebnf-terminal-font . '(7 Courier "Black" "White"))
|
|
2102 (ebnf-terminal-shape . 'miter)
|
|
2103 (ebnf-terminal-shadow . nil)
|
|
2104 (ebnf-terminal-border-width . 1.0)
|
|
2105 (ebnf-terminal-border-color . "Black")
|
|
2106 (ebnf-non-terminal-font . '(7 Helvetica "Black" "White"))
|
|
2107 (ebnf-non-terminal-shape . 'round)
|
|
2108 (ebnf-non-terminal-shadow . nil)
|
|
2109 (ebnf-non-terminal-border-width . 1.0)
|
|
2110 (ebnf-non-terminal-border-color . "Black")
|
|
2111 (ebnf-sort-production . nil)
|
|
2112 (ebnf-production-font . '(10 Helvetica "Black" "White" bold))
|
|
2113 (ebnf-arrow-shape . 'hollow)
|
|
2114 (ebnf-chart-shape . 'round)
|
|
2115 (ebnf-user-arrow . nil)
|
|
2116 (ebnf-horizontal-orientation . nil)
|
|
2117 (ebnf-horizontal-max-height . nil)
|
|
2118 (ebnf-production-horizontal-space . 0.0)
|
|
2119 (ebnf-production-vertical-space . 0.0)
|
|
2120 (ebnf-justify-sequence . 'center)
|
|
2121 (ebnf-lex-comment-char . ?\;)
|
|
2122 (ebnf-lex-eop-char . ?.)
|
|
2123 (ebnf-syntax . 'ebnf)
|
|
2124 (ebnf-iso-alternative-p . nil)
|
|
2125 (ebnf-iso-normalize-p . nil)
|
|
2126 (ebnf-eps-prefix . "ebnf--")
|
|
2127 (ebnf-entry-percentage . 0.5)
|
|
2128 (ebnf-color-p . (or (fboundp 'x-color-values) ; Emacs
|
|
2129 (fboundp 'color-instance-rgb-components))) ; XEmacs
|
|
2130 (ebnf-line-width . 1.0)
|
|
2131 (ebnf-line-color . "Black")
|
|
2132 (ebnf-debug-ps . nil)
|
|
2133 (ebnf-use-float-format . t)
|
|
2134 (ebnf-yac-ignore-error-recovery . nil)
|
|
2135 (ebnf-ignore-empty-rule . nil)
|
|
2136 (ebnf-optimize . nil))
|
|
2137 ;; Happy EBNF default
|
|
2138 (happy
|
|
2139 default
|
|
2140 (ebnf-justify-sequence . 'left)
|
|
2141 (ebnf-lex-comment-char . ?\#)
|
|
2142 (ebnf-lex-eop-char . ?\;))
|
|
2143 ;; ISO EBNF default
|
|
2144 (iso-ebnf
|
|
2145 default
|
|
2146 (ebnf-syntax . 'iso-ebnf))
|
|
2147 ;; Yacc/Bison default
|
|
2148 (yacc
|
|
2149 default
|
|
2150 (ebnf-syntax . 'yacc))
|
|
2151 )
|
|
2152 "Style database.
|
|
2153
|
|
2154 Each element has the following form:
|
|
2155
|
|
2156 (CUSTOM INHERITS (VAR . VALUE)...)
|
|
2157
|
|
2158 CUSTOM is a symbol name style.
|
|
2159 INHERITS is a symbol name style from which the current style inherits the
|
|
2160 context. If INHERITS is nil, means that there is no inheritance.
|
|
2161 VAR is a valid ebnf2ps symbol custom variable. See `ebnf-style-custom-list' for
|
|
2162 valid symbol variable.
|
|
2163 VALUE is a sexp which it'll be evaluated to set the value to VAR. So, don't
|
|
2164 forget to quote symbols and constant lists. See `default' style for an
|
|
2165 example.
|
|
2166
|
|
2167 Don't handle this variable directly. Use functions `ebnf-insert-style' and
|
|
2168 `ebnf-merge-style'.")
|
|
2169
|
|
2170
|
|
2171 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
2172 ;; Style commands
|
|
2173
|
|
2174
|
|
2175 ;;;###autoload
|
|
2176 (defun ebnf-insert-style (name inherits &rest values)
|
|
2177 "Insert a new style NAME with inheritance INHERITS and values VALUES."
|
|
2178 (interactive)
|
|
2179 (and (assoc name ebnf-style-database)
|
|
2180 (error "Style name already exists: %s" name))
|
|
2181 (or (assoc inherits ebnf-style-database)
|
|
2182 (error "Style inheritance name does'nt exist: %s" inherits))
|
|
2183 (setq ebnf-style-database
|
|
2184 (cons (cons name (cons inherits (ebnf-check-style-values values)))
|
|
2185 ebnf-style-database)))
|
|
2186
|
|
2187
|
|
2188 ;;;###autoload
|
|
2189 (defun ebnf-merge-style (name &rest values)
|
|
2190 "Merge values of style NAME with style VALUES."
|
|
2191 (interactive)
|
|
2192 (let ((style (or (assoc name ebnf-style-database)
|
|
2193 (error "Style name does'nt exist: %s" name)))
|
|
2194 (merge (ebnf-check-style-values values))
|
|
2195 val elt new check)
|
|
2196 ;; modify value of existing variables
|
|
2197 (setq val (nthcdr 2 style))
|
|
2198 (while merge
|
|
2199 (setq check (car merge)
|
|
2200 merge (cdr merge)
|
|
2201 elt (assoc (car check) val))
|
|
2202 (if elt
|
|
2203 (setcdr elt (cdr check))
|
|
2204 (setq new (cons check new))))
|
|
2205 ;; insert new variables
|
|
2206 (nconc style (nreverse new))))
|
|
2207
|
|
2208
|
|
2209 ;;;###autoload
|
|
2210 (defun ebnf-apply-style (style)
|
|
2211 "Set STYLE to current style.
|
|
2212
|
|
2213 It returns the old style symbol."
|
|
2214 (interactive)
|
|
2215 (prog1
|
|
2216 ebnf-current-style
|
|
2217 (and (ebnf-apply-style1 style)
|
|
2218 (setq ebnf-current-style style))))
|
|
2219
|
|
2220
|
|
2221 ;;;###autoload
|
|
2222 (defun ebnf-reset-style (&optional style)
|
|
2223 "Reset current style.
|
|
2224
|
|
2225 It returns the old style symbol."
|
|
2226 (interactive)
|
|
2227 (setq ebnf-stack-style nil)
|
|
2228 (ebnf-apply-style (or style 'default)))
|
|
2229
|
|
2230
|
|
2231 ;;;###autoload
|
|
2232 (defun ebnf-push-style (&optional style)
|
|
2233 "Push the current style and set STYLE to current style.
|
|
2234
|
|
2235 It returns the old style symbol."
|
|
2236 (interactive)
|
|
2237 (prog1
|
|
2238 ebnf-current-style
|
|
2239 (setq ebnf-stack-style (cons ebnf-current-style ebnf-stack-style))
|
|
2240 (and style
|
|
2241 (ebnf-apply-style style))))
|
|
2242
|
|
2243
|
|
2244 ;;;###autoload
|
|
2245 (defun ebnf-pop-style ()
|
|
2246 "Pop a style and set it to current style.
|
|
2247
|
|
2248 It returns the old style symbol."
|
|
2249 (interactive)
|
|
2250 (prog1
|
|
2251 (ebnf-apply-style (car ebnf-stack-style))
|
|
2252 (setq ebnf-stack-style (cdr ebnf-stack-style))))
|
|
2253
|
|
2254
|
|
2255 (defun ebnf-apply-style1 (style)
|
|
2256 (let ((value (cdr (assoc style ebnf-style-database))))
|
|
2257 (prog1
|
|
2258 value
|
|
2259 (and (car value) (ebnf-apply-style1 (car value)))
|
|
2260 (while (setq value (cdr value))
|
|
2261 (set (caar value) (eval (cdar value)))))))
|
|
2262
|
|
2263
|
|
2264 (defun ebnf-check-style-values (values)
|
|
2265 (let (style)
|
|
2266 (while values
|
|
2267 (and (memq (car values) ebnf-style-custom-list)
|
|
2268 (setq style (cons (car values) style)))
|
|
2269 (setq values (cdr values)))
|
|
2270 (nreverse style)))
|
|
2271
|
|
2272
|
|
2273 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
2274 ;; Internal variables
|
|
2275
|
|
2276
|
|
2277 (make-local-hook 'ebnf-hook)
|
|
2278 (make-local-hook 'ebnf-production-hook)
|
|
2279 (make-local-hook 'ebnf-page-hook)
|
|
2280
|
|
2281
|
|
2282 (defvar ebnf-eps-buffer-name " *EPS*")
|
|
2283 (defvar ebnf-parser-func nil)
|
|
2284 (defvar ebnf-eps-executing nil)
|
|
2285 (defvar ebnf-eps-upper-x 0.0)
|
|
2286 (make-variable-buffer-local 'ebnf-eps-upper-x)
|
|
2287 (defvar ebnf-eps-upper-y 0.0)
|
|
2288 (make-variable-buffer-local 'ebnf-eps-upper-y)
|
|
2289 (defvar ebnf-eps-prod-width 0.0)
|
|
2290 (make-variable-buffer-local 'ebnf-eps-prod-width)
|
|
2291 (defvar ebnf-eps-max-height 0.0)
|
|
2292 (make-variable-buffer-local 'ebnf-eps-max-height)
|
|
2293 (defvar ebnf-eps-max-width 0.0)
|
|
2294 (make-variable-buffer-local 'ebnf-eps-max-width)
|
|
2295
|
|
2296
|
|
2297 (defvar ebnf-eps-context nil
|
|
2298 "List of EPS file name during parsing.
|
|
2299
|
|
2300 See section \"Actions in Comments\" in ebnf2ps documentation.")
|
|
2301
|
|
2302
|
|
2303 (defvar ebnf-eps-production-list nil
|
|
2304 "Alist associating production name with EPS file name list.
|
|
2305
|
|
2306 Each element has the following form:
|
|
2307
|
|
2308 (PRODUCTION EPS-FILENAME...)
|
|
2309
|
|
2310 PRODUCTION is the production name.
|
|
2311 EPS-FILENAME is the EPS file name.
|
|
2312
|
|
2313 It's generated during parsing and used during EPS generation.
|
|
2314
|
|
2315 See `ebnf-eps-context' and section \"Actions in Comments\" in ebnf2ps
|
|
2316 documentation.")
|
|
2317
|
|
2318
|
|
2319 (defconst ebnf-arrow-shape-alist
|
|
2320 '((none . 0)
|
|
2321 (semi-up . 1)
|
|
2322 (semi-down . 2)
|
|
2323 (simple . 3)
|
|
2324 (transparent . 4)
|
|
2325 (hollow . 5)
|
|
2326 (full . 6)
|
|
2327 (user . 7))
|
|
2328 "Alist associating values for `ebnf-arrow-shape'.
|
|
2329
|
|
2330 See documentation for `ebnf-arrow-shape'.")
|
|
2331
|
|
2332
|
|
2333 (defconst ebnf-terminal-shape-alist
|
|
2334 '((miter . 0)
|
|
2335 (round . 1)
|
|
2336 (bevel . 2))
|
|
2337 "Alist associating values from `ebnf-terminal-shape' to a bit vector.
|
|
2338
|
|
2339 See documentation for `ebnf-terminal-shape', `ebnf-non-terminal-shape' and
|
|
2340 `ebnf-chart-shape'.")
|
|
2341
|
|
2342
|
|
2343 (defvar ebnf-limit nil)
|
|
2344 (defvar ebnf-action nil)
|
|
2345 (defvar ebnf-action-list nil)
|
|
2346
|
|
2347
|
|
2348 (defvar ebnf-default-p nil)
|
|
2349
|
|
2350
|
|
2351 (defvar ebnf-font-height-P 0)
|
|
2352 (defvar ebnf-font-height-T 0)
|
|
2353 (defvar ebnf-font-height-NT 0)
|
|
2354 (defvar ebnf-font-height-S 0)
|
|
2355 (defvar ebnf-font-height-E 0)
|
|
2356 (defvar ebnf-font-height-R 0)
|
|
2357 (defvar ebnf-font-width-P 0)
|
|
2358 (defvar ebnf-font-width-T 0)
|
|
2359 (defvar ebnf-font-width-NT 0)
|
|
2360 (defvar ebnf-font-width-S 0)
|
|
2361 (defvar ebnf-font-width-E 0)
|
|
2362 (defvar ebnf-font-width-R 0)
|
|
2363 (defvar ebnf-space-T 0)
|
|
2364 (defvar ebnf-space-NT 0)
|
|
2365 (defvar ebnf-space-S 0)
|
|
2366 (defvar ebnf-space-E 0)
|
|
2367 (defvar ebnf-space-R 0)
|
|
2368
|
|
2369
|
|
2370 (defvar ebnf-basic-width 0)
|
|
2371 (defvar ebnf-basic-height 0)
|
|
2372 (defvar ebnf-vertical-space 0)
|
|
2373 (defvar ebnf-horizontal-space 0)
|
|
2374
|
|
2375
|
|
2376 (defvar ebnf-settings nil)
|
|
2377 (defvar ebnf-fonts-required nil)
|
|
2378
|
|
2379
|
|
2380 (defconst ebnf-debug
|
|
2381 "
|
|
2382 % === begin EBNF procedures to help debugging
|
|
2383
|
|
2384 % Mark visually current point: string debug
|
|
2385 /debug
|
|
2386 {/-s- exch def
|
|
2387 currentpoint
|
|
2388 gsave -s- show grestore
|
|
2389 gsave
|
|
2390 20 20 rlineto
|
|
2391 0 -40 rlineto
|
|
2392 -40 40 rlineto
|
|
2393 0 -40 rlineto
|
|
2394 20 20 rlineto
|
|
2395 stroke
|
|
2396 grestore
|
|
2397 moveto
|
|
2398 }def
|
|
2399
|
|
2400 % Show number value: number string debug-number
|
|
2401 /debug-number
|
|
2402 {gsave
|
|
2403 20 0 rmoveto show ([) show 60 string cvs show (]) show
|
|
2404 grestore
|
|
2405 }def
|
|
2406
|
|
2407 % === end EBNF procedures to help debugging
|
|
2408
|
|
2409 "
|
|
2410 "This is intended to help debugging PostScript programming.")
|
|
2411
|
|
2412
|
|
2413 (defconst ebnf-prologue
|
|
2414 "
|
|
2415 % === begin EBNF engine
|
|
2416
|
|
2417 % --- Basic Definitions
|
|
2418
|
|
2419 /fS F
|
|
2420 /SpaceS FontHeight 0.5 mul def
|
|
2421 /HeightS FontHeight FontHeight add def
|
|
2422
|
|
2423 /fE F
|
|
2424 /SpaceE FontHeight 0.5 mul def
|
|
2425 /HeightE FontHeight FontHeight add def
|
|
2426
|
|
2427 /fR F
|
|
2428 /SpaceR FontHeight 0.5 mul def
|
|
2429 /HeightR FontHeight FontHeight add def
|
|
2430
|
|
2431 /fT F
|
|
2432 /SpaceT FontHeight 0.5 mul def
|
|
2433 /HeightT FontHeight FontHeight add def
|
|
2434
|
|
2435 /fNT F
|
|
2436 /SpaceNT FontHeight 0.5 mul def
|
|
2437 /HeightNT FontHeight FontHeight add def
|
|
2438
|
|
2439 /T HeightT HeightNT add 0.5 mul def
|
|
2440 /hT T 0.5 mul def
|
|
2441 /hT2 hT 0.5 mul def
|
|
2442 /hT4 hT 0.25 mul def
|
|
2443
|
|
2444 /Er 0.1 def % Error factor
|
|
2445
|
|
2446
|
|
2447 /c{currentpoint}bind def
|
|
2448 /xyi{/xi c /yi exch def def}bind def
|
|
2449 /xyo{/xo c /yo exch def def}bind def
|
|
2450 /xyp{/xp c /yp exch def def}bind def
|
|
2451 /xyt{/xt c /yt exch def def}bind def
|
|
2452
|
|
2453 % vertical movement: x y height vm
|
|
2454 /vm{add moveto}bind def
|
|
2455
|
|
2456 % horizontal movement: x y width hm
|
|
2457 /hm{3 -1 roll exch add exch moveto}bind def
|
|
2458
|
|
2459 % set color: [R G B] SetRGB
|
|
2460 /SetRGB{aload pop setrgbcolor}bind def
|
|
2461
|
|
2462 % filling gray area: gray-scale FillGray
|
|
2463 /FillGray{gsave setgray fill grestore}bind def
|
|
2464
|
|
2465 % filling color area: [R G B] FillRGB
|
|
2466 /FillRGB{gsave SetRGB fill grestore}bind def
|
|
2467
|
|
2468 /Stroke{LineWidth setlinewidth LineColor SetRGB stroke}bind def
|
|
2469 /StrokeShape{borderwidth setlinewidth bordercolor SetRGB stroke}bind def
|
|
2470 /Gstroke{gsave Stroke grestore}bind def
|
|
2471
|
|
2472 % Empty Line: width EL
|
|
2473 /EL{0 rlineto Gstroke}bind def
|
|
2474
|
|
2475 % --- Arrows
|
|
2476
|
|
2477 /Down{hT2 neg hT4 neg rlineto}bind def
|
|
2478
|
|
2479 /Arrow
|
|
2480 {hT2 neg hT4 rmoveto
|
|
2481 hT2 hT4 neg rlineto
|
|
2482 Down
|
|
2483 }bind def
|
|
2484
|
|
2485 /ArrowPath{c newpath moveto Arrow closepath}bind def
|
|
2486
|
|
2487 %>Right Arrow: RA
|
|
2488 % \\
|
|
2489 % *---+
|
|
2490 % /
|
|
2491 /RA-vector
|
|
2492 [{} % 0 - none
|
|
2493 {hT2 neg hT4 rlineto} % 1 - semi-up
|
|
2494 {Down} % 2 - semi-down
|
|
2495 {Arrow} % 3 - simple
|
|
2496 {Gstroke ArrowPath} % 4 - transparent
|
|
2497 {Gstroke ArrowPath 1 FillGray} % 5 - hollow
|
|
2498 {Gstroke ArrowPath LineColor FillRGB} % 6 - full
|
|
2499 {Gstroke gsave UserArrow grestore} % 7 - user
|
|
2500 ]def
|
|
2501
|
|
2502 /RA
|
|
2503 {hT 0 rlineto
|
|
2504 c
|
|
2505 RA-vector ArrowShape get exec
|
|
2506 Gstroke
|
|
2507 moveto
|
|
2508 }def
|
|
2509
|
|
2510 % rotation DrawArrow
|
|
2511 /DrawArrow
|
|
2512 {gsave
|
|
2513 0 0 translate
|
|
2514 rotate
|
|
2515 RA
|
|
2516 c
|
|
2517 grestore
|
|
2518 rmoveto
|
|
2519 }def
|
|
2520
|
|
2521 %>Left Arrow: LA
|
|
2522 % /
|
|
2523 % +---*
|
|
2524 % \\
|
|
2525 /LA{180 DrawArrow}def
|
|
2526
|
|
2527 %>Up Arrow: UA
|
|
2528 % +
|
|
2529 % /|\\
|
|
2530 % |
|
|
2531 % *
|
|
2532 /UA{90 DrawArrow}def
|
|
2533
|
|
2534 %>Down Arrow: DA
|
|
2535 % *
|
|
2536 % |
|
|
2537 % \\|/
|
|
2538 % +
|
|
2539 /DA{270 DrawArrow}def
|
|
2540
|
|
2541 % --- Corners
|
|
2542
|
|
2543 %>corner Right Descendent: height arrow corner_RD
|
|
2544 % _ | arrow
|
|
2545 % / height > 0 | 0 - none
|
|
2546 % | | 1 - right
|
|
2547 % * ---------- | 2 - left
|
|
2548 % | | 3 - vertical
|
|
2549 % \\ height < 0 |
|
|
2550 % - |
|
|
2551 /cRD0-vector
|
|
2552 [% 0 - none
|
|
2553 {0 h rlineto
|
|
2554 hT 0 rlineto}
|
|
2555 % 1 - right
|
|
2556 {0 h rlineto
|
|
2557 RA}
|
|
2558 % 2 - left
|
|
2559 {hT 0 rmoveto xyi
|
|
2560 LA
|
|
2561 0 h neg rlineto
|
|
2562 xi yi moveto}
|
|
2563 % 3 - vertical
|
|
2564 {hT h rmoveto xyi
|
|
2565 hT neg 0 rlineto
|
|
2566 h 0 gt{DA}{UA}ifelse
|
|
2567 xi yi moveto}
|
|
2568 ]def
|
|
2569
|
|
2570 /cRD-vector
|
|
2571 [{cRD0-vector arrow get exec} % 0 - miter
|
|
2572 {0 0 0 h hT h rcurveto} % 1 - rounded
|
|
2573 {hT h rlineto} % 2 - bevel
|
|
2574 ]def
|
|
2575
|
|
2576 /corner_RD
|
|
2577 {/arrow exch def /h exch def
|
|
2578 cRD-vector ChartShape get exec
|
|
2579 Gstroke
|
|
2580 }def
|
|
2581
|
|
2582 %>corner Right Ascendent: height arrow corner_RA
|
|
2583 % | arrow
|
|
2584 % | height > 0 | 0 - none
|
|
2585 % / | 1 - right
|
|
2586 % *- ---------- | 2 - left
|
|
2587 % \\ | 3 - vertical
|
|
2588 % | height < 0 |
|
|
2589 % |
|
|
2590 /cRA0-vector
|
|
2591 [% 0 - none
|
|
2592 {hT 0 rlineto
|
|
2593 0 h rlineto}
|
|
2594 % 1 - right
|
|
2595 {RA
|
|
2596 0 h rlineto}
|
|
2597 % 2 - left
|
|
2598 {hT h rmoveto xyi
|
|
2599 0 h neg rlineto
|
|
2600 LA
|
|
2601 xi yi moveto}
|
|
2602 % 3 - vertical
|
|
2603 {hT h rmoveto xyi
|
|
2604 h 0 gt{DA}{UA}ifelse
|
|
2605 hT neg 0 rlineto
|
|
2606 xi yi moveto}
|
|
2607 ]def
|
|
2608
|
|
2609 /cRA-vector
|
|
2610 [{cRA0-vector arrow get exec} % 0 - miter
|
|
2611 {0 0 hT 0 hT h rcurveto} % 1 - rounded
|
|
2612 {hT h rlineto} % 2 - bevel
|
|
2613 ]def
|
|
2614
|
|
2615 /corner_RA
|
|
2616 {/arrow exch def /h exch def
|
|
2617 cRA-vector ChartShape get exec
|
|
2618 Gstroke
|
|
2619 }def
|
|
2620
|
|
2621 %>corner Left Descendent: height arrow corner_LD
|
|
2622 % _ | arrow
|
|
2623 % \\ height > 0 | 0 - none
|
|
2624 % | | 1 - right
|
|
2625 % * ---------- | 2 - left
|
|
2626 % | | 3 - vertical
|
|
2627 % / height < 0 |
|
|
2628 % - |
|
|
2629 /cLD0-vector
|
|
2630 [% 0 - none
|
|
2631 {0 h rlineto
|
|
2632 hT neg 0 rlineto}
|
|
2633 % 1 - right
|
|
2634 {hT neg h rmoveto xyi
|
|
2635 RA
|
|
2636 0 h neg rlineto
|
|
2637 xi yi moveto}
|
|
2638 % 2 - left
|
|
2639 {0 h rlineto
|
|
2640 LA}
|
|
2641 % 3 - vertical
|
|
2642 {hT neg h rmoveto xyi
|
|
2643 hT 0 rlineto
|
|
2644 h 0 gt{DA}{UA}ifelse
|
|
2645 xi yi moveto}
|
|
2646 ]def
|
|
2647
|
|
2648 /cLD-vector
|
|
2649 [{cLD0-vector arrow get exec} % 0 - miter
|
|
2650 {0 0 0 h hT neg h rcurveto} % 1 - rounded
|
|
2651 {hT neg h rlineto} % 2 - bevel
|
|
2652 ]def
|
|
2653
|
|
2654 /corner_LD
|
|
2655 {/arrow exch def /h exch def
|
|
2656 cLD-vector ChartShape get exec
|
|
2657 Gstroke
|
|
2658 }def
|
|
2659
|
|
2660 %>corner Left Ascendent: height arrow corner_LA
|
|
2661 % | arrow
|
|
2662 % | height > 0 | 0 - none
|
|
2663 % \\ | 1 - right
|
|
2664 % -* ---------- | 2 - left
|
|
2665 % / | 3 - vertical
|
|
2666 % | height < 0 |
|
|
2667 % |
|
|
2668 /cLA0-vector
|
|
2669 [% 0 - none
|
|
2670 {hT neg 0 rlineto
|
|
2671 0 h rlineto}
|
|
2672 % 1 - right
|
|
2673 {hT neg h rmoveto xyi
|
|
2674 0 h neg rlineto
|
|
2675 RA
|
|
2676 xi yi moveto}
|
|
2677 % 2 - left
|
|
2678 {LA
|
|
2679 0 h rlineto}
|
|
2680 % 3 - vertical
|
|
2681 {hT neg h rmoveto xyi
|
|
2682 h 0 gt{DA}{UA}ifelse
|
|
2683 hT 0 rlineto
|
|
2684 xi yi moveto}
|
|
2685 ]def
|
|
2686
|
|
2687 /cLA-vector
|
|
2688 [{cLA0-vector arrow get exec} % 0 - miter
|
|
2689 {0 0 hT neg 0 hT neg h rcurveto} % 1 - rounded
|
|
2690 {hT neg h rlineto} % 2 - bevel
|
|
2691 ]def
|
|
2692
|
|
2693 /corner_LA
|
|
2694 {/arrow exch def /h exch def
|
|
2695 cLA-vector ChartShape get exec
|
|
2696 Gstroke
|
|
2697 }def
|
|
2698
|
|
2699 % --- Flow Stuff
|
|
2700
|
|
2701 % height prepare_height |- line_height corner_height corner_height
|
|
2702 /prepare_height
|
|
2703 {dup 0 gt
|
|
2704 {T sub hT}
|
|
2705 {T add hT neg}ifelse
|
|
2706 dup
|
|
2707 }def
|
|
2708
|
|
2709 %>Left Alternative: height LAlt
|
|
2710 % _
|
|
2711 % /
|
|
2712 % | height > 0
|
|
2713 % |
|
|
2714 % /
|
|
2715 % *- ----------
|
|
2716 % \\
|
|
2717 % |
|
|
2718 % | height < 0
|
|
2719 % \\
|
|
2720 % -
|
|
2721 /LAlt
|
|
2722 {dup 0 eq
|
|
2723 {T exch rlineto}
|
|
2724 {dup abs T lt
|
|
2725 {0.5 mul dup
|
|
2726 1 corner_RA
|
|
2727 0 corner_RD}
|
|
2728 {prepare_height
|
|
2729 1 corner_RA
|
|
2730 exch 0 exch rlineto
|
|
2731 0 corner_RD
|
|
2732 }ifelse
|
|
2733 }ifelse
|
|
2734 }def
|
|
2735
|
|
2736 %>Left Loop: height LLoop
|
|
2737 % _
|
|
2738 % /
|
|
2739 % | height > 0
|
|
2740 % |
|
|
2741 % \\
|
|
2742 % -* ----------
|
|
2743 % /
|
|
2744 % |
|
|
2745 % | height < 0
|
|
2746 % \\
|
|
2747 % -
|
|
2748 /LLoop
|
|
2749 {prepare_height
|
|
2750 3 corner_LA
|
|
2751 exch 0 exch rlineto
|
|
2752 0 corner_RD
|
|
2753 }def
|
|
2754
|
|
2755 %>Right Alternative: height RAlt
|
|
2756 % _
|
|
2757 % \\
|
|
2758 % | height > 0
|
|
2759 % |
|
|
2760 % \\
|
|
2761 % -* ----------
|
|
2762 % /
|
|
2763 % |
|
|
2764 % | height < 0
|
|
2765 % /
|
|
2766 % -
|
|
2767 /RAlt
|
|
2768 {dup 0 eq
|
|
2769 {T neg exch rlineto}
|
|
2770 {dup abs T lt
|
|
2771 {0.5 mul dup
|
|
2772 1 corner_LA
|
|
2773 0 corner_LD}
|
|
2774 {prepare_height
|
|
2775 1 corner_LA
|
|
2776 exch 0 exch rlineto
|
|
2777 0 corner_LD
|
|
2778 }ifelse
|
|
2779 }ifelse
|
|
2780 }def
|
|
2781
|
|
2782 %>Right Loop: height RLoop
|
|
2783 % _
|
|
2784 % \\
|
|
2785 % | height > 0
|
|
2786 % |
|
|
2787 % /
|
|
2788 % *- ----------
|
|
2789 % \\
|
|
2790 % |
|
|
2791 % | height < 0
|
|
2792 % /
|
|
2793 % -
|
|
2794 /RLoop
|
|
2795 {prepare_height
|
|
2796 1 corner_RA
|
|
2797 exch 0 exch rlineto
|
|
2798 0 corner_LD
|
|
2799 }def
|
|
2800
|
|
2801 % --- Terminal, Non-terminal and Special Basics
|
|
2802
|
|
2803 % string width prepare-width |- string
|
|
2804 /prepare-width
|
|
2805 {/width exch def
|
|
2806 dup stringwidth pop space add space add width exch sub 0.5 mul
|
|
2807 /w exch def
|
|
2808 }def
|
|
2809
|
|
2810 % string width begin-right
|
|
2811 /begin-right
|
|
2812 {xyo
|
|
2813 prepare-width
|
|
2814 w hT sub EL
|
|
2815 RA
|
|
2816 }def
|
|
2817
|
|
2818 % end-right
|
|
2819 /end-right
|
|
2820 {xo width add Er add yo moveto
|
|
2821 w Er add neg EL
|
|
2822 xo yo moveto
|
|
2823 }def
|
|
2824
|
|
2825 % string width begin-left
|
|
2826 /begin-left
|
|
2827 {xyo
|
|
2828 prepare-width
|
|
2829 w EL
|
|
2830 }def
|
|
2831
|
|
2832 % end-left
|
|
2833 /end-left
|
|
2834 {xo width add Er add yo moveto
|
|
2835 hT w sub Er add EL
|
|
2836 LA
|
|
2837 xo yo moveto
|
|
2838 }def
|
|
2839
|
|
2840 /ShapePath-vector
|
|
2841 [% 0 - miter
|
|
2842 {xx yy moveto
|
|
2843 xx YY lineto
|
|
2844 XX YY lineto
|
|
2845 XX yy lineto}
|
|
2846 % 1 - rounded
|
|
2847 {/half YY yy sub 0.5 mul abs def
|
|
2848 xx half add YY moveto
|
|
2849 0 0 half neg 0 half neg half neg rcurveto
|
|
2850 0 0 0 half neg half half neg rcurveto
|
|
2851 XX xx sub abs half sub half sub 0 rlineto
|
|
2852 0 0 half 0 half half rcurveto
|
|
2853 0 0 0 half half neg half rcurveto}
|
|
2854 % 2 - bevel
|
|
2855 {/quarter YY yy sub 0.25 mul abs def
|
|
2856 xx quarter add YY moveto
|
|
2857 quarter neg quarter neg rlineto
|
|
2858 0 quarter quarter add neg rlineto
|
|
2859 quarter quarter neg rlineto
|
|
2860 XX xx sub abs quarter sub quarter sub 0 rlineto
|
|
2861 quarter quarter rlineto
|
|
2862 0 quarter quarter add rlineto
|
|
2863 quarter neg quarter rlineto}
|
|
2864 ]def
|
|
2865
|
|
2866 /doShapePath
|
|
2867 {newpath
|
|
2868 ShapePath-vector shape get exec
|
|
2869 closepath
|
|
2870 }def
|
|
2871
|
|
2872 /doShapeShadow
|
|
2873 {gsave
|
|
2874 Xshadow Xshadow add Xshadow add
|
|
2875 Yshadow Yshadow add Yshadow add translate
|
|
2876 doShapePath
|
|
2877 0.9 FillGray
|
|
2878 grestore
|
|
2879 }def
|
|
2880
|
|
2881 /doShape
|
|
2882 {gsave
|
|
2883 doShapePath
|
|
2884 shapecolor FillRGB
|
|
2885 StrokeShape
|
|
2886 grestore
|
|
2887 }def
|
|
2888
|
|
2889 % string SBound |- string
|
|
2890 /SBound
|
|
2891 {/xx c dup /yy exch def
|
|
2892 FontHeight add /YY exch def def
|
|
2893 dup stringwidth pop xx add /XX exch def
|
|
2894 Effect 8 and 0 ne
|
|
2895 {/yy yy YShadow add def
|
|
2896 /XX XX XShadow add def
|
|
2897 }if
|
|
2898 }def
|
|
2899
|
|
2900 % string SBox
|
|
2901 /SBox
|
|
2902 {gsave
|
|
2903 c space sub moveto
|
|
2904 SBound
|
|
2905 /XX XX space add space add def
|
|
2906 /YY YY space add def
|
|
2907 /yy yy space sub def
|
|
2908 shadow{doShapeShadow}if
|
|
2909 doShape
|
|
2910 space Descent abs rmoveto
|
|
2911 foreground SetRGB S
|
|
2912 grestore
|
|
2913 }def
|
|
2914
|
|
2915 % --- Terminal
|
|
2916
|
|
2917 % TeRminal: string TR
|
|
2918 /TR
|
|
2919 {/Effect EffectT def
|
|
2920 /shape ShapeT def
|
|
2921 /shapecolor BackgroundT def
|
|
2922 /borderwidth BorderWidthT def
|
|
2923 /bordercolor BorderColorT def
|
|
2924 /foreground ForegroundT def
|
|
2925 /shadow ShadowT def
|
|
2926 SBox
|
|
2927 }def
|
|
2928
|
|
2929 %>Right Terminal: string width RT |- x y
|
|
2930 /RT
|
|
2931 {xyt
|
|
2932 /fT F
|
|
2933 /space SpaceT def
|
|
2934 begin-right
|
|
2935 TR
|
|
2936 end-right
|
|
2937 xt yt
|
|
2938 }def
|
|
2939
|
|
2940 %>Left Terminal: string width LT |- x y
|
|
2941 /LT
|
|
2942 {xyt
|
|
2943 /fT F
|
|
2944 /space SpaceT def
|
|
2945 begin-left
|
|
2946 TR
|
|
2947 end-left
|
|
2948 xt yt
|
|
2949 }def
|
|
2950
|
|
2951 %>Right Terminal Default: string width RTD |- x y
|
|
2952 /RTD
|
|
2953 {/-save- BorderWidthT def
|
|
2954 /BorderWidthT BorderWidthT DefaultWidth add def
|
|
2955 RT
|
|
2956 /BorderWidthT -save- def
|
|
2957 }def
|
|
2958
|
|
2959 %>Left Terminal Default: string width LTD |- x y
|
|
2960 /LTD
|
|
2961 {/-save- BorderWidthT def
|
|
2962 /BorderWidthT BorderWidthT DefaultWidth add def
|
|
2963 LT
|
|
2964 /BorderWidthT -save- def
|
|
2965 }def
|
|
2966
|
|
2967 % --- Non-Terminal
|
|
2968
|
|
2969 % Non-Terminal: string NT
|
|
2970 /NT
|
|
2971 {/Effect EffectNT def
|
|
2972 /shape ShapeNT def
|
|
2973 /shapecolor BackgroundNT def
|
|
2974 /borderwidth BorderWidthNT def
|
|
2975 /bordercolor BorderColorNT def
|
|
2976 /foreground ForegroundNT def
|
|
2977 /shadow ShadowNT def
|
|
2978 SBox
|
|
2979 }def
|
|
2980
|
|
2981 %>Right Non-Terminal: string width RNT |- x y
|
|
2982 /RNT
|
|
2983 {xyt
|
|
2984 /fNT F
|
|
2985 /space SpaceNT def
|
|
2986 begin-right
|
|
2987 NT
|
|
2988 end-right
|
|
2989 xt yt
|
|
2990 }def
|
|
2991
|
|
2992 %>Left Non-Terminal: string width LNT |- x y
|
|
2993 /LNT
|
|
2994 {xyt
|
|
2995 /fNT F
|
|
2996 /space SpaceNT def
|
|
2997 begin-left
|
|
2998 NT
|
|
2999 end-left
|
|
3000 xt yt
|
|
3001 }def
|
|
3002
|
|
3003 %>Right Non-Terminal Default: string width RNTD |- x y
|
|
3004 /RNTD
|
|
3005 {/-save- BorderWidthNT def
|
|
3006 /BorderWidthNT BorderWidthNT DefaultWidth add def
|
|
3007 RNT
|
|
3008 /BorderWidthNT -save- def
|
|
3009 }def
|
|
3010
|
|
3011 %>Left Non-Terminal Default: string width LNTD |- x y
|
|
3012 /LNTD
|
|
3013 {/-save- BorderWidthNT def
|
|
3014 /BorderWidthNT BorderWidthNT DefaultWidth add def
|
|
3015 LNT
|
|
3016 /BorderWidthNT -save- def
|
|
3017 }def
|
|
3018
|
|
3019 % --- Special
|
|
3020
|
|
3021 % SPecial: string SP
|
|
3022 /SP
|
|
3023 {/Effect EffectS def
|
|
3024 /shape ShapeS def
|
|
3025 /shapecolor BackgroundS def
|
|
3026 /borderwidth BorderWidthS def
|
|
3027 /bordercolor BorderColorS def
|
|
3028 /foreground ForegroundS def
|
|
3029 /shadow ShadowS def
|
|
3030 SBox
|
|
3031 }def
|
|
3032
|
|
3033 %>Right SPecial: string width RSP |- x y
|
|
3034 /RSP
|
|
3035 {xyt
|
|
3036 /fS F
|
|
3037 /space SpaceS def
|
|
3038 begin-right
|
|
3039 SP
|
|
3040 end-right
|
|
3041 xt yt
|
|
3042 }def
|
|
3043
|
|
3044 %>Left SPecial: string width LSP |- x y
|
|
3045 /LSP
|
|
3046 {xyt
|
|
3047 /fS F
|
|
3048 /space SpaceS def
|
|
3049 begin-left
|
|
3050 SP
|
|
3051 end-left
|
|
3052 xt yt
|
|
3053 }def
|
|
3054
|
|
3055 %>Right SPecial Default: string width RSPD |- x y
|
|
3056 /RSPD
|
|
3057 {/-save- BorderWidthS def
|
|
3058 /BorderWidthS BorderWidthS DefaultWidth add def
|
|
3059 RSP
|
|
3060 /BorderWidthS -save- def
|
|
3061 }def
|
|
3062
|
|
3063 %>Left SPecial Default: string width LSPD |- x y
|
|
3064 /LSPD
|
|
3065 {/-save- BorderWidthS def
|
|
3066 /BorderWidthS BorderWidthS DefaultWidth add def
|
|
3067 LSP
|
|
3068 /BorderWidthS -save- def
|
|
3069 }def
|
|
3070
|
|
3071 % --- Repeat and Except basics
|
|
3072
|
|
3073 /begin-direction
|
|
3074 {/w width rwidth sub 0.5 mul def
|
|
3075 width 0 rmoveto}def
|
|
3076
|
|
3077 /end-direction
|
|
3078 {gsave
|
|
3079 /xx c entry add /YY exch def def
|
|
3080 /yy YY height sub def
|
|
3081 /XX xx rwidth add def
|
|
3082 shadow{doShapeShadow}if
|
|
3083 doShape
|
|
3084 grestore
|
|
3085 }def
|
|
3086
|
|
3087 /right-direction
|
|
3088 {begin-direction
|
|
3089 w neg EL
|
|
3090 xt yt moveto
|
|
3091 w hT sub EL RA
|
|
3092 end-direction
|
|
3093 }def
|
|
3094
|
|
3095 /left-direction
|
|
3096 {begin-direction
|
|
3097 hT w sub EL LA
|
|
3098 xt yt moveto
|
|
3099 w EL
|
|
3100 end-direction
|
|
3101 }def
|
|
3102
|
|
3103 % --- Repeat
|
|
3104
|
|
3105 % entry height width rwidth begin-repeat
|
|
3106 /begin-repeat
|
|
3107 {/rwidth exch def
|
|
3108 /width exch def
|
|
3109 /height exch def
|
|
3110 /entry exch def
|
|
3111 /fR F
|
|
3112 /space SpaceR def
|
|
3113 /Effect EffectR def
|
|
3114 /shape ShapeR def
|
|
3115 /shapecolor BackgroundR def
|
|
3116 /borderwidth BorderWidthR def
|
|
3117 /bordercolor BorderColorR def
|
|
3118 /foreground ForegroundR def
|
|
3119 /shadow ShadowR def
|
|
3120 xyt
|
|
3121 }def
|
|
3122
|
|
3123 % string end-repeat |- x y
|
|
3124 /end-repeat
|
|
3125 {gsave
|
|
3126 space Descent rmoveto
|
|
3127 foreground SetRGB S
|
|
3128 c Descent sub
|
|
3129 grestore
|
|
3130 exch space add exch moveto
|
|
3131 xt yt
|
|
3132 }def
|
|
3133
|
|
3134 %>Right RePeat: string entry height width rwidth RRP |- x y
|
|
3135 /RRP{begin-repeat right-direction end-repeat}def
|
|
3136
|
|
3137 %>Left RePeat: string entry height width rwidth LRP |- x y
|
|
3138 /LRP{begin-repeat left-direction end-repeat}def
|
|
3139
|
|
3140 % --- Except
|
|
3141
|
|
3142 % entry height width rwidth begin-except
|
|
3143 /begin-except
|
|
3144 {/rwidth exch def
|
|
3145 /width exch def
|
|
3146 /height exch def
|
|
3147 /entry exch def
|
|
3148 /fE F
|
|
3149 /space SpaceE def
|
|
3150 /Effect EffectE def
|
|
3151 /shape ShapeE def
|
|
3152 /shapecolor BackgroundE def
|
|
3153 /borderwidth BorderWidthE def
|
|
3154 /bordercolor BorderColorE def
|
|
3155 /foreground ForegroundE def
|
|
3156 /shadow ShadowE def
|
|
3157 xyt
|
|
3158 }def
|
|
3159
|
|
3160 % x-width end-except |- x y
|
|
3161 /end-except
|
|
3162 {gsave
|
|
3163 space space add add Descent rmoveto
|
|
3164 (-) foreground SetRGB S
|
|
3165 grestore
|
|
3166 space 0 rmoveto
|
|
3167 xt yt
|
|
3168 }def
|
|
3169
|
|
3170 %>Right EXcept: x-width entry height width rwidth REX |- x y
|
|
3171 /REX{begin-except right-direction end-except}def
|
|
3172
|
|
3173 %>Left EXcept: x-width entry height width rwidth LEX |- x y
|
|
3174 /LEX{begin-except left-direction end-except}def
|
|
3175
|
|
3176 % --- Sequence
|
|
3177
|
|
3178 %>Beginning Of Sequence: BOS |- x y
|
|
3179 /BOS{currentpoint}bind def
|
|
3180
|
|
3181 %>End Of Sequence: x y x1 y1 EOS |- x y
|
|
3182 /EOS{pop pop}bind def
|
|
3183
|
|
3184 % --- Production
|
|
3185
|
|
3186 %>Beginning Of Production: string width height BOP |- y x
|
|
3187 /BOP
|
|
3188 {xyp
|
|
3189 neg yp add /yw exch def
|
|
3190 xp add T sub /xw exch def
|
|
3191 /Effect EffectP def
|
|
3192 /fP F ForegroundP SetRGB BackgroundP aload pop true BG S
|
|
3193 /Effect 0 def
|
|
3194 ( :) S false BG
|
|
3195 xw yw moveto
|
|
3196 hT EL RA
|
|
3197 xp yw moveto
|
|
3198 T EL
|
|
3199 yp xp
|
|
3200 }def
|
|
3201
|
|
3202 %>End Of Production: y x delta EOP
|
|
3203 /EOPH{add exch moveto}bind def % horizontal
|
|
3204 /EOPV{exch pop sub 0 exch moveto}bind def % vertical
|
|
3205
|
|
3206 % --- Empty Alternative
|
|
3207
|
|
3208 %>Empty Alternative: width EA |- x y
|
|
3209 /EA
|
|
3210 {gsave
|
|
3211 Er add 0 rlineto
|
|
3212 Stroke
|
|
3213 grestore
|
|
3214 c
|
|
3215 }def
|
|
3216
|
|
3217 % --- Alternative
|
|
3218
|
|
3219 %>AlTernative: h1 h2 ... hn n width AT |- x y
|
|
3220 /AT
|
|
3221 {xyo xo add /xw exch def
|
|
3222 xw yo moveto
|
|
3223 Er EL
|
|
3224 {xw yo moveto
|
|
3225 dup RAlt
|
|
3226 xo yo moveto
|
|
3227 LAlt}repeat
|
|
3228 xo yo
|
|
3229 }def
|
|
3230
|
|
3231 % --- Optional
|
|
3232
|
|
3233 %>OPtional: height width OP |- x y
|
|
3234 /OP
|
|
3235 {xyo
|
|
3236 T sub /ow exch def
|
|
3237 ow Er sub 0 rmoveto
|
|
3238 T Er add EL
|
|
3239 neg dup RAlt
|
|
3240 ow T sub neg EL
|
|
3241 xo yo moveto
|
|
3242 LAlt
|
|
3243 xo yo moveto
|
|
3244 T EL
|
|
3245 xo yo
|
|
3246 }def
|
|
3247
|
|
3248 % --- List Flow
|
|
3249
|
|
3250 %>One or More: height width OM |- x y
|
|
3251 /OM
|
|
3252 {xyo
|
|
3253 /ow exch def
|
|
3254 ow Er add 0 rmoveto
|
|
3255 T Er add neg EL
|
|
3256 dup RLoop
|
|
3257 xo T add yo moveto
|
|
3258 LLoop
|
|
3259 xo yo moveto
|
|
3260 T EL
|
|
3261 xo yo
|
|
3262 }def
|
|
3263
|
|
3264 %>Zero or More: h2 h1 width ZM |- x y
|
|
3265 /ZM
|
|
3266 {xyo
|
|
3267 Er add EL
|
|
3268 Er neg 0 rmoveto
|
|
3269 dup RAlt
|
|
3270 exch dup RLoop
|
|
3271 xo yo moveto
|
|
3272 exch dup LAlt
|
|
3273 exch LLoop
|
|
3274 yo add xo T add exch moveto
|
|
3275 xo yo
|
|
3276 }def
|
|
3277
|
|
3278 % === end EBNF engine
|
|
3279
|
|
3280 "
|
|
3281 "EBNF PostScript prologue")
|
|
3282
|
|
3283
|
|
3284 (defconst ebnf-eps-prologue
|
|
3285 "
|
|
3286 /#ebnf2ps#dict 230 dict def
|
|
3287 #ebnf2ps#dict begin
|
|
3288
|
|
3289 % Initiliaze variables to avoid name-conflicting with document variables.
|
|
3290 % This is the case when using `bind' operator.
|
|
3291 /-fillp- 0 def /h 0 def
|
|
3292 /-ox- 0 def /half 0 def
|
|
3293 /-oy- 0 def /height 0 def
|
|
3294 /-save- 0 def /ow 0 def
|
|
3295 /Ascent 0 def /quarter 0 def
|
|
3296 /Descent 0 def /rXX 0 def
|
|
3297 /Effect 0 def /rYY 0 def
|
|
3298 /FontHeight 0 def /rwidth 0 def
|
|
3299 /LineThickness 0 def /rxx 0 def
|
|
3300 /OverlinePosition 0 def /ryy 0 def
|
|
3301 /SpaceBackground 0 def /shadow 0 def
|
|
3302 /StrikeoutPosition 0 def /shape 0 def
|
|
3303 /UnderlinePosition 0 def /shapecolor 0 def
|
|
3304 /XBox 0 def /space 0 def
|
|
3305 /XX 0 def /st 1 string def
|
|
3306 /Xshadow 0 def /w 0 def
|
|
3307 /YBox 0 def /width 0 def
|
|
3308 /YY 0 def /xi 0 def
|
|
3309 /Yshadow 0 def /xo 0 def
|
|
3310 /arrow 0 def /xp 0 def
|
|
3311 /bg false def /xt 0 def
|
|
3312 /bgcolor 0 def /xw 0 def
|
|
3313 /bordercolor 0 def /xx 0 def
|
|
3314 /borderwidth 0 def /yi 0 def
|
|
3315 /dd 0 def /yo 0 def
|
|
3316 /entry 0 def /yp 0 def
|
|
3317 /foreground 0 def /yt 0 def
|
|
3318 /yy 0 def
|
|
3319
|
|
3320
|
|
3321 % ISOLatin1Encoding stolen from ps_init.ps in GhostScript 2.6.1.4:
|
|
3322 /ISOLatin1Encoding where
|
|
3323 {pop}
|
|
3324 {% -- The ISO Latin-1 encoding vector isn't known, so define it.
|
|
3325 % -- The first half is the same as the standard encoding,
|
|
3326 % -- except for minus instead of hyphen at code 055.
|
|
3327 /ISOLatin1Encoding
|
|
3328 StandardEncoding 0 45 getinterval aload pop
|
|
3329 /minus
|
|
3330 StandardEncoding 46 82 getinterval aload pop
|
|
3331 %*** NOTE: the following are missing in the Adobe documentation,
|
|
3332 %*** but appear in the displayed table:
|
|
3333 %*** macron at 0225, dieresis at 0230, cedilla at 0233, space at 0240.
|
|
3334 % 0200 (128)
|
|
3335 /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
|
|
3336 /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
|
|
3337 /dotlessi /grave /acute /circumflex /tilde /macron /breve /dotaccent
|
|
3338 /dieresis /.notdef /ring /cedilla /.notdef /hungarumlaut /ogonek /caron
|
|
3339 % 0240 (160)
|
|
3340 /space /exclamdown /cent /sterling
|
|
3341 /currency /yen /brokenbar /section
|
|
3342 /dieresis /copyright /ordfeminine /guillemotleft
|
|
3343 /logicalnot /hyphen /registered /macron
|
|
3344 /degree /plusminus /twosuperior /threesuperior
|
|
3345 /acute /mu /paragraph /periodcentered
|
|
3346 /cedilla /onesuperior /ordmasculine /guillemotright
|
|
3347 /onequarter /onehalf /threequarters /questiondown
|
|
3348 % 0300 (192)
|
|
3349 /Agrave /Aacute /Acircumflex /Atilde
|
|
3350 /Adieresis /Aring /AE /Ccedilla
|
|
3351 /Egrave /Eacute /Ecircumflex /Edieresis
|
|
3352 /Igrave /Iacute /Icircumflex /Idieresis
|
|
3353 /Eth /Ntilde /Ograve /Oacute
|
|
3354 /Ocircumflex /Otilde /Odieresis /multiply
|
|
3355 /Oslash /Ugrave /Uacute /Ucircumflex
|
|
3356 /Udieresis /Yacute /Thorn /germandbls
|
|
3357 % 0340 (224)
|
|
3358 /agrave /aacute /acircumflex /atilde
|
|
3359 /adieresis /aring /ae /ccedilla
|
|
3360 /egrave /eacute /ecircumflex /edieresis
|
|
3361 /igrave /iacute /icircumflex /idieresis
|
|
3362 /eth /ntilde /ograve /oacute
|
|
3363 /ocircumflex /otilde /odieresis /divide
|
|
3364 /oslash /ugrave /uacute /ucircumflex
|
|
3365 /udieresis /yacute /thorn /ydieresis
|
|
3366 256 packedarray def
|
|
3367 }ifelse
|
|
3368
|
|
3369 /reencodeFontISO %def
|
|
3370 {dup
|
|
3371 length 12 add dict % Make a new font (a new dict the same size
|
|
3372 % as the old one) with room for our new symbols.
|
|
3373
|
|
3374 begin % Make the new font the current dictionary.
|
|
3375 {1 index /FID ne
|
|
3376 {def}{pop pop}ifelse
|
|
3377 }forall % Copy each of the symbols from the old dictionary
|
|
3378 % to the new one except for the font ID.
|
|
3379
|
|
3380 currentdict /FontType get 0 ne
|
|
3381 {/Encoding ISOLatin1Encoding def}if % Override the encoding with
|
|
3382 % the ISOLatin1 encoding.
|
|
3383
|
|
3384 % Use the font's bounding box to determine the ascent, descent,
|
|
3385 % and overall height; don't forget that these values have to be
|
|
3386 % transformed using the font's matrix.
|
|
3387
|
|
3388 % ^ (x2 y2)
|
|
3389 % | |
|
|
3390 % | v
|
|
3391 % | +----+ - -
|
|
3392 % | | | ^
|
|
3393 % | | | | Ascent (usually > 0)
|
|
3394 % | | | |
|
|
3395 % (0 0) -> +--+----+-------->
|
|
3396 % | | |
|
|
3397 % | | v Descent (usually < 0)
|
|
3398 % (x1 y1) --> +----+ - -
|
|
3399
|
|
3400 currentdict /FontType get 0 ne
|
|
3401 {/FontBBox load aload pop % -- x1 y1 x2 y2
|
|
3402 FontMatrix transform /Ascent exch def pop
|
|
3403 FontMatrix transform /Descent exch def pop}
|
|
3404 {/PrimaryFont FDepVector 0 get def
|
|
3405 PrimaryFont /FontBBox get aload pop
|
|
3406 PrimaryFont /FontMatrix get transform /Ascent exch def pop
|
|
3407 PrimaryFont /FontMatrix get transform /Descent exch def pop
|
|
3408 }ifelse
|
|
3409
|
|
3410 /FontHeight Ascent Descent sub def % use `sub' because descent < 0
|
|
3411
|
|
3412 % Define these in case they're not in the FontInfo
|
|
3413 % (also, here they're easier to get to).
|
|
3414 /UnderlinePosition Descent 0.70 mul def
|
|
3415 /OverlinePosition Descent UnderlinePosition sub Ascent add def
|
|
3416 /StrikeoutPosition Ascent 0.30 mul def
|
|
3417 /LineThickness FontHeight 0.05 mul def
|
|
3418 /Xshadow FontHeight 0.08 mul def
|
|
3419 /Yshadow FontHeight -0.09 mul def
|
|
3420 /SpaceBackground Descent neg UnderlinePosition add def
|
|
3421 /XBox Descent neg def
|
|
3422 /YBox LineThickness 0.7 mul def
|
|
3423
|
|
3424 currentdict % Leave the new font on the stack
|
|
3425 end % Stop using the font as the current dictionary
|
|
3426 definefont % Put the font into the font dictionary
|
|
3427 pop % Discard the returned font
|
|
3428 }bind def
|
|
3429
|
|
3430 % Font definition
|
|
3431 /DefFont{findfont exch scalefont reencodeFontISO}def
|
|
3432
|
|
3433 % Font selection
|
|
3434 /F
|
|
3435 {findfont
|
|
3436 dup /Ascent get /Ascent exch def
|
|
3437 dup /Descent get /Descent exch def
|
|
3438 dup /FontHeight get /FontHeight exch def
|
|
3439 dup /UnderlinePosition get /UnderlinePosition exch def
|
|
3440 dup /OverlinePosition get /OverlinePosition exch def
|
|
3441 dup /StrikeoutPosition get /StrikeoutPosition exch def
|
|
3442 dup /LineThickness get /LineThickness exch def
|
|
3443 dup /Xshadow get /Xshadow exch def
|
|
3444 dup /Yshadow get /Yshadow exch def
|
|
3445 dup /SpaceBackground get /SpaceBackground exch def
|
|
3446 dup /XBox get /XBox exch def
|
|
3447 dup /YBox get /YBox exch def
|
|
3448 setfont
|
|
3449 }def
|
|
3450
|
|
3451 /BG
|
|
3452 {dup /bg exch def
|
|
3453 {mark 4 1 roll ]}
|
|
3454 {[ 1.0 1.0 1.0 ]}
|
|
3455 ifelse
|
|
3456 /bgcolor exch def
|
|
3457 }def
|
|
3458
|
|
3459 % stack: --
|
|
3460 /FillBgColor{bgcolor aload pop setrgbcolor fill}bind def
|
|
3461
|
|
3462 % stack: fill-or-not lower-x lower-y upper-x upper-y |- --
|
|
3463 /doRect
|
|
3464 {/rYY exch def
|
|
3465 /rXX exch def
|
|
3466 /ryy exch def
|
|
3467 /rxx exch def
|
|
3468 gsave
|
|
3469 newpath
|
|
3470 rXX rYY moveto
|
|
3471 rxx rYY lineto
|
|
3472 rxx ryy lineto
|
|
3473 rXX ryy lineto
|
|
3474 closepath
|
|
3475 % top of stack: fill-or-not
|
|
3476 {FillBgColor}
|
|
3477 {LineThickness setlinewidth stroke}
|
|
3478 ifelse
|
|
3479 grestore
|
|
3480 }bind def
|
|
3481
|
|
3482 % stack: string fill-or-not |- --
|
|
3483 /doOutline
|
|
3484 {/-fillp- exch def
|
|
3485 /-ox- currentpoint /-oy- exch def def
|
|
3486 gsave
|
|
3487 LineThickness setlinewidth
|
|
3488 {st 0 3 -1 roll put
|
|
3489 st dup true charpath
|
|
3490 -fillp- {gsave FillBgColor grestore}if
|
|
3491 stroke stringwidth
|
|
3492 -oy- add /-oy- exch def
|
|
3493 -ox- add /-ox- exch def
|
|
3494 -ox- -oy- moveto
|
|
3495 }forall
|
|
3496 grestore
|
|
3497 -ox- -oy- moveto
|
|
3498 }bind def
|
|
3499
|
|
3500 % stack: fill-or-not delta |- --
|
|
3501 /doBox
|
|
3502 {/dd exch def
|
|
3503 xx XBox sub dd sub yy YBox sub dd sub
|
|
3504 XX XBox add dd add YY YBox add dd add
|
|
3505 doRect
|
|
3506 }bind def
|
|
3507
|
|
3508 % stack: string |- --
|
|
3509 /doShadow
|
|
3510 {gsave
|
|
3511 Xshadow Yshadow rmoveto
|
|
3512 false doOutline
|
|
3513 grestore
|
|
3514 }bind def
|
|
3515
|
|
3516 % stack: position |- --
|
|
3517 /Hline
|
|
3518 {currentpoint exch pop add dup
|
|
3519 gsave
|
|
3520 newpath
|
|
3521 xx exch moveto
|
|
3522 XX exch lineto
|
|
3523 closepath
|
|
3524 LineThickness setlinewidth stroke
|
|
3525 grestore
|
|
3526 }bind def
|
|
3527
|
|
3528 % stack: string |- --
|
|
3529 % effect: 1 - underline 2 - strikeout 4 - overline
|
|
3530 % 8 - shadow 16 - box 32 - outline
|
|
3531 /S
|
|
3532 {/xx currentpoint dup Descent add /yy exch def
|
|
3533 Ascent add /YY exch def def
|
|
3534 dup stringwidth pop xx add /XX exch def
|
|
3535 Effect 8 and 0 ne
|
|
3536 {/yy yy Yshadow add def
|
|
3537 /XX XX Xshadow add def
|
|
3538 }if
|
|
3539 bg
|
|
3540 {true
|
|
3541 Effect 16 and 0 ne
|
|
3542 {SpaceBackground doBox}
|
|
3543 {xx yy XX YY doRect}
|
|
3544 ifelse
|
|
3545 }if % background
|
|
3546 Effect 16 and 0 ne{false 0 doBox}if % box
|
|
3547 Effect 8 and 0 ne{dup doShadow}if % shadow
|
|
3548 Effect 32 and 0 ne
|
|
3549 {true doOutline} % outline
|
|
3550 {show} % normal text
|
|
3551 ifelse
|
|
3552 Effect 1 and 0 ne{UnderlinePosition Hline}if % underline
|
|
3553 Effect 2 and 0 ne{StrikeoutPosition Hline}if % strikeout
|
|
3554 Effect 4 and 0 ne{OverlinePosition Hline}if % overline
|
|
3555 }bind def
|
|
3556
|
|
3557 "
|
|
3558 "EBNF EPS prologue")
|
|
3559
|
|
3560
|
|
3561 (defconst ebnf-eps-begin
|
|
3562 "
|
|
3563 end
|
|
3564
|
|
3565 % x y #ebnf2ps#begin
|
|
3566 /#ebnf2ps#begin
|
|
3567 {#ebnf2ps#dict begin /#ebnf2ps#save save def
|
|
3568 moveto false BG 0.0 0.0 0.0 setrgbcolor}def
|
|
3569
|
|
3570 /#ebnf2ps#end{showpage #ebnf2ps#save restore end}def
|
|
3571
|
|
3572 %%EndPrologue
|
|
3573 "
|
|
3574 "EBNF EPS begin")
|
|
3575
|
|
3576
|
|
3577 (defconst ebnf-eps-end
|
|
3578 "#ebnf2ps#end
|
|
3579 %%EOF
|
|
3580 "
|
|
3581 "EBNF EPS end")
|
|
3582
|
|
3583
|
|
3584 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
3585 ;; Formatting
|
|
3586
|
|
3587
|
|
3588 (defvar ebnf-format-float "%1.3f")
|
|
3589
|
|
3590
|
|
3591 (defun ebnf-format-float (&rest floats)
|
|
3592 (mapconcat
|
|
3593 #'(lambda (float)
|
|
3594 (format ebnf-format-float float))
|
|
3595 floats
|
|
3596 " "))
|
|
3597
|
|
3598
|
|
3599 (defun ebnf-format-color (format-str color default)
|
|
3600 (let* ((the-color (or color default))
|
|
3601 (rgb (mapcar 'ps-color-value (ps-color-values the-color))))
|
|
3602 (format format-str
|
|
3603 (concat "["
|
|
3604 (ebnf-format-float (nth 0 rgb) (nth 1 rgb) (nth 2 rgb))
|
|
3605 "]")
|
|
3606 the-color)))
|
|
3607
|
|
3608
|
|
3609 (defvar ebnf-message-float "%3.2f")
|
|
3610
|
|
3611
|
|
3612 (defsubst ebnf-message-float (format-str value)
|
|
3613 (message format-str
|
|
3614 (format ebnf-message-float value)))
|
|
3615
|
|
3616
|
|
3617 (defsubst ebnf-message-info (messag)
|
|
3618 (message "%s...%3d%%"
|
|
3619 messag
|
|
3620 (round (/ (* (setq ebnf-nprod (1+ ebnf-nprod)) 100.0) ebnf-total))))
|
|
3621
|
|
3622
|
|
3623 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
3624 ;; Macros
|
|
3625
|
|
3626
|
|
3627 (defmacro ebnf-node-kind (vec &optional value)
|
|
3628 (if value
|
|
3629 `(aset ,vec 0 ,value)
|
|
3630 `(aref ,vec 0)))
|
|
3631
|
|
3632
|
|
3633 (defmacro ebnf-node-width-func (node width)
|
|
3634 `(funcall (aref ,node 1) ,node ,width))
|
|
3635
|
|
3636
|
|
3637 (defmacro ebnf-node-dimension-func (node &optional value)
|
|
3638 (if value
|
|
3639 `(aset ,node 2 ,value)
|
|
3640 `(funcall (aref ,node 2) ,node)))
|
|
3641
|
|
3642
|
|
3643 (defmacro ebnf-node-entry (vec &optional value)
|
|
3644 (if value
|
|
3645 `(aset ,vec 3 ,value)
|
|
3646 `(aref ,vec 3)))
|
|
3647
|
|
3648
|
|
3649 (defmacro ebnf-node-height (vec &optional value)
|
|
3650 (if value
|
|
3651 `(aset ,vec 4 ,value)
|
|
3652 `(aref ,vec 4)))
|
|
3653
|
|
3654
|
|
3655 (defmacro ebnf-node-width (vec &optional value)
|
|
3656 (if value
|
|
3657 `(aset ,vec 5 ,value)
|
|
3658 `(aref ,vec 5)))
|
|
3659
|
|
3660
|
|
3661 (defmacro ebnf-node-name (vec)
|
|
3662 `(aref ,vec 6))
|
|
3663
|
|
3664
|
|
3665 (defmacro ebnf-node-list (vec &optional value)
|
|
3666 (if value
|
|
3667 `(aset ,vec 6 ,value)
|
|
3668 `(aref ,vec 6)))
|
|
3669
|
|
3670
|
|
3671 (defmacro ebnf-node-default (vec)
|
|
3672 `(aref ,vec 7))
|
|
3673
|
|
3674
|
|
3675 (defmacro ebnf-node-production (vec &optional value)
|
|
3676 (if value
|
|
3677 `(aset ,vec 7 ,value)
|
|
3678 `(aref ,vec 7)))
|
|
3679
|
|
3680
|
|
3681 (defmacro ebnf-node-separator (vec &optional value)
|
|
3682 (if value
|
|
3683 `(aset ,vec 7 ,value)
|
|
3684 `(aref ,vec 7)))
|
|
3685
|
|
3686
|
|
3687 (defmacro ebnf-node-action (vec &optional value)
|
|
3688 (if value
|
|
3689 `(aset ,vec 8 ,value)
|
|
3690 `(aref ,vec 8)))
|
|
3691
|
|
3692
|
|
3693 (defmacro ebnf-node-generation (node)
|
|
3694 `(funcall (ebnf-node-kind ,node) ,node))
|
|
3695
|
|
3696
|
|
3697 (defmacro ebnf-max-width (prod)
|
|
3698 `(max (ebnf-node-width ,prod)
|
|
3699 (+ (* (length (ebnf-node-name ,prod))
|
|
3700 ebnf-font-width-P)
|
|
3701 ebnf-production-horizontal-space)))
|
|
3702
|
|
3703
|
|
3704 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
3705 ;; PostScript generation
|
|
3706
|
|
3707
|
|
3708 (defun ebnf-generate-eps (ebnf-tree)
|
|
3709 (let* ((ps-color-p (and ebnf-color-p (ps-color-device)))
|
|
3710 (ps-print-color-scale (if ps-color-p
|
|
3711 (float (car (ps-color-values "white")))
|
|
3712 1.0))
|
|
3713 (ebnf-total (length ebnf-tree))
|
|
3714 (ebnf-nprod 0)
|
|
3715 (old-ps-output (symbol-function 'ps-output))
|
|
3716 (old-ps-output-string (symbol-function 'ps-output-string))
|
|
3717 (eps-buffer (get-buffer-create ebnf-eps-buffer-name))
|
|
3718 ebnf-debug-ps error-msg horizontal
|
|
3719 prod prod-name prod-width prod-height prod-list file-list)
|
|
3720 ;; redefines `ps-output' and `ps-output-string'
|
|
3721 (defalias 'ps-output 'ebnf-eps-output)
|
|
3722 (defalias 'ps-output-string 'ps-output-string-prim)
|
|
3723 ;; generate EPS file
|
|
3724 (save-excursion
|
|
3725 (condition-case data
|
|
3726 (progn
|
|
3727 (while ebnf-tree
|
|
3728 (setq prod (car ebnf-tree)
|
|
3729 prod-name (ebnf-node-name prod)
|
|
3730 prod-width (ebnf-max-width prod)
|
|
3731 prod-height (ebnf-node-height prod)
|
|
3732 horizontal (memq (ebnf-node-action prod) ebnf-action-list))
|
|
3733 ;; generate production in EPS buffer
|
|
3734 (save-excursion
|
|
3735 (set-buffer eps-buffer)
|
|
3736 (setq ebnf-eps-upper-x 0.0
|
|
3737 ebnf-eps-upper-y 0.0
|
|
3738 ebnf-eps-max-width prod-width
|
|
3739 ebnf-eps-max-height prod-height)
|
|
3740 (ebnf-generate-production prod))
|
|
3741 (if (setq prod-list (cdr (assoc prod-name
|
|
3742 ebnf-eps-production-list)))
|
|
3743 ;; insert EPS buffer in all buffer associated with production
|
|
3744 (ebnf-eps-production-list prod-list 'file-list horizontal
|
|
3745 prod-width prod-height eps-buffer)
|
|
3746 ;; write EPS file for production
|
|
3747 (ebnf-eps-finish-and-write eps-buffer
|
|
3748 (ebnf-eps-filename prod-name)))
|
|
3749 ;; prepare for next loop
|
|
3750 (save-excursion
|
|
3751 (set-buffer eps-buffer)
|
|
3752 (erase-buffer))
|
|
3753 (setq ebnf-tree (cdr ebnf-tree)))
|
|
3754 ;; write and kill temporary buffers
|
|
3755 (ebnf-eps-write-kill-temp file-list t)
|
|
3756 (setq file-list nil))
|
|
3757 ;; handler
|
|
3758 ((quit error)
|
|
3759 (setq error-msg (error-message-string data)))))
|
|
3760 ;; restore `ps-output' and `ps-output-string'
|
|
3761 (defalias 'ps-output old-ps-output)
|
|
3762 (defalias 'ps-output-string old-ps-output-string)
|
|
3763 ;; kill temporary buffers
|
|
3764 (kill-buffer eps-buffer)
|
|
3765 (ebnf-eps-write-kill-temp file-list nil)
|
|
3766 (and error-msg (error error-msg))
|
|
3767 (message " ")))
|
|
3768
|
|
3769
|
|
3770 ;; write and kill temporary buffers
|
|
3771 (defun ebnf-eps-write-kill-temp (file-list write-p)
|
|
3772 (while file-list
|
|
3773 (let ((buffer (get-buffer (concat " *" (car file-list) "*"))))
|
|
3774 (when buffer
|
|
3775 (and write-p
|
|
3776 (ebnf-eps-finish-and-write buffer (car file-list)))
|
|
3777 (kill-buffer buffer)))
|
|
3778 (setq file-list (cdr file-list))))
|
|
3779
|
|
3780
|
|
3781 ;; insert EPS buffer in all buffer associated with production
|
|
3782 (defun ebnf-eps-production-list (prod-list file-list-sym horizontal
|
|
3783 prod-width prod-height eps-buffer)
|
|
3784 (while prod-list
|
|
3785 (add-to-list file-list-sym (car prod-list))
|
|
3786 (save-excursion
|
|
3787 (set-buffer (get-buffer-create (concat " *" (car prod-list) "*")))
|
|
3788 (goto-char (point-max))
|
|
3789 (cond
|
|
3790 ;; first production
|
|
3791 ((zerop (buffer-size))
|
|
3792 (setq ebnf-eps-upper-x 0.0
|
|
3793 ebnf-eps-upper-y 0.0
|
|
3794 ebnf-eps-max-width prod-width
|
|
3795 ebnf-eps-max-height prod-height))
|
|
3796 ;; horizontal
|
|
3797 (horizontal
|
|
3798 (ebnf-eop-horizontal ebnf-eps-prod-width)
|
|
3799 (setq ebnf-eps-max-width (+ ebnf-eps-max-width
|
|
3800 ebnf-production-horizontal-space
|
|
3801 prod-width)
|
|
3802 ebnf-eps-max-height (max ebnf-eps-max-height prod-height)))
|
|
3803 ;; vertical
|
|
3804 (t
|
|
3805 (ebnf-eop-vertical ebnf-eps-max-height)
|
|
3806 (setq ebnf-eps-upper-x (max ebnf-eps-upper-x ebnf-eps-max-width)
|
|
3807 ebnf-eps-upper-y (if (zerop ebnf-eps-upper-y)
|
|
3808 ebnf-eps-max-height
|
|
3809 (+ ebnf-eps-upper-y
|
|
3810 ebnf-production-vertical-space
|
|
3811 ebnf-eps-max-height))
|
|
3812 ebnf-eps-max-width prod-width
|
|
3813 ebnf-eps-max-height prod-height))
|
|
3814 )
|
|
3815 (setq ebnf-eps-prod-width prod-width)
|
|
3816 (insert-buffer eps-buffer))
|
|
3817 (setq prod-list (cdr prod-list))))
|
|
3818
|
|
3819
|
|
3820 (defun ebnf-generate (ebnf-tree)
|
|
3821 (let* ((ps-color-p (and ebnf-color-p (ps-color-device)))
|
|
3822 (ps-print-color-scale (if ps-color-p
|
|
3823 (float (car (ps-color-values "white")))
|
|
3824 1.0))
|
|
3825 ps-zebra-stripes ps-line-number ps-razzle-dazzle
|
|
3826 ps-print-hook
|
|
3827 ps-print-begin-sheet-hook
|
|
3828 ps-print-begin-page-hook
|
|
3829 ps-print-begin-column-hook)
|
|
3830 (ps-generate (current-buffer) (point-min) (point-max)
|
|
3831 'ebnf-generate-postscript)))
|
|
3832
|
|
3833
|
|
3834 (defvar ebnf-tree nil)
|
|
3835 (defvar ebnf-direction "R")
|
|
3836 (defvar ebnf-total 0)
|
|
3837 (defvar ebnf-nprod 0)
|
|
3838
|
|
3839
|
|
3840 (defun ebnf-generate-postscript (from to)
|
|
3841 (ebnf-begin-file)
|
|
3842 (if ebnf-horizontal-max-height
|
|
3843 (ebnf-generate-with-max-height)
|
|
3844 (ebnf-generate-without-max-height))
|
|
3845 (message " "))
|
|
3846
|
|
3847
|
|
3848 (defun ebnf-generate-with-max-height ()
|
|
3849 (let ((ebnf-total (length ebnf-tree))
|
|
3850 (ebnf-nprod 0)
|
|
3851 next-line max-height prod the-width)
|
|
3852 (while ebnf-tree
|
|
3853 ;; find next line point
|
|
3854 (setq next-line ebnf-tree
|
|
3855 prod (car ebnf-tree)
|
|
3856 max-height (ebnf-node-height prod))
|
|
3857 (ebnf-begin-line prod (ebnf-max-width prod))
|
|
3858 (while (and (setq next-line (cdr next-line))
|
|
3859 (setq prod (car next-line))
|
|
3860 (memq (ebnf-node-action prod) ebnf-action-list)
|
|
3861 (setq the-width (ebnf-max-width prod))
|
|
3862 (<= the-width ps-width-remaining))
|
|
3863 (setq max-height (max max-height (ebnf-node-height prod))
|
|
3864 ps-width-remaining (- ps-width-remaining
|
|
3865 (+ the-width
|
|
3866 ebnf-production-horizontal-space))))
|
|
3867 ;; generate current line
|
|
3868 (ebnf-newline max-height)
|
|
3869 (setq prod (car ebnf-tree))
|
|
3870 (ebnf-generate-production prod)
|
|
3871 (while (not (eq (setq ebnf-tree (cdr ebnf-tree)) next-line))
|
|
3872 (ebnf-eop-horizontal (ebnf-max-width prod))
|
|
3873 (setq prod (car ebnf-tree))
|
|
3874 (ebnf-generate-production prod))
|
|
3875 (ebnf-eop-vertical max-height))))
|
|
3876
|
|
3877
|
|
3878 (defun ebnf-generate-without-max-height ()
|
|
3879 (let ((ebnf-total (length ebnf-tree))
|
|
3880 (ebnf-nprod 0)
|
|
3881 max-height prod bef-width cur-width)
|
|
3882 (while ebnf-tree
|
|
3883 ;; generate current line
|
|
3884 (setq prod (car ebnf-tree)
|
|
3885 max-height (ebnf-node-height prod)
|
|
3886 bef-width (ebnf-max-width prod))
|
|
3887 (ebnf-begin-line prod bef-width)
|
|
3888 (ebnf-generate-production prod)
|
|
3889 (while (and (setq ebnf-tree (cdr ebnf-tree))
|
|
3890 (setq prod (car ebnf-tree))
|
|
3891 (memq (ebnf-node-action prod) ebnf-action-list)
|
|
3892 (setq cur-width (ebnf-max-width prod))
|
|
3893 (<= cur-width ps-width-remaining)
|
|
3894 (<= (ebnf-node-height prod) ps-height-remaining))
|
|
3895 (ebnf-eop-horizontal bef-width)
|
|
3896 (ebnf-generate-production prod)
|
|
3897 (setq bef-width cur-width
|
|
3898 max-height (max max-height (ebnf-node-height prod))
|
|
3899 ps-width-remaining (- ps-width-remaining
|
|
3900 (+ cur-width
|
|
3901 ebnf-production-horizontal-space))))
|
|
3902 (ebnf-eop-vertical max-height)
|
|
3903 ;; prepare next line
|
|
3904 (ebnf-newline max-height))))
|
|
3905
|
|
3906
|
|
3907 (defun ebnf-begin-line (prod width)
|
|
3908 (and (or (eq (ebnf-node-action prod) 'form-feed)
|
|
3909 (> (ebnf-node-height prod) ps-height-remaining))
|
|
3910 (ebnf-new-page))
|
|
3911 (setq ps-width-remaining (- ps-width-remaining
|
|
3912 (+ width
|
|
3913 ebnf-production-horizontal-space))))
|
|
3914
|
|
3915
|
|
3916 (defun ebnf-newline (height)
|
|
3917 (and (> height ps-height-remaining)
|
|
3918 (ebnf-new-page))
|
|
3919 (setq ps-width-remaining ps-print-width
|
|
3920 ps-height-remaining (- ps-height-remaining
|
|
3921 (+ height
|
|
3922 ebnf-production-vertical-space))))
|
|
3923
|
|
3924
|
|
3925 ;; [production width-fun dim-fun entry height width name production action]
|
|
3926 (defun ebnf-generate-production (production)
|
|
3927 (ebnf-message-info "Generating")
|
|
3928 (run-hooks 'ebnf-production-hook)
|
|
3929 (ps-output-string (ebnf-node-name production))
|
|
3930 (ps-output " "
|
|
3931 (ebnf-format-float
|
|
3932 (ebnf-node-width production)
|
|
3933 (+ ebnf-basic-height
|
|
3934 (ebnf-node-entry (ebnf-node-production production))))
|
|
3935 " BOP\n")
|
|
3936 (ebnf-node-generation (ebnf-node-production production))
|
|
3937 (ps-output "EOS\n"))
|
|
3938
|
|
3939
|
|
3940 ;; [alternative width-fun dim-fun entry height width list]
|
|
3941 (defun ebnf-generate-alternative (alternative)
|
|
3942 (let ((alt (ebnf-node-list alternative))
|
|
3943 (entry (ebnf-node-entry alternative))
|
|
3944 (nlist 0)
|
|
3945 alt-height alt-entry)
|
|
3946 (while alt
|
|
3947 (ps-output (ebnf-format-float (- entry (ebnf-node-entry (car alt))))
|
|
3948 " ")
|
|
3949 (setq entry (- entry (ebnf-node-height (car alt)) ebnf-vertical-space)
|
|
3950 nlist (1+ nlist)
|
|
3951 alt (cdr alt)))
|
|
3952 (ps-output (format "%d " nlist)
|
|
3953 (ebnf-format-float (ebnf-node-width alternative))
|
|
3954 " AT\n")
|
|
3955 (setq alt (ebnf-node-list alternative))
|
|
3956 (when alt
|
|
3957 (ebnf-node-generation (car alt))
|
|
3958 (setq alt-height (- (ebnf-node-height (car alt))
|
|
3959 (ebnf-node-entry (car alt)))))
|
|
3960 (while (setq alt (cdr alt))
|
|
3961 (setq alt-entry (ebnf-node-entry (car alt)))
|
|
3962 (ebnf-vertical-movement
|
|
3963 (- (+ alt-height ebnf-vertical-space alt-entry)))
|
|
3964 (ebnf-node-generation (car alt))
|
|
3965 (setq alt-height (- (ebnf-node-height (car alt)) alt-entry))))
|
|
3966 (ps-output "EOS\n"))
|
|
3967
|
|
3968
|
|
3969 ;; [sequence width-fun dim-fun entry height width list]
|
|
3970 (defun ebnf-generate-sequence (sequence)
|
|
3971 (ps-output "BOS\n")
|
|
3972 (let ((seq (ebnf-node-list sequence))
|
|
3973 seq-width)
|
|
3974 (when seq
|
|
3975 (ebnf-node-generation (car seq))
|
|
3976 (setq seq-width (ebnf-node-width (car seq))))
|
|
3977 (while (setq seq (cdr seq))
|
|
3978 (ebnf-horizontal-movement seq-width)
|
|
3979 (ebnf-node-generation (car seq))
|
|
3980 (setq seq-width (ebnf-node-width (car seq)))))
|
|
3981 (ps-output "EOS\n"))
|
|
3982
|
|
3983
|
|
3984 ;; [terminal width-fun dim-fun entry height width name]
|
|
3985 (defun ebnf-generate-terminal (terminal)
|
|
3986 (ebnf-gen-terminal terminal "T"))
|
|
3987
|
|
3988
|
|
3989 ;; [non-terminal width-fun dim-fun entry height width name]
|
|
3990 (defun ebnf-generate-non-terminal (non-terminal)
|
|
3991 (ebnf-gen-terminal non-terminal "NT"))
|
|
3992
|
|
3993
|
|
3994 ;; [empty width-fun dim-fun entry height width]
|
|
3995 (defun ebnf-generate-empty (empty)
|
|
3996 (ebnf-empty-alternative (ebnf-node-width empty)))
|
|
3997
|
|
3998
|
|
3999 ;; [optional width-fun dim-fun entry height width element]
|
|
4000 (defun ebnf-generate-optional (optional)
|
|
4001 (let ((the-optional (ebnf-node-list optional)))
|
|
4002 (ps-output (ebnf-format-float
|
|
4003 (+ (- (ebnf-node-height the-optional)
|
|
4004 (ebnf-node-entry optional))
|
|
4005 ebnf-vertical-space)
|
|
4006 (ebnf-node-width optional))
|
|
4007 " OP\n")
|
|
4008 (ebnf-node-generation the-optional)
|
|
4009 (ps-output "EOS\n")))
|
|
4010
|
|
4011
|
|
4012 ;; [one-or-more width-fun dim-fun entry height width element separator]
|
|
4013 (defun ebnf-generate-one-or-more (one-or-more)
|
|
4014 (let* ((width (ebnf-node-width one-or-more))
|
|
4015 (sep (ebnf-node-separator one-or-more))
|
|
4016 (entry (- (ebnf-node-entry one-or-more)
|
|
4017 (if sep
|
|
4018 (ebnf-node-entry sep)
|
|
4019 0))))
|
|
4020 (ps-output (ebnf-format-float entry width)
|
|
4021 " OM\n")
|
|
4022 (ebnf-node-generation (ebnf-node-list one-or-more))
|
|
4023 (ebnf-vertical-movement entry)
|
|
4024 (if sep
|
|
4025 (let ((ebnf-direction "L"))
|
|
4026 (ebnf-node-generation sep))
|
|
4027 (ebnf-empty-alternative (- width ebnf-horizontal-space))))
|
|
4028 (ps-output "EOS\n"))
|
|
4029
|
|
4030
|
|
4031 ;; [zero-or-more width-fun dim-fun entry height width element separator]
|
|
4032 (defun ebnf-generate-zero-or-more (zero-or-more)
|
|
4033 (let* ((width (ebnf-node-width zero-or-more))
|
|
4034 (node-list (ebnf-node-list zero-or-more))
|
|
4035 (list-entry (ebnf-node-entry node-list))
|
|
4036 (node-sep (ebnf-node-separator zero-or-more))
|
|
4037 (entry (+ list-entry
|
|
4038 ebnf-vertical-space
|
|
4039 (if node-sep
|
|
4040 (- (ebnf-node-height node-sep)
|
|
4041 (ebnf-node-entry node-sep))
|
|
4042 0))))
|
|
4043 (ps-output (ebnf-format-float entry
|
|
4044 (+ (- (ebnf-node-height node-list)
|
|
4045 list-entry)
|
|
4046 ebnf-vertical-space)
|
|
4047 width)
|
|
4048 " ZM\n")
|
|
4049 (ebnf-node-generation (ebnf-node-list zero-or-more))
|
|
4050 (ebnf-vertical-movement entry)
|
|
4051 (if (ebnf-node-separator zero-or-more)
|
|
4052 (let ((ebnf-direction "L"))
|
|
4053 (ebnf-node-generation (ebnf-node-separator zero-or-more)))
|
|
4054 (ebnf-empty-alternative (- width ebnf-horizontal-space))))
|
|
4055 (ps-output "EOS\n"))
|
|
4056
|
|
4057
|
|
4058 ;; [special width-fun dim-fun entry height width name]
|
|
4059 (defun ebnf-generate-special (special)
|
|
4060 (ebnf-gen-terminal special "SP"))
|
|
4061
|
|
4062
|
|
4063 ;; [repeat width-fun dim-fun entry height width times element]
|
|
4064 (defun ebnf-generate-repeat (repeat)
|
|
4065 (let ((times (ebnf-node-name repeat))
|
|
4066 (element (ebnf-node-separator repeat)))
|
|
4067 (ps-output-string times)
|
|
4068 (ps-output " "
|
|
4069 (ebnf-format-float
|
|
4070 (ebnf-node-entry repeat)
|
|
4071 (ebnf-node-height repeat)
|
|
4072 (ebnf-node-width repeat)
|
|
4073 (if element
|
|
4074 (+ (ebnf-node-width element)
|
|
4075 ebnf-space-R ebnf-space-R ebnf-space-R
|
|
4076 (* (length times) ebnf-font-width-R))
|
|
4077 0.0))
|
|
4078 " " ebnf-direction "RP\n")
|
|
4079 (and element
|
|
4080 (ebnf-node-generation element)))
|
|
4081 (ps-output "EOS\n"))
|
|
4082
|
|
4083
|
|
4084 ;; [except width-fun dim-fun entry height width element element]
|
|
4085 (defun ebnf-generate-except (except)
|
|
4086 (let* ((element (ebnf-node-list except))
|
|
4087 (exception (ebnf-node-separator except))
|
|
4088 (width (ebnf-node-width element)))
|
|
4089 (ps-output (ebnf-format-float
|
|
4090 width
|
|
4091 (ebnf-node-entry except)
|
|
4092 (ebnf-node-height except)
|
|
4093 (ebnf-node-width except)
|
|
4094 (+ width
|
|
4095 ebnf-space-E ebnf-space-E ebnf-space-E
|
|
4096 ebnf-font-width-E
|
|
4097 (if exception
|
|
4098 (+ (ebnf-node-width exception) ebnf-space-E)
|
|
4099 0.0)))
|
|
4100 " " ebnf-direction "EX\n")
|
|
4101 (ebnf-node-generation (ebnf-node-list except))
|
|
4102 (when exception
|
|
4103 (ebnf-horizontal-movement (+ width ebnf-space-E
|
|
4104 ebnf-font-width-E ebnf-space-E))
|
|
4105 (ebnf-node-generation exception)))
|
|
4106 (ps-output "EOS\n"))
|
|
4107
|
|
4108
|
|
4109 (defun ebnf-gen-terminal (node code)
|
|
4110 (ps-output-string (ebnf-node-name node))
|
|
4111 (ps-output " " (ebnf-format-float (ebnf-node-width node))
|
|
4112 " " ebnf-direction code
|
|
4113 (if (ebnf-node-default node)
|
|
4114 "D\n"
|
|
4115 "\n")))
|
|
4116
|
|
4117
|
|
4118 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
4119 ;; Internal functions
|
|
4120
|
|
4121
|
|
4122 (defvar ebnf-map-name
|
|
4123 (let ((map (make-vector 256 ?\_)))
|
|
4124 (mapcar #'(lambda (char)
|
|
4125 (aset map char char))
|
|
4126 (concat "#$%&+-.0123456789=?@~"
|
|
4127 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
4128 "abcdefghijklmnopqrstuvwxyz"))
|
|
4129 map))
|
|
4130
|
|
4131
|
|
4132 (defun ebnf-eps-filename (str)
|
|
4133 (let* ((len (length str))
|
|
4134 (stri 0)
|
|
4135 (new (make-string len ?\ )))
|
|
4136 (while (< stri len)
|
|
4137 (aset new stri (aref ebnf-map-name (aref str stri)))
|
|
4138 (setq stri (1+ stri)))
|
|
4139 (concat ebnf-eps-prefix new ".eps")))
|
|
4140
|
|
4141
|
|
4142 (defun ebnf-eps-output (&rest args)
|
|
4143 (while args
|
|
4144 (insert (car args))
|
|
4145 (setq args (cdr args))))
|
|
4146
|
|
4147
|
|
4148 (defun ebnf-generate-region (from to gen-func)
|
|
4149 (run-hooks 'ebnf-hook)
|
|
4150 (let ((ebnf-limit (max from to))
|
|
4151 the-point)
|
|
4152 (save-excursion
|
|
4153 (save-restriction
|
|
4154 (save-match-data
|
|
4155 (condition-case data
|
|
4156 (let ((tree (ebnf-parse-and-sort (min from to))))
|
|
4157 (when gen-func
|
|
4158 (funcall gen-func
|
|
4159 (ebnf-dimensions
|
|
4160 (ebnf-optimize
|
|
4161 (ebnf-eliminate-empty-rules tree))))))
|
|
4162 ;; handler
|
|
4163 ((quit error)
|
|
4164 (ding)
|
|
4165 (setq the-point (max (1- (point)) (point-min)))
|
|
4166 (message (error-message-string data)))))))
|
|
4167 (cond
|
|
4168 (the-point
|
|
4169 (goto-char the-point))
|
|
4170 (gen-func
|
|
4171 nil)
|
|
4172 (t
|
|
4173 (message "EBNF syntatic analysis: NO ERRORS.")))))
|
|
4174
|
|
4175
|
|
4176 (defun ebnf-parse-and-sort (start)
|
|
4177 (ebnf-begin-job)
|
|
4178 (let ((tree (funcall ebnf-parser-func start)))
|
|
4179 (if ebnf-sort-production
|
|
4180 (progn
|
|
4181 (message "Sorting...")
|
|
4182 (sort tree
|
|
4183 (if (eq ebnf-sort-production 'ascending)
|
|
4184 'ebnf-sorter-ascending
|
|
4185 'ebnf-sorter-descending)))
|
|
4186 (nreverse tree))))
|
|
4187
|
|
4188
|
|
4189 (defun ebnf-sorter-ascending (first second)
|
|
4190 (string< (ebnf-node-name first)
|
|
4191 (ebnf-node-name second)))
|
|
4192
|
|
4193
|
|
4194 (defun ebnf-sorter-descending (first second)
|
|
4195 (string< (ebnf-node-name second)
|
|
4196 (ebnf-node-name first)))
|
|
4197
|
|
4198
|
|
4199 (defun ebnf-empty-alternative (width)
|
|
4200 (ps-output (ebnf-format-float width) " EA\n"))
|
|
4201
|
|
4202
|
|
4203 (defun ebnf-vertical-movement (height)
|
|
4204 (ps-output (ebnf-format-float height) " vm\n"))
|
|
4205
|
|
4206
|
|
4207 (defun ebnf-horizontal-movement (width)
|
|
4208 (ps-output (ebnf-format-float width) " hm\n"))
|
|
4209
|
|
4210
|
|
4211 (defun ebnf-entry (height)
|
|
4212 (* height ebnf-entry-percentage))
|
|
4213
|
|
4214
|
|
4215 (defun ebnf-eop-vertical (height)
|
|
4216 (ps-output (ebnf-format-float (+ height ebnf-production-vertical-space))
|
|
4217 " EOPV\n\n"))
|
|
4218
|
|
4219
|
|
4220 (defun ebnf-eop-horizontal (width)
|
|
4221 (ps-output (ebnf-format-float (+ width ebnf-production-horizontal-space))
|
|
4222 " EOPH\n\n"))
|
|
4223
|
|
4224
|
|
4225 (defun ebnf-new-page ()
|
|
4226 (when (< ps-height-remaining ps-print-height)
|
|
4227 (run-hooks 'ebnf-page-hook)
|
|
4228 (ps-next-page)
|
|
4229 (ps-output "\n")))
|
|
4230
|
|
4231
|
|
4232 (defsubst ebnf-font-size (font) (nth 0 font))
|
|
4233 (defsubst ebnf-font-name (font) (nth 1 font))
|
|
4234 (defsubst ebnf-font-foreground (font) (nth 2 font))
|
|
4235 (defsubst ebnf-font-background (font) (nth 3 font))
|
|
4236 (defsubst ebnf-font-list (font) (nthcdr 4 font))
|
|
4237 (defsubst ebnf-font-attributes (font)
|
|
4238 (lsh (ps-extension-bit (cdr font)) -2))
|
|
4239
|
|
4240
|
|
4241 (defconst ebnf-font-name-select
|
|
4242 (vector 'normal 'bold 'italic 'bold-italic))
|
|
4243
|
|
4244
|
|
4245 (defun ebnf-font-name-select (font)
|
|
4246 (let* ((font-list (ebnf-font-list font))
|
|
4247 (font-index (+ (if (memq 'bold font-list) 1 0)
|
|
4248 (if (memq 'italic font-list) 2 0)))
|
|
4249 (name (ebnf-font-name font))
|
|
4250 (database (cdr (assoc name ps-font-info-database)))
|
|
4251 (info-list (or (cdr (assoc 'fonts database))
|
|
4252 (error "Invalid font: %s" name))))
|
|
4253 (or (cdr (assoc (aref ebnf-font-name-select font-index)
|
|
4254 info-list))
|
|
4255 (error "Invalid attributes for font %s" name))))
|
|
4256
|
|
4257
|
|
4258 (defun ebnf-font-select (font select)
|
|
4259 (let* ((name (ebnf-font-name font))
|
|
4260 (database (cdr (assoc name ps-font-info-database)))
|
|
4261 (size (cdr (assoc 'size database)))
|
|
4262 (base (cdr (assoc select database))))
|
|
4263 (if (and size base)
|
|
4264 (/ (* (ebnf-font-size font) base)
|
|
4265 size)
|
|
4266 (error "Invalid font: %s" name))))
|
|
4267
|
|
4268
|
|
4269 (defsubst ebnf-font-width (font)
|
|
4270 (ebnf-font-select font 'avg-char-width))
|
|
4271 (defsubst ebnf-font-height (font)
|
|
4272 (ebnf-font-select font 'line-height))
|
|
4273
|
|
4274
|
|
4275 (defun ebnf-begin-job ()
|
|
4276 (ps-printing-region nil)
|
|
4277 (if ebnf-use-float-format
|
|
4278 (setq ebnf-format-float "%1.3f"
|
|
4279 ebnf-message-float "%3.2f")
|
|
4280 (setq ebnf-format-float "%s"
|
|
4281 ebnf-message-float "%s"))
|
|
4282 (ebnf-otz-initialize)
|
|
4283 ;; to avoid compilation gripes when calling autoloaded functions
|
|
4284 (funcall (cond ((eq ebnf-syntax 'iso-ebnf)
|
|
4285 (setq ebnf-parser-func 'ebnf-iso-parser)
|
|
4286 'ebnf-iso-initialize)
|
|
4287 ((eq ebnf-syntax 'yacc)
|
|
4288 (setq ebnf-parser-func 'ebnf-yac-parser)
|
|
4289 'ebnf-yac-initialize)
|
|
4290 (t
|
|
4291 (setq ebnf-parser-func 'ebnf-bnf-parser)
|
|
4292 'ebnf-bnf-initialize)))
|
|
4293 (and ebnf-terminal-regexp ; ensures that it's a string or nil
|
|
4294 (not (stringp ebnf-terminal-regexp))
|
|
4295 (setq ebnf-terminal-regexp nil))
|
|
4296 (or (and ebnf-eps-prefix ; ensures that it's a string
|
|
4297 (stringp ebnf-eps-prefix))
|
|
4298 (setq ebnf-eps-prefix "ebnf--"))
|
|
4299 (setq ebnf-entry-percentage ; ensures value between 0.0 and 1.0
|
|
4300 (min (max ebnf-entry-percentage 0.0) 1.0)
|
|
4301 ebnf-action-list (if ebnf-horizontal-orientation
|
|
4302 '(nil keep-line)
|
|
4303 '(keep-line))
|
|
4304 ebnf-settings nil
|
|
4305 ebnf-fonts-required nil
|
|
4306 ebnf-action nil
|
|
4307 ebnf-default-p nil
|
|
4308 ebnf-eps-context nil
|
|
4309 ebnf-eps-production-list nil
|
|
4310 ebnf-eps-upper-x 0.0
|
|
4311 ebnf-eps-upper-y 0.0
|
|
4312 ebnf-font-height-P (ebnf-font-height ebnf-production-font)
|
|
4313 ebnf-font-height-T (ebnf-font-height ebnf-terminal-font)
|
|
4314 ebnf-font-height-NT (ebnf-font-height ebnf-non-terminal-font)
|
|
4315 ebnf-font-height-S (ebnf-font-height ebnf-special-font)
|
|
4316 ebnf-font-height-E (ebnf-font-height ebnf-except-font)
|
|
4317 ebnf-font-height-R (ebnf-font-height ebnf-repeat-font)
|
|
4318 ebnf-font-width-P (ebnf-font-width ebnf-production-font)
|
|
4319 ebnf-font-width-T (ebnf-font-width ebnf-terminal-font)
|
|
4320 ebnf-font-width-NT (ebnf-font-width ebnf-non-terminal-font)
|
|
4321 ebnf-font-width-S (ebnf-font-width ebnf-special-font)
|
|
4322 ebnf-font-width-E (ebnf-font-width ebnf-except-font)
|
|
4323 ebnf-font-width-R (ebnf-font-width ebnf-repeat-font)
|
|
4324 ebnf-space-T (* ebnf-font-height-T 0.5)
|
|
4325 ebnf-space-NT (* ebnf-font-height-NT 0.5)
|
|
4326 ebnf-space-S (* ebnf-font-height-S 0.5)
|
|
4327 ebnf-space-E (* ebnf-font-height-E 0.5)
|
|
4328 ebnf-space-R (* ebnf-font-height-R 0.5))
|
|
4329 (let ((basic (+ ebnf-font-height-T ebnf-font-height-NT)))
|
|
4330 (setq ebnf-basic-width (* basic 0.5)
|
|
4331 ebnf-horizontal-space (+ basic basic)
|
|
4332 ebnf-basic-height ebnf-basic-width
|
|
4333 ebnf-vertical-space ebnf-basic-width)
|
|
4334 ;; ensures value is greater than zero
|
|
4335 (or (and (numberp ebnf-production-horizontal-space)
|
|
4336 (> ebnf-production-horizontal-space 0.0))
|
|
4337 (setq ebnf-production-horizontal-space basic))
|
|
4338 ;; ensures value is greater than zero
|
|
4339 (or (and (numberp ebnf-production-vertical-space)
|
|
4340 (> ebnf-production-vertical-space 0.0))
|
|
4341 (setq ebnf-production-vertical-space basic))))
|
|
4342
|
|
4343
|
|
4344 (defsubst ebnf-shape-value (sym alist)
|
|
4345 (or (cdr (assq sym alist)) 0))
|
|
4346
|
|
4347
|
|
4348 (defsubst ebnf-boolean (value)
|
|
4349 (if value "true" "false"))
|
|
4350
|
|
4351
|
|
4352 (defun ebnf-begin-file ()
|
|
4353 (ps-flush-output)
|
|
4354 (save-excursion
|
|
4355 (set-buffer ps-spool-buffer)
|
|
4356 (goto-char (point-min))
|
|
4357 (and (search-forward "%%Creator: " nil t)
|
|
4358 (not (search-forward "& ebnf2ps v"
|
|
4359 (save-excursion (end-of-line) (point))
|
|
4360 t))
|
|
4361 (progn
|
|
4362 ;; adjust creator comment
|
|
4363 (end-of-line)
|
|
4364 (backward-char)
|
|
4365 (insert " & ebnf2ps v" ebnf-version)
|
|
4366 ;; insert ebnf settings & engine
|
|
4367 (goto-char (point-max))
|
|
4368 (search-backward "\n%%EndPrologue\n")
|
|
4369 (ebnf-insert-ebnf-prologue)
|
|
4370 (ps-output "\n")))))
|
|
4371
|
|
4372
|
|
4373 (defun ebnf-eps-finish-and-write (buffer filename)
|
|
4374 (save-excursion
|
|
4375 (set-buffer buffer)
|
|
4376 (setq ebnf-eps-upper-x (max ebnf-eps-upper-x ebnf-eps-max-width)
|
|
4377 ebnf-eps-upper-y (if (zerop ebnf-eps-upper-y)
|
|
4378 ebnf-eps-max-height
|
|
4379 (+ ebnf-eps-upper-y
|
|
4380 ebnf-production-vertical-space
|
|
4381 ebnf-eps-max-height)))
|
|
4382 ;; prologue
|
|
4383 (goto-char (point-min))
|
|
4384 (insert
|
|
4385 "%!PS-Adobe-3.0 EPSF-3.0"
|
|
4386 "\n%%BoundingBox: 0 0 "
|
|
4387 (format "%d %d" (1+ ebnf-eps-upper-x) (1+ ebnf-eps-upper-y))
|
|
4388 "\n%%Title: " filename
|
|
4389 "\n%%CreationDate: " (time-stamp-hh:mm:ss) " " (time-stamp-mon-dd-yyyy)
|
|
4390 "\n%%Creator: " (user-full-name) " (using ebnf2ps v" ebnf-version ")"
|
|
4391 "\n%%DocumentNeededResources: font "
|
|
4392 (or ebnf-fonts-required
|
|
4393 (setq ebnf-fonts-required
|
|
4394 (let ((fonts (ps-remove-duplicates
|
|
4395 (mapcar 'ebnf-font-name-select
|
|
4396 (list ebnf-production-font
|
|
4397 ebnf-terminal-font
|
|
4398 ebnf-non-terminal-font
|
|
4399 ebnf-special-font
|
|
4400 ebnf-except-font
|
|
4401 ebnf-repeat-font)))))
|
|
4402 (concat (car fonts)
|
|
4403 (and (cdr fonts) "\n%%+ font ")
|
|
4404 (mapconcat 'identity (cdr fonts) "\n%%+ font ")))))
|
|
4405 "\n%%Pages: 0\n%%EndComments\n\n%%BeginPrologue\n"
|
|
4406 ebnf-eps-prologue)
|
|
4407 (ebnf-insert-ebnf-prologue)
|
|
4408 (insert ebnf-eps-begin
|
|
4409 "\n0 " (ebnf-format-float
|
|
4410 (- ebnf-eps-upper-y (* ebnf-font-height-P 0.7)))
|
|
4411 " #ebnf2ps#begin\n")
|
|
4412 ;; epilogue
|
|
4413 (goto-char (point-max))
|
|
4414 (insert ebnf-eps-end)
|
|
4415 ;; write file
|
|
4416 (message "Saving...")
|
|
4417 (setq filename (expand-file-name filename))
|
|
4418 (let ((coding-system-for-write 'raw-text-unix))
|
|
4419 (write-region (point-min) (point-max) filename))
|
|
4420 (message "Wrote %s" filename)))
|
|
4421
|
|
4422
|
|
4423 (defun ebnf-insert-ebnf-prologue ()
|
|
4424 (insert
|
|
4425 (or ebnf-settings
|
|
4426 (setq ebnf-settings
|
|
4427 (concat
|
|
4428 "\n\n% === begin EBNF settings\n\n"
|
|
4429 ;; production
|
|
4430 (format "/fP %s /%s DefFont\n"
|
|
4431 (ebnf-format-float (ebnf-font-size ebnf-production-font))
|
|
4432 (ebnf-font-name-select ebnf-production-font))
|
|
4433 (ebnf-format-color "/ForegroundP %s def %% %s\n"
|
|
4434 (ebnf-font-foreground ebnf-production-font)
|
|
4435 "Black")
|
|
4436 (ebnf-format-color "/BackgroundP %s def %% %s\n"
|
|
4437 (ebnf-font-background ebnf-production-font)
|
|
4438 "White")
|
|
4439 (format "/EffectP %d def\n"
|
|
4440 (ebnf-font-attributes ebnf-production-font))
|
|
4441 ;; terminal
|
|
4442 (format "/fT %s /%s DefFont\n"
|
|
4443 (ebnf-format-float (ebnf-font-size ebnf-terminal-font))
|
|
4444 (ebnf-font-name-select ebnf-terminal-font))
|
|
4445 (ebnf-format-color "/ForegroundT %s def %% %s\n"
|
|
4446 (ebnf-font-foreground ebnf-terminal-font)
|
|
4447 "Black")
|
|
4448 (ebnf-format-color "/BackgroundT %s def %% %s\n"
|
|
4449 (ebnf-font-background ebnf-terminal-font)
|
|
4450 "White")
|
|
4451 (format "/EffectT %d def\n"
|
|
4452 (ebnf-font-attributes ebnf-terminal-font))
|
|
4453 (format "/BorderWidthT %s def\n"
|
|
4454 (ebnf-format-float ebnf-terminal-border-width))
|
|
4455 (ebnf-format-color "/BorderColorT %s def %% %s\n"
|
|
4456 ebnf-terminal-border-color
|
|
4457 "Black")
|
|
4458 (format "/ShapeT %d def\n"
|
|
4459 (ebnf-shape-value ebnf-terminal-shape
|
|
4460 ebnf-terminal-shape-alist))
|
|
4461 (format "/ShadowT %s def\n"
|
|
4462 (ebnf-boolean ebnf-terminal-shadow))
|
|
4463 ;; non-terminal
|
|
4464 (format "/fNT %s /%s DefFont\n"
|
|
4465 (ebnf-format-float
|
|
4466 (ebnf-font-size ebnf-non-terminal-font))
|
|
4467 (ebnf-font-name-select ebnf-non-terminal-font))
|
|
4468 (ebnf-format-color "/ForegroundNT %s def %% %s\n"
|
|
4469 (ebnf-font-foreground ebnf-non-terminal-font)
|
|
4470 "Black")
|
|
4471 (ebnf-format-color "/BackgroundNT %s def %% %s\n"
|
|
4472 (ebnf-font-background ebnf-non-terminal-font)
|
|
4473 "White")
|
|
4474 (format "/EffectNT %d def\n"
|
|
4475 (ebnf-font-attributes ebnf-non-terminal-font))
|
|
4476 (format "/BorderWidthNT %s def\n"
|
|
4477 (ebnf-format-float ebnf-non-terminal-border-width))
|
|
4478 (ebnf-format-color "/BorderColorNT %s def %% %s\n"
|
|
4479 ebnf-non-terminal-border-color
|
|
4480 "Black")
|
|
4481 (format "/ShapeNT %d def\n"
|
|
4482 (ebnf-shape-value ebnf-non-terminal-shape
|
|
4483 ebnf-terminal-shape-alist))
|
|
4484 (format "/ShadowNT %s def\n"
|
|
4485 (ebnf-boolean ebnf-non-terminal-shadow))
|
|
4486 ;; special
|
|
4487 (format "/fS %s /%s DefFont\n"
|
|
4488 (ebnf-format-float (ebnf-font-size ebnf-special-font))
|
|
4489 (ebnf-font-name-select ebnf-special-font))
|
|
4490 (ebnf-format-color "/ForegroundS %s def %% %s\n"
|
|
4491 (ebnf-font-foreground ebnf-special-font)
|
|
4492 "Black")
|
|
4493 (ebnf-format-color "/BackgroundS %s def %% %s\n"
|
|
4494 (ebnf-font-background ebnf-special-font)
|
|
4495 "Gray95")
|
|
4496 (format "/EffectS %d def\n"
|
|
4497 (ebnf-font-attributes ebnf-special-font))
|
|
4498 (format "/BorderWidthS %s def\n"
|
|
4499 (ebnf-format-float ebnf-special-border-width))
|
|
4500 (ebnf-format-color "/BorderColorS %s def %% %s\n"
|
|
4501 ebnf-special-border-color
|
|
4502 "Black")
|
|
4503 (format "/ShapeS %d def\n"
|
|
4504 (ebnf-shape-value ebnf-special-shape
|
|
4505 ebnf-terminal-shape-alist))
|
|
4506 (format "/ShadowS %s def\n"
|
|
4507 (ebnf-boolean ebnf-special-shadow))
|
|
4508 ;; except
|
|
4509 (format "/fE %s /%s DefFont\n"
|
|
4510 (ebnf-format-float (ebnf-font-size ebnf-except-font))
|
|
4511 (ebnf-font-name-select ebnf-except-font))
|
|
4512 (ebnf-format-color "/ForegroundE %s def %% %s\n"
|
|
4513 (ebnf-font-foreground ebnf-except-font)
|
|
4514 "Black")
|
|
4515 (ebnf-format-color "/BackgroundE %s def %% %s\n"
|
|
4516 (ebnf-font-background ebnf-except-font)
|
|
4517 "Gray90")
|
|
4518 (format "/EffectE %d def\n"
|
|
4519 (ebnf-font-attributes ebnf-except-font))
|
|
4520 (format "/BorderWidthE %s def\n"
|
|
4521 (ebnf-format-float ebnf-except-border-width))
|
|
4522 (ebnf-format-color "/BorderColorE %s def %% %s\n"
|
|
4523 ebnf-except-border-color
|
|
4524 "Black")
|
|
4525 (format "/ShapeE %d def\n"
|
|
4526 (ebnf-shape-value ebnf-except-shape
|
|
4527 ebnf-terminal-shape-alist))
|
|
4528 (format "/ShadowE %s def\n"
|
|
4529 (ebnf-boolean ebnf-except-shadow))
|
|
4530 ;; repeat
|
|
4531 (format "/fR %s /%s DefFont\n"
|
|
4532 (ebnf-format-float (ebnf-font-size ebnf-repeat-font))
|
|
4533 (ebnf-font-name-select ebnf-repeat-font))
|
|
4534 (ebnf-format-color "/ForegroundR %s def %% %s\n"
|
|
4535 (ebnf-font-foreground ebnf-repeat-font)
|
|
4536 "Black")
|
|
4537 (ebnf-format-color "/BackgroundR %s def %% %s\n"
|
|
4538 (ebnf-font-background ebnf-repeat-font)
|
|
4539 "Gray85")
|
|
4540 (format "/EffectR %d def\n"
|
|
4541 (ebnf-font-attributes ebnf-repeat-font))
|
|
4542 (format "/BorderWidthR %s def\n"
|
|
4543 (ebnf-format-float ebnf-repeat-border-width))
|
|
4544 (ebnf-format-color "/BorderColorR %s def %% %s\n"
|
|
4545 ebnf-repeat-border-color
|
|
4546 "Black")
|
|
4547 (format "/ShapeR %d def\n"
|
|
4548 (ebnf-shape-value ebnf-repeat-shape
|
|
4549 ebnf-terminal-shape-alist))
|
|
4550 (format "/ShadowR %s def\n"
|
|
4551 (ebnf-boolean ebnf-repeat-shadow))
|
|
4552 ;; miscellaneous
|
|
4553 (format "/DefaultWidth %s def\n"
|
|
4554 (ebnf-format-float ebnf-default-width))
|
|
4555 (format "/LineWidth %s def\n"
|
|
4556 (ebnf-format-float ebnf-line-width))
|
|
4557 (ebnf-format-color "/LineColor %s def %% %s\n"
|
|
4558 ebnf-line-color
|
|
4559 "Black")
|
|
4560 (format "/ArrowShape %d def\n"
|
|
4561 (ebnf-shape-value ebnf-arrow-shape
|
|
4562 ebnf-arrow-shape-alist))
|
|
4563 (format "/ChartShape %d def\n"
|
|
4564 (ebnf-shape-value ebnf-chart-shape
|
|
4565 ebnf-terminal-shape-alist))
|
|
4566 (format "/UserArrow{%s}def\n"
|
|
4567 (ebnf-user-arrow ebnf-user-arrow))
|
|
4568 "\n% === end EBNF settings\n\n"
|
|
4569 (and ebnf-debug-ps ebnf-debug))))
|
|
4570 ebnf-prologue))
|
|
4571
|
|
4572
|
|
4573 (defun ebnf-user-arrow (user-arrow)
|
|
4574 "Return a user arrow shape from USER-ARROW (a PostScript code).
|
|
4575
|
|
4576 This function is only called when `ebnf-arrow-shape' is set to symbol `user'.
|
|
4577
|
|
4578 If is a string, should be a PostScript procedure body.
|
|
4579 If is a variable symbol, should contain a string.
|
|
4580 If is a function symbol, it is called and the result is applied recursively.
|
|
4581 If is a cons and car is a function symbol, it is called as:
|
|
4582 (funcall (car cons) (cdr cons))
|
|
4583 and the result is applied recursively.
|
|
4584 If is a cons and car is not a function symbol, it is applied recursively on
|
|
4585 car and cdr, and the results are concatened as:
|
|
4586 (concat RESULT-FROM-CAR \" \" RESULT-FROM-CDR)
|
|
4587 If is a list and car is a function symbol, it is called as:
|
|
4588 (apply (car list) (cdr list))
|
|
4589 and the result is applied recursively.
|
|
4590 If is a list and car is not a function symbol, it is applied recursively on
|
|
4591 each element and the resulting list is concatened as:
|
|
4592 (mapconcat 'identity RESULTING-LIST \" \")
|
|
4593 Otherwise, it is treated as an empty string."
|
|
4594 (cond
|
|
4595 ((null user-arrow)
|
|
4596 "")
|
|
4597 ((stringp user-arrow)
|
|
4598 user-arrow)
|
|
4599 ((and (symbolp user-arrow) (fboundp user-arrow))
|
|
4600 (ebnf-user-arrow (funcall user-arrow)))
|
|
4601 ((and (symbolp user-arrow) (boundp user-arrow))
|
|
4602 (ebnf-user-arrow (symbol-value user-arrow)))
|
|
4603 ((consp user-arrow)
|
|
4604 (if (and (symbolp (car user-arrow)) (fboundp (car user-arrow)))
|
|
4605 (ebnf-user-arrow (funcall (car user-arrow) (cdr user-arrow)))
|
|
4606 (concat (ebnf-user-arrow (car user-arrow))
|
|
4607 " "
|
|
4608 (ebnf-user-arrow (cdr user-arrow)))))
|
|
4609 ((listp user-arrow)
|
|
4610 (if (and (symbolp (car user-arrow))
|
|
4611 (fboundp (car user-arrow)))
|
|
4612 (ebnf-user-arrow (apply (car user-arrow) (cdr user-arrow)))
|
|
4613 (mapconcat 'ebnf-user-arrow user-arrow " ")))
|
|
4614 (t
|
|
4615 "")
|
|
4616 ))
|
|
4617
|
|
4618
|
|
4619 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
4620 ;; Adjusting dimensions
|
|
4621
|
|
4622
|
|
4623 (defun ebnf-dimensions (tree)
|
|
4624 (let ((ebnf-total (length tree))
|
|
4625 (ebnf-nprod 0))
|
|
4626 (mapcar 'ebnf-production-dimension tree))
|
|
4627 tree)
|
|
4628
|
|
4629
|
|
4630 ;; [empty width-fun dim-fun entry height width]
|
|
4631 ;;(defun ebnf-empty-dimension (empty)
|
|
4632 ;; )
|
|
4633
|
|
4634
|
|
4635 ;; [production width-fun dim-fun entry height width name production action]
|
|
4636 (defun ebnf-production-dimension (production)
|
|
4637 (ebnf-message-info "Calculating dimensions")
|
|
4638 (ebnf-node-dimension-func (ebnf-node-production production))
|
|
4639 (let* ((prod (ebnf-node-production production))
|
|
4640 (height (+ ebnf-font-height-P
|
|
4641 ebnf-basic-height
|
|
4642 (ebnf-node-height prod))))
|
|
4643 (ebnf-node-entry production height)
|
|
4644 (ebnf-node-height production height)
|
|
4645 (ebnf-node-width production (+ (ebnf-node-width prod)
|
|
4646 ebnf-horizontal-space))))
|
|
4647
|
|
4648
|
|
4649 ;; [terminal width-fun dim-fun entry height width name]
|
|
4650 (defun ebnf-terminal-dimension (terminal)
|
|
4651 (ebnf-terminal-dimension1 terminal
|
|
4652 ebnf-font-height-T
|
|
4653 ebnf-font-width-T
|
|
4654 ebnf-space-T))
|
|
4655
|
|
4656
|
|
4657 ;; [non-terminal width-fun dim-fun entry height width name]
|
|
4658 (defun ebnf-non-terminal-dimension (non-terminal)
|
|
4659 (ebnf-terminal-dimension1 non-terminal
|
|
4660 ebnf-font-height-NT
|
|
4661 ebnf-font-width-NT
|
|
4662 ebnf-space-NT))
|
|
4663
|
|
4664
|
|
4665 ;; [special width-fun dim-fun entry height width name]
|
|
4666 (defun ebnf-special-dimension (special)
|
|
4667 (ebnf-terminal-dimension1 special
|
|
4668 ebnf-font-height-S
|
|
4669 ebnf-font-width-S
|
|
4670 ebnf-space-S))
|
|
4671
|
|
4672
|
|
4673 (defun ebnf-terminal-dimension1 (node font-height font-width space)
|
|
4674 (let ((height (+ space font-height space))
|
|
4675 (len (length (ebnf-node-name node))))
|
|
4676 (ebnf-node-entry node (* height 0.5))
|
|
4677 (ebnf-node-height node height)
|
|
4678 (ebnf-node-width node (+ ebnf-basic-width space
|
|
4679 (* len font-width)
|
|
4680 space ebnf-basic-width))))
|
|
4681
|
|
4682
|
|
4683 (defconst ebnf-null-vector (vector t t t 0.0 0.0 0.0))
|
|
4684
|
|
4685
|
|
4686 ;; [repeat width-fun dim-fun entry height width times element]
|
|
4687 (defun ebnf-repeat-dimension (repeat)
|
|
4688 (let ((times (ebnf-node-name repeat))
|
|
4689 (element (ebnf-node-separator repeat)))
|
|
4690 (if element
|
|
4691 (ebnf-node-dimension-func element)
|
|
4692 (setq element ebnf-null-vector))
|
|
4693 (ebnf-node-entry repeat (+ (ebnf-node-entry element)
|
|
4694 ebnf-space-R))
|
|
4695 (ebnf-node-height repeat (+ (max (ebnf-node-height element)
|
|
4696 ebnf-font-height-S)
|
|
4697 ebnf-space-R ebnf-space-R))
|
|
4698 (ebnf-node-width repeat (+ (ebnf-node-width element)
|
|
4699 ebnf-space-R ebnf-space-R ebnf-space-R
|
|
4700 ebnf-horizontal-space
|
|
4701 (* (length times) ebnf-font-width-R)))))
|
|
4702
|
|
4703
|
|
4704 ;; [except width-fun dim-fun entry height width element element]
|
|
4705 (defun ebnf-except-dimension (except)
|
|
4706 (let ((factor (ebnf-node-list except))
|
|
4707 (element (ebnf-node-separator except)))
|
|
4708 (ebnf-node-dimension-func factor)
|
|
4709 (if element
|
|
4710 (ebnf-node-dimension-func element)
|
|
4711 (setq element ebnf-null-vector))
|
|
4712 (ebnf-node-entry except (+ (max (ebnf-node-entry factor)
|
|
4713 (ebnf-node-entry element))
|
|
4714 ebnf-space-E))
|
|
4715 (ebnf-node-height except (+ (max (ebnf-node-height factor)
|
|
4716 (ebnf-node-height element))
|
|
4717 ebnf-space-E ebnf-space-E))
|
|
4718 (ebnf-node-width except (+ (ebnf-node-width factor)
|
|
4719 (ebnf-node-width element)
|
|
4720 ebnf-space-E ebnf-space-E
|
|
4721 ebnf-space-E ebnf-space-E
|
|
4722 ebnf-font-width-E
|
|
4723 ebnf-horizontal-space))))
|
|
4724
|
|
4725
|
|
4726 ;; [alternative width-fun dim-fun entry height width list]
|
|
4727 (defun ebnf-alternative-dimension (alternative)
|
|
4728 (let ((body (ebnf-node-list alternative))
|
|
4729 (lis (ebnf-node-list alternative)))
|
|
4730 (while lis
|
|
4731 (ebnf-node-dimension-func (car lis))
|
|
4732 (setq lis (cdr lis)))
|
|
4733 (let ((height 0.0)
|
|
4734 (width 0.0)
|
|
4735 (alt body)
|
|
4736 (tail (car (last body)))
|
|
4737 (entry (ebnf-node-entry (car body)))
|
|
4738 node)
|
|
4739 (while alt
|
|
4740 (setq node (car alt)
|
|
4741 alt (cdr alt)
|
|
4742 height (+ (ebnf-node-height node) height)
|
|
4743 width (max (ebnf-node-width node) width)))
|
|
4744 (ebnf-adjust-width body width)
|
|
4745 (setq height (+ height (* (1- (length body)) ebnf-vertical-space)))
|
|
4746 (ebnf-node-entry alternative (+ entry
|
|
4747 (ebnf-entry
|
|
4748 (- height entry
|
|
4749 (- (ebnf-node-height tail)
|
|
4750 (ebnf-node-entry tail))))))
|
|
4751 (ebnf-node-height alternative height)
|
|
4752 (ebnf-node-width alternative (+ width ebnf-horizontal-space))
|
|
4753 (ebnf-node-list alternative body))))
|
|
4754
|
|
4755
|
|
4756 ;; [optional width-fun dim-fun entry height width element]
|
|
4757 (defun ebnf-optional-dimension (optional)
|
|
4758 (let ((body (ebnf-node-list optional)))
|
|
4759 (ebnf-node-dimension-func body)
|
|
4760 (ebnf-node-entry optional (ebnf-node-entry body))
|
|
4761 (ebnf-node-height optional (+ (ebnf-node-height body)
|
|
4762 ebnf-vertical-space))
|
|
4763 (ebnf-node-width optional (+ (ebnf-node-width body)
|
|
4764 ebnf-horizontal-space))))
|
|
4765
|
|
4766
|
|
4767 ;; [one-or-more width-fun dim-fun entry height width element separator]
|
|
4768 (defun ebnf-one-or-more-dimension (or-more)
|
|
4769 (let ((list-part (ebnf-node-list or-more))
|
|
4770 (sep-part (ebnf-node-separator or-more)))
|
|
4771 (ebnf-node-dimension-func list-part)
|
|
4772 (and sep-part
|
|
4773 (ebnf-node-dimension-func sep-part))
|
|
4774 (let ((height (+ (if sep-part
|
|
4775 (ebnf-node-height sep-part)
|
|
4776 0.0)
|
|
4777 ebnf-vertical-space
|
|
4778 (ebnf-node-height list-part)))
|
|
4779 (width (max (if sep-part
|
|
4780 (ebnf-node-width sep-part)
|
|
4781 0.0)
|
|
4782 (ebnf-node-width list-part))))
|
|
4783 (when sep-part
|
|
4784 (ebnf-adjust-width list-part width)
|
|
4785 (ebnf-adjust-width sep-part width))
|
|
4786 (ebnf-node-entry or-more (+ (- height (ebnf-node-height list-part))
|
|
4787 (ebnf-node-entry list-part)))
|
|
4788 (ebnf-node-height or-more height)
|
|
4789 (ebnf-node-width or-more (+ width ebnf-horizontal-space)))))
|
|
4790
|
|
4791
|
|
4792 ;; [zero-or-more width-fun dim-fun entry height width element separator]
|
|
4793 (defun ebnf-zero-or-more-dimension (or-more)
|
|
4794 (let ((list-part (ebnf-node-list or-more))
|
|
4795 (sep-part (ebnf-node-separator or-more)))
|
|
4796 (ebnf-node-dimension-func list-part)
|
|
4797 (and sep-part
|
|
4798 (ebnf-node-dimension-func sep-part))
|
|
4799 (let ((height (+ (if sep-part
|
|
4800 (ebnf-node-height sep-part)
|
|
4801 0.0)
|
|
4802 ebnf-vertical-space
|
|
4803 (ebnf-node-height list-part)
|
|
4804 ebnf-vertical-space))
|
|
4805 (width (max (if sep-part
|
|
4806 (ebnf-node-width sep-part)
|
|
4807 0.0)
|
|
4808 (ebnf-node-width list-part))))
|
|
4809 (when sep-part
|
|
4810 (ebnf-adjust-width list-part width)
|
|
4811 (ebnf-adjust-width sep-part width))
|
|
4812 (ebnf-node-entry or-more height)
|
|
4813 (ebnf-node-height or-more height)
|
|
4814 (ebnf-node-width or-more (+ width ebnf-horizontal-space)))))
|
|
4815
|
|
4816
|
|
4817 ;; [sequence width-fun dim-fun entry height width list]
|
|
4818 (defun ebnf-sequence-dimension (sequence)
|
|
4819 (let ((above 0.0)
|
|
4820 (below 0.0)
|
|
4821 (width 0.0)
|
|
4822 (lis (ebnf-node-list sequence))
|
|
4823 entry node)
|
|
4824 (while lis
|
|
4825 (setq node (car lis)
|
|
4826 lis (cdr lis))
|
|
4827 (ebnf-node-dimension-func node)
|
|
4828 (setq entry (ebnf-node-entry node)
|
|
4829 above (max above entry)
|
|
4830 below (max below (- (ebnf-node-height node) entry))
|
|
4831 width (+ width (ebnf-node-width node))))
|
|
4832 (ebnf-node-entry sequence above)
|
|
4833 (ebnf-node-height sequence (+ above below))
|
|
4834 (ebnf-node-width sequence width)))
|
|
4835
|
|
4836
|
|
4837 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
4838 ;; Adjusting width
|
|
4839
|
|
4840
|
|
4841 (defun ebnf-adjust-width (node width)
|
|
4842 (cond
|
|
4843 ((listp node)
|
|
4844 (prog1
|
|
4845 node
|
|
4846 (while node
|
|
4847 (setcar node (ebnf-adjust-width (car node) width))
|
|
4848 (setq node (cdr node)))))
|
|
4849 ((vectorp node)
|
|
4850 (cond
|
|
4851 ;; nothing to be done
|
|
4852 ((= width (ebnf-node-width node))
|
|
4853 node)
|
|
4854 ;; left justify term
|
|
4855 ((eq ebnf-justify-sequence 'left)
|
|
4856 (ebnf-adjust-empty node width nil))
|
|
4857 ;; right justify terms
|
|
4858 ((eq ebnf-justify-sequence 'right)
|
|
4859 (ebnf-adjust-empty node width t))
|
|
4860 ;; centralize terms
|
|
4861 (t
|
|
4862 (ebnf-node-width-func node width)
|
|
4863 (ebnf-node-width node width)
|
|
4864 node)
|
|
4865 ))
|
|
4866 (t
|
|
4867 node)
|
|
4868 ))
|
|
4869
|
|
4870
|
|
4871 (defun ebnf-adjust-empty (node width last-p)
|
|
4872 (if (eq (ebnf-node-kind node) 'ebnf-generate-empty)
|
|
4873 (progn
|
|
4874 (ebnf-node-width node width)
|
|
4875 node)
|
|
4876 (let ((empty (ebnf-make-empty (- width (ebnf-node-width node)))))
|
|
4877 (ebnf-make-dup-sequence node
|
|
4878 (if last-p
|
|
4879 (list empty node)
|
|
4880 (list node empty))))))
|
|
4881
|
|
4882
|
|
4883 ;; [terminal width-fun dim-fun entry height width name]
|
|
4884 ;; [non-terminal width-fun dim-fun entry height width name]
|
|
4885 ;; [empty width-fun dim-fun entry height width]
|
|
4886 ;; [special width-fun dim-fun entry height width name]
|
|
4887 ;; [repeat width-fun dim-fun entry height width times element]
|
|
4888 ;; [except width-fun dim-fun entry height width element element]
|
|
4889 ;;(defun ebnf-terminal-width (terminal width)
|
|
4890 ;; )
|
|
4891
|
|
4892
|
|
4893 ;; [alternative width-fun dim-fun entry height width list]
|
|
4894 ;; [optional width-fun dim-fun entry height width element]
|
|
4895 (defun ebnf-alternative-width (alternative width)
|
|
4896 (ebnf-adjust-width (ebnf-node-list alternative)
|
|
4897 (- width ebnf-horizontal-space)))
|
|
4898
|
|
4899
|
|
4900 ;; [one-or-more width-fun dim-fun entry height width element separator]
|
|
4901 ;; [zero-or-more width-fun dim-fun entry height width element separator]
|
|
4902 (defun ebnf-list-width (or-more width)
|
|
4903 (setq width (- width ebnf-horizontal-space))
|
|
4904 (ebnf-node-list or-more
|
|
4905 (ebnf-justify-list or-more
|
|
4906 (ebnf-node-list or-more)
|
|
4907 width))
|
|
4908 (ebnf-node-separator or-more
|
|
4909 (ebnf-justify-list or-more
|
|
4910 (ebnf-node-separator or-more)
|
|
4911 width)))
|
|
4912
|
|
4913
|
|
4914 ;; [sequence width-fun dim-fun entry height width list]
|
|
4915 (defun ebnf-sequence-width (sequence width)
|
|
4916 (ebnf-node-list sequence
|
|
4917 (ebnf-justify-list sequence (ebnf-node-list sequence) width)))
|
|
4918
|
|
4919
|
|
4920 (defun ebnf-justify-list (node seq width)
|
|
4921 (let ((seq-width (ebnf-node-width node)))
|
|
4922 (if (= width seq-width)
|
|
4923 seq
|
|
4924 (cond
|
|
4925 ;; left justify terms
|
|
4926 ((eq ebnf-justify-sequence 'left)
|
|
4927 (ebnf-justify node seq seq-width width t))
|
|
4928 ;; right justify terms
|
|
4929 ((eq ebnf-justify-sequence 'right)
|
|
4930 (ebnf-justify node seq seq-width width nil))
|
|
4931 ;; centralize terms
|
|
4932 (t
|
|
4933 (let ((the-width (/ (- width seq-width) (length seq)))
|
|
4934 (lis seq))
|
|
4935 (while lis
|
|
4936 (ebnf-adjust-width (car lis)
|
|
4937 (+ (ebnf-node-width (car lis))
|
|
4938 the-width))
|
|
4939 (setq lis (cdr lis)))
|
|
4940 seq))
|
|
4941 ))))
|
|
4942
|
|
4943
|
|
4944 (defun ebnf-justify (node seq seq-width width last-p)
|
|
4945 (let ((term (car (if last-p (last seq) seq))))
|
|
4946 (cond
|
|
4947 ;; adjust empty term
|
|
4948 ((eq (ebnf-node-kind term) 'ebnf-generate-empty)
|
|
4949 (ebnf-node-width term (+ (- width seq-width)
|
|
4950 (ebnf-node-width term)))
|
|
4951 seq)
|
|
4952 ;; insert empty at end ==> left justify
|
|
4953 (last-p
|
|
4954 (nconc seq
|
|
4955 (list (ebnf-make-empty (- width seq-width)))))
|
|
4956 ;; insert empty at beginning ==> right justify
|
|
4957 (t
|
|
4958 (cons (ebnf-make-empty (- width seq-width))
|
|
4959 seq))
|
|
4960 )))
|
|
4961
|
|
4962
|
|
4963 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
4964 ;; Functions used by parsers
|
|
4965
|
|
4966
|
|
4967 (defun ebnf-eps-add-context (name)
|
|
4968 (let ((filename (ebnf-eps-filename name)))
|
|
4969 (if (member filename ebnf-eps-context)
|
|
4970 (error "Try to open an already opened EPS file: %s" filename)
|
|
4971 (setq ebnf-eps-context (cons filename ebnf-eps-context)))))
|
|
4972
|
|
4973
|
|
4974 (defun ebnf-eps-remove-context (name)
|
|
4975 (let ((filename (ebnf-eps-filename name)))
|
|
4976 (if (member filename ebnf-eps-context)
|
|
4977 (setq ebnf-eps-context (delete filename ebnf-eps-context))
|
|
4978 (error "Try to close a not opened EPS file: %s" filename))))
|
|
4979
|
|
4980
|
|
4981 (defun ebnf-eps-add-production (header)
|
|
4982 (and ebnf-eps-executing
|
|
4983 ebnf-eps-context
|
|
4984 (let ((prod (assoc header ebnf-eps-production-list)))
|
|
4985 (if prod
|
|
4986 (setcdr prod (append ebnf-eps-context (cdr prod)))
|
|
4987 (setq ebnf-eps-production-list
|
|
4988 (cons (cons header (ebnf-dup-list ebnf-eps-context))
|
|
4989 ebnf-eps-production-list))))))
|
|
4990
|
|
4991
|
|
4992 (defun ebnf-dup-list (old)
|
|
4993 (let (new)
|
|
4994 (while old
|
|
4995 (setq new (cons (car old) new)
|
|
4996 old (cdr old)))
|
|
4997 (nreverse new)))
|
|
4998
|
|
4999
|
|
5000 (defun ebnf-buffer-substring (chars)
|
|
5001 (buffer-substring-no-properties
|
|
5002 (point)
|
|
5003 (progn
|
|
5004 (skip-chars-forward chars ebnf-limit)
|
|
5005 (point))))
|
|
5006
|
|
5007
|
|
5008 (defun ebnf-string (chars eos-char kind)
|
|
5009 (forward-char)
|
|
5010 (buffer-substring-no-properties
|
|
5011 (point)
|
|
5012 (progn
|
|
5013 (skip-chars-forward (concat chars "\240-\377") ebnf-limit)
|
|
5014 (if (or (eobp) (/= (following-char) eos-char))
|
|
5015 (error "Illegal %s: missing `%c'." kind eos-char)
|
|
5016 (forward-char)
|
|
5017 (1- (point))))))
|
|
5018
|
|
5019
|
|
5020 (defun ebnf-get-string ()
|
|
5021 (forward-char)
|
|
5022 (buffer-substring-no-properties (point) (ebnf-end-of-string)))
|
|
5023
|
|
5024
|
|
5025 (defun ebnf-end-of-string ()
|
|
5026 (let ((n 1))
|
|
5027 (while (> (logand n 1) 0)
|
|
5028 (skip-chars-forward "^\"" ebnf-limit)
|
|
5029 (setq n (- (skip-chars-backward "\\\\")))
|
|
5030 (goto-char (+ (point) n 1))))
|
|
5031 (if (= (preceding-char) ?\")
|
|
5032 (1- (point))
|
|
5033 (error "Missing `\"'.")))
|
|
5034
|
|
5035
|
|
5036 (defun ebnf-trim-right (str)
|
|
5037 (let* ((len (1- (length str)))
|
|
5038 (index len))
|
|
5039 (while (and (> index 0) (= (aref str index) ?\ ))
|
|
5040 (setq index (1- index)))
|
|
5041 (if (= index len)
|
|
5042 str
|
|
5043 (substring str 0 (1+ index)))))
|
|
5044
|
|
5045
|
|
5046 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
5047 ;; Vector creation
|
|
5048
|
|
5049
|
|
5050 (defun ebnf-make-empty (&optional width)
|
|
5051 (vector 'ebnf-generate-empty
|
|
5052 'ignore
|
|
5053 'ignore
|
|
5054 0.0
|
|
5055 0.0
|
|
5056 (or width ebnf-horizontal-space)))
|
|
5057
|
|
5058
|
|
5059 (defun ebnf-make-terminal (name)
|
|
5060 (ebnf-make-terminal1 name
|
|
5061 'ebnf-generate-terminal
|
|
5062 'ebnf-terminal-dimension))
|
|
5063
|
|
5064
|
|
5065 (defun ebnf-make-non-terminal (name)
|
|
5066 (ebnf-make-terminal1 name
|
|
5067 'ebnf-generate-non-terminal
|
|
5068 'ebnf-non-terminal-dimension))
|
|
5069
|
|
5070
|
|
5071 (defun ebnf-make-special (name)
|
|
5072 (ebnf-make-terminal1 name
|
|
5073 'ebnf-generate-special
|
|
5074 'ebnf-special-dimension))
|
|
5075
|
|
5076
|
|
5077 (defun ebnf-make-terminal1 (name gen-func dim-func)
|
|
5078 (vector gen-func
|
|
5079 'ignore
|
|
5080 dim-func
|
|
5081 0.0
|
|
5082 0.0
|
|
5083 0.0
|
|
5084 (let ((len (length name)))
|
|
5085 (cond ((> len 2) name)
|
|
5086 ((= len 2) (concat " " name))
|
|
5087 ((= len 1) (concat " " name " "))
|
|
5088 (t " ")))
|
|
5089 ebnf-default-p))
|
|
5090
|
|
5091
|
|
5092 (defun ebnf-make-one-or-more (list-part &optional sep-part)
|
|
5093 (ebnf-make-or-more1 'ebnf-generate-one-or-more
|
|
5094 'ebnf-one-or-more-dimension
|
|
5095 list-part
|
|
5096 sep-part))
|
|
5097
|
|
5098
|
|
5099 (defun ebnf-make-zero-or-more (list-part &optional sep-part)
|
|
5100 (ebnf-make-or-more1 'ebnf-generate-zero-or-more
|
|
5101 'ebnf-zero-or-more-dimension
|
|
5102 list-part
|
|
5103 sep-part))
|
|
5104
|
|
5105
|
|
5106 (defun ebnf-make-or-more1 (gen-func dim-func list-part sep-part)
|
|
5107 (vector gen-func
|
|
5108 'ebnf-list-width
|
|
5109 dim-func
|
|
5110 0.0
|
|
5111 0.0
|
|
5112 0.0
|
|
5113 (if (listp list-part)
|
|
5114 (ebnf-make-sequence list-part)
|
|
5115 list-part)
|
|
5116 (if (and sep-part (listp sep-part))
|
|
5117 (ebnf-make-sequence sep-part)
|
|
5118 sep-part)))
|
|
5119
|
|
5120
|
|
5121 (defun ebnf-make-production (name prod action)
|
|
5122 (vector 'ebnf-generate-production
|
|
5123 'ignore
|
|
5124 'ebnf-production-dimension
|
|
5125 0.0
|
|
5126 0.0
|
|
5127 0.0
|
|
5128 name
|
|
5129 prod
|
|
5130 action))
|
|
5131
|
|
5132
|
|
5133 (defun ebnf-make-alternative (body)
|
|
5134 (vector 'ebnf-generate-alternative
|
|
5135 'ebnf-alternative-width
|
|
5136 'ebnf-alternative-dimension
|
|
5137 0.0
|
|
5138 0.0
|
|
5139 0.0
|
|
5140 body))
|
|
5141
|
|
5142
|
|
5143 (defun ebnf-make-optional (body)
|
|
5144 (vector 'ebnf-generate-optional
|
|
5145 'ebnf-alternative-width
|
|
5146 'ebnf-optional-dimension
|
|
5147 0.0
|
|
5148 0.0
|
|
5149 0.0
|
|
5150 body))
|
|
5151
|
|
5152
|
|
5153 (defun ebnf-make-except (factor exception)
|
|
5154 (vector 'ebnf-generate-except
|
|
5155 'ignore
|
|
5156 'ebnf-except-dimension
|
|
5157 0.0
|
|
5158 0.0
|
|
5159 0.0
|
|
5160 factor
|
|
5161 exception))
|
|
5162
|
|
5163
|
|
5164 (defun ebnf-make-repeat (times primary)
|
|
5165 (vector 'ebnf-generate-repeat
|
|
5166 'ignore
|
|
5167 'ebnf-repeat-dimension
|
|
5168 0.0
|
|
5169 0.0
|
|
5170 0.0
|
|
5171 (concat times " *")
|
|
5172 primary))
|
|
5173
|
|
5174
|
|
5175 (defun ebnf-make-sequence (seq)
|
|
5176 (vector 'ebnf-generate-sequence
|
|
5177 'ebnf-sequence-width
|
|
5178 'ebnf-sequence-dimension
|
|
5179 0.0
|
|
5180 0.0
|
|
5181 0.0
|
|
5182 seq))
|
|
5183
|
|
5184
|
|
5185 (defun ebnf-make-dup-sequence (node seq)
|
|
5186 (vector 'ebnf-generate-sequence
|
|
5187 'ebnf-sequence-width
|
|
5188 'ebnf-sequence-dimension
|
|
5189 (ebnf-node-entry node)
|
|
5190 (ebnf-node-height node)
|
|
5191 (ebnf-node-width node)
|
|
5192 seq))
|
|
5193
|
|
5194
|
|
5195 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
5196 ;; Optimizers used by parsers
|
|
5197
|
|
5198
|
|
5199 (defun ebnf-token-except (element exception)
|
|
5200 (cons (prog1
|
|
5201 (car exception)
|
|
5202 (setq exception (cdr exception)))
|
|
5203 (and element ; EMPTY - A ==> EMPTY
|
|
5204 (let ((kind (ebnf-node-kind element)))
|
|
5205 (cond
|
|
5206 ;; [ A ]- ==> A
|
|
5207 ((and (null exception)
|
|
5208 (eq kind 'ebnf-generate-optional))
|
|
5209 (ebnf-node-list element))
|
|
5210 ;; { A }- ==> { A }+
|
|
5211 ((and (null exception)
|
|
5212 (eq kind 'ebnf-generate-zero-or-more))
|
|
5213 (ebnf-node-kind element 'ebnf-generate-one-or-more)
|
|
5214 (ebnf-node-dimension-func element 'ebnf-one-or-more-dimension)
|
|
5215 element)
|
|
5216 ;; ( A | EMPTY )- ==> A
|
|
5217 ;; ( A | B | EMPTY )- ==> A | B
|
|
5218 ((and (null exception)
|
|
5219 (eq kind 'ebnf-generate-alternative)
|
|
5220 (eq (ebnf-node-kind (car (last (ebnf-node-list element))))
|
|
5221 'ebnf-generate-empty))
|
|
5222 (let ((elt (ebnf-node-list element))
|
|
5223 bef)
|
|
5224 (while (cdr elt)
|
|
5225 (setq bef elt
|
|
5226 elt (cdr elt)))
|
|
5227 (if (null bef)
|
|
5228 ;; this should not happen!!?!
|
|
5229 (setq element (ebnf-make-empty
|
|
5230 (ebnf-node-width element)))
|
|
5231 (setcdr bef nil)
|
|
5232 (setq elt (ebnf-node-list element))
|
|
5233 (and (= (length elt) 1)
|
|
5234 (setq element (car elt))))
|
|
5235 element))
|
|
5236 ;; A - B
|
|
5237 (t
|
|
5238 (ebnf-make-except element exception))
|
|
5239 )))))
|
|
5240
|
|
5241
|
|
5242 (defun ebnf-token-repeat (times repeat)
|
|
5243 (if (null (cdr repeat))
|
|
5244 ;; n * EMPTY ==> EMPTY
|
|
5245 repeat
|
|
5246 ;; n * term
|
|
5247 (cons (car repeat)
|
|
5248 (ebnf-make-repeat times (cdr repeat)))))
|
|
5249
|
|
5250
|
|
5251 (defun ebnf-token-optional (body)
|
|
5252 (let ((kind (ebnf-node-kind body)))
|
|
5253 (cond
|
|
5254 ;; [ EMPTY ] ==> EMPTY
|
|
5255 ((eq kind 'ebnf-generate-empty)
|
|
5256 nil)
|
|
5257 ;; [ { A }* ] ==> { A }*
|
|
5258 ((eq kind 'ebnf-generate-zero-or-more)
|
|
5259 body)
|
|
5260 ;; [ { A }+ ] ==> { A }*
|
|
5261 ((eq kind 'ebnf-generate-one-or-more)
|
|
5262 (ebnf-node-kind body 'ebnf-generate-zero-or-more)
|
|
5263 body)
|
|
5264 ;; [ A | B ] ==> A | B | EMPTY
|
|
5265 ((eq kind 'ebnf-generate-alternative)
|
|
5266 (ebnf-node-list body (nconc (ebnf-node-list body)
|
|
5267 (list (ebnf-make-empty))))
|
|
5268 body)
|
|
5269 ;; [ A ]
|
|
5270 (t
|
|
5271 (ebnf-make-optional body))
|
|
5272 )))
|
|
5273
|
|
5274
|
|
5275 (defun ebnf-token-alternative (body sequence)
|
|
5276 (if (null body)
|
|
5277 (if (cdr sequence)
|
|
5278 sequence
|
|
5279 (cons (car sequence)
|
|
5280 (ebnf-make-empty)))
|
|
5281 (cons (car sequence)
|
|
5282 (let ((seq (cdr sequence)))
|
|
5283 (if (and (= (length body) 1) (null seq))
|
|
5284 (car body)
|
|
5285 (ebnf-make-alternative (nreverse (if seq
|
|
5286 (cons seq body)
|
|
5287 body))))))))
|
|
5288
|
|
5289
|
|
5290 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
5291 ;; Variables used by parsers
|
|
5292
|
|
5293
|
|
5294 (defconst ebnf-comment-table
|
|
5295 (let ((table (make-vector 256 nil)))
|
|
5296 ;; Override special comment character:
|
|
5297 (aset table ?< 'newline)
|
|
5298 (aset table ?> 'keep-line)
|
|
5299 table)
|
|
5300 "Vector used to map characters to a special comment token.")
|
|
5301
|
|
5302
|
|
5303 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
5304 ;; To make this file smaller, some commands go in a separate file.
|
|
5305 ;; But autoload them here to make the separation invisible.
|
|
5306
|
|
5307 (autoload 'ebnf-bnf-parser "ebnf-bnf"
|
|
5308 "EBNF parser.")
|
|
5309
|
|
5310 (autoload 'ebnf-bnf-initialize "ebnf-bnf"
|
|
5311 "Initialize EBNF token table.")
|
|
5312
|
|
5313 (autoload 'ebnf-iso-parser "ebnf-iso"
|
|
5314 "ISO EBNF parser.")
|
|
5315
|
|
5316 (autoload 'ebnf-iso-initialize "ebnf-iso"
|
|
5317 "Initialize ISO EBNF token table.")
|
|
5318
|
|
5319 (autoload 'ebnf-yac-parser "ebnf-yac"
|
|
5320 "Yacc/Bison parser.")
|
|
5321
|
|
5322 (autoload 'ebnf-yac-initialize "ebnf-yac"
|
|
5323 "Initializations for Yacc/Bison parser.")
|
|
5324
|
|
5325 (autoload 'ebnf-eliminate-empty-rules "ebnf-otz"
|
|
5326 "Eliminate empty rules.")
|
|
5327
|
|
5328 (autoload 'ebnf-optimize "ebnf-otz"
|
|
5329 "Syntatic chart optimizer.")
|
|
5330
|
|
5331 (autoload 'ebnf-otz-initialize "ebnf-otz"
|
|
5332 "Initialize optimizer.")
|
|
5333
|
|
5334
|
|
5335 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
5336
|
|
5337
|
|
5338 (provide 'ebnf2ps)
|
|
5339
|
|
5340
|
|
5341 ;;; ebnf2ps.el ends here
|