ebnf-otz.el 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  1. ;;; ebnf-otz.el --- syntactic chart OpTimiZer
  2. ;; Copyright (C) 1999-2012 Free Software Foundation, Inc.
  3. ;; Author: Vinicius Jose Latorre <viniciusjl@ig.com.br>
  4. ;; Maintainer: Vinicius Jose Latorre <viniciusjl@ig.com.br>
  5. ;; Keywords: wp, ebnf, PostScript
  6. ;; Version: 1.0
  7. ;; Package: ebnf2ps
  8. ;; This file is part of GNU Emacs.
  9. ;; GNU Emacs is free software: you can redistribute it and/or modify
  10. ;; it under the terms of the GNU General Public License as published by
  11. ;; the Free Software Foundation, either version 3 of the License, or
  12. ;; (at your option) any later version.
  13. ;; GNU Emacs is distributed in the hope that it will be useful,
  14. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. ;; GNU General Public License for more details.
  17. ;; You should have received a copy of the GNU General Public License
  18. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  19. ;;; Commentary:
  20. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  21. ;;
  22. ;;
  23. ;; This is part of ebnf2ps package.
  24. ;;
  25. ;; This package defines an optimizer for ebnf2ps.
  26. ;;
  27. ;; See ebnf2ps.el for documentation.
  28. ;;
  29. ;;
  30. ;; Optimizations
  31. ;; -------------
  32. ;;
  33. ;;
  34. ;; *To be implemented*:
  35. ;; left recursion:
  36. ;; A = B | A C B | A C D. ==> A = B {C (B | D)}*.
  37. ;;
  38. ;; right recursion:
  39. ;; A = B | C A. ==> A = {C}* B.
  40. ;; A = B | D | C A | E A. ==> A = { C | E }* ( B | D ).
  41. ;;
  42. ;; optional:
  43. ;; A = B | C B. ==> A = [C] B.
  44. ;; A = B | B C. ==> A = B [C].
  45. ;; A = D | B D | B C D. ==> A = [B [C]] D.
  46. ;;
  47. ;;
  48. ;; *Already implemented*:
  49. ;; left recursion:
  50. ;; A = B | A C. ==> A = B {C}*.
  51. ;; A = B | A B. ==> A = {B}+.
  52. ;; A = | A B. ==> A = {B}*.
  53. ;; A = B | A C B. ==> A = {B || C}+.
  54. ;; A = B | D | A C | A E. ==> A = ( B | D ) { C | E }*.
  55. ;;
  56. ;; optional:
  57. ;; A = B | . ==> A = [B].
  58. ;; A = | B . ==> A = [B].
  59. ;;
  60. ;; factorization:
  61. ;; A = B C | B D. ==> A = B (C | D).
  62. ;; A = C B | D B. ==> A = (C | D) B.
  63. ;; A = B C E | B D E. ==> A = B (C | D) E.
  64. ;;
  65. ;; none:
  66. ;; A = B | C | . ==> A = B | C | .
  67. ;; A = B | C A D. ==> A = B | C A D.
  68. ;;
  69. ;;
  70. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  71. ;;; Code:
  72. (require 'ebnf2ps)
  73. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  74. (defvar ebnf-empty-rule-list nil
  75. "List of empty rule name.")
  76. (defun ebnf-add-empty-rule-list (rule)
  77. "Add empty RULE in `ebnf-empty-rule-list'."
  78. (and ebnf-ignore-empty-rule
  79. (eq (ebnf-node-kind (ebnf-node-production rule))
  80. 'ebnf-generate-empty)
  81. (setq ebnf-empty-rule-list (cons (ebnf-node-name rule)
  82. ebnf-empty-rule-list))))
  83. (defun ebnf-otz-initialize ()
  84. "Initialize optimizer."
  85. (setq ebnf-empty-rule-list nil))
  86. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  87. ;; Eliminate empty rules
  88. (defun ebnf-eliminate-empty-rules (syntax-list)
  89. "Eliminate empty rules."
  90. (while ebnf-empty-rule-list
  91. (let ((ebnf-total (length syntax-list))
  92. (ebnf-nprod 0)
  93. (prod-list syntax-list)
  94. new-list before)
  95. (while prod-list
  96. (ebnf-message-info "Eliminating empty rules")
  97. (let ((rule (car prod-list)))
  98. ;; if any non-terminal pertains to ebnf-empty-rule-list
  99. ;; then eliminate non-terminal from rule
  100. (if (ebnf-eliminate-empty rule)
  101. (setq before prod-list)
  102. ;; eliminate empty rule from syntax-list
  103. (setq new-list (cons (ebnf-node-name rule) new-list))
  104. (if before
  105. (setcdr before (cdr prod-list))
  106. (setq syntax-list (cdr syntax-list)))))
  107. (setq prod-list (cdr prod-list)))
  108. (setq ebnf-empty-rule-list new-list)))
  109. syntax-list)
  110. ;; [production width-func entry height width name production action]
  111. ;; [sequence width-func entry height width list]
  112. ;; [alternative width-func entry height width list]
  113. ;; [non-terminal width-func entry height width name default]
  114. ;; [empty width-func entry height width]
  115. ;; [terminal width-func entry height width name default]
  116. ;; [special width-func entry height width name default]
  117. (defun ebnf-eliminate-empty (rule)
  118. (let ((kind (ebnf-node-kind rule)))
  119. (cond
  120. ;; non-terminal
  121. ((eq kind 'ebnf-generate-non-terminal)
  122. (if (member (ebnf-node-name rule) ebnf-empty-rule-list)
  123. nil
  124. rule))
  125. ;; sequence
  126. ((eq kind 'ebnf-generate-sequence)
  127. (let ((seq (ebnf-node-list rule))
  128. (header (ebnf-node-list rule))
  129. before elt)
  130. (while seq
  131. (setq elt (car seq))
  132. (if (ebnf-eliminate-empty elt)
  133. (setq before seq)
  134. (if before
  135. (setcdr before (cdr seq))
  136. (setq header (cdr header))))
  137. (setq seq (cdr seq)))
  138. (when header
  139. (ebnf-node-list rule header)
  140. rule)))
  141. ;; alternative
  142. ((eq kind 'ebnf-generate-alternative)
  143. (let ((seq (ebnf-node-list rule))
  144. (header (ebnf-node-list rule))
  145. before elt)
  146. (while seq
  147. (setq elt (car seq))
  148. (if (ebnf-eliminate-empty elt)
  149. (setq before seq)
  150. (if before
  151. (setcdr before (cdr seq))
  152. (setq header (cdr header))))
  153. (setq seq (cdr seq)))
  154. (when header
  155. (if (= (length header) 1)
  156. (car header)
  157. (ebnf-node-list rule header)
  158. rule))))
  159. ;; production
  160. ((eq kind 'ebnf-generate-production)
  161. (let ((prod (ebnf-eliminate-empty (ebnf-node-production rule))))
  162. (when prod
  163. (ebnf-node-production rule prod)
  164. rule)))
  165. ;; terminal, special and empty
  166. (t
  167. rule)
  168. )))
  169. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  170. ;; Optimizations
  171. ;; *To be implemented*:
  172. ;; left recursion:
  173. ;; A = B | A C B | A C D. ==> A = B {C (B | D)}*.
  174. ;; right recursion:
  175. ;; A = B | C A. ==> A = {C}* B.
  176. ;; A = B | D | C A | E A. ==> A = { C | E }* ( B | D ).
  177. ;; optional:
  178. ;; A = B | C B. ==> A = [C] B.
  179. ;; A = B | B C. ==> A = B [C].
  180. ;; A = D | B D | B C D. ==> A = [B [C]] D.
  181. ;; *Already implemented*:
  182. ;; left recursion:
  183. ;; A = B | A C. ==> A = B {C}*.
  184. ;; A = B | A B. ==> A = {B}+.
  185. ;; A = | A B. ==> A = {B}*.
  186. ;; A = B | A C B. ==> A = {B || C}+.
  187. ;; A = B | D | A C | A E. ==> A = ( B | D ) { C | E }*.
  188. ;; optional:
  189. ;; A = B | . ==> A = [B].
  190. ;; A = | B . ==> A = [B].
  191. ;; factorization:
  192. ;; A = B C | B D. ==> A = B (C | D).
  193. ;; A = C B | D B. ==> A = (C | D) B.
  194. ;; A = B C E | B D E. ==> A = B (C | D) E.
  195. ;; none:
  196. ;; A = B | C | . ==> A = B | C | .
  197. ;; A = B | C A D. ==> A = B | C A D.
  198. (defun ebnf-optimize (syntax-list)
  199. "Syntactic chart optimizer."
  200. (if (not ebnf-optimize)
  201. syntax-list
  202. (let ((ebnf-total (length syntax-list))
  203. (ebnf-nprod 0)
  204. new)
  205. (while syntax-list
  206. (setq new (cons (ebnf-optimize1 (car syntax-list)) new)
  207. syntax-list (cdr syntax-list)))
  208. (nreverse new))))
  209. ;; left recursion:
  210. ;; 1. A = B | A C. ==> A = B {C}*.
  211. ;; 2. A = B | A B. ==> A = {B}+.
  212. ;; 3. A = | A B. ==> A = {B}*.
  213. ;; 4. A = B | A C B. ==> A = {B || C}+.
  214. ;; 5. A = B | D | A C | A E. ==> A = ( B | D ) { C | E }*.
  215. ;; optional:
  216. ;; 6. A = B | . ==> A = [B].
  217. ;; 7. A = | B . ==> A = [B].
  218. ;; factorization:
  219. ;; 8. A = B C | B D. ==> A = B (C | D).
  220. ;; 9. A = C B | D B. ==> A = (C | D) B.
  221. ;; 10. A = B C E | B D E. ==> A = B (C | D) E.
  222. (defun ebnf-optimize1 (prod)
  223. (ebnf-message-info "Optimizing syntactic chart")
  224. (let ((production (ebnf-node-production prod)))
  225. (and (eq (ebnf-node-kind production) 'ebnf-generate-alternative)
  226. (let* ((hlist (ebnf-split-header-prefix
  227. (ebnf-node-list production)
  228. (ebnf-node-name prod)))
  229. (nlist (car hlist))
  230. (zlist (cdr hlist))
  231. (elist (ebnf-split-header-suffix nlist zlist)))
  232. (ebnf-node-production
  233. prod
  234. (cond
  235. ;; cases 2., 4.
  236. (elist
  237. (and (eq elist t)
  238. (setq elist nil))
  239. (setq elist (or (ebnf-prefix-suffix elist)
  240. elist))
  241. (let* ((nl (ebnf-extract-empty nlist))
  242. (el (or (ebnf-prefix-suffix (cdr nl))
  243. (ebnf-create-alternative (cdr nl)))))
  244. (if (car nl)
  245. (ebnf-make-zero-or-more el elist)
  246. (ebnf-make-one-or-more el elist))))
  247. ;; cases 1., 3., 5.
  248. (zlist
  249. (let* ((xlist (cdr (ebnf-extract-empty zlist)))
  250. (znode (ebnf-make-zero-or-more
  251. (or (ebnf-prefix-suffix xlist)
  252. (ebnf-create-alternative xlist))))
  253. (nnode (ebnf-map-list-to-optional nlist)))
  254. (and nnode
  255. (setq nlist (list nnode)))
  256. (if (or (null nlist)
  257. (and (= (length nlist) 1)
  258. (eq (ebnf-node-kind (car nlist))
  259. 'ebnf-generate-empty)))
  260. znode
  261. (ebnf-make-sequence
  262. (list (or (ebnf-prefix-suffix nlist)
  263. (ebnf-create-alternative nlist))
  264. znode)))))
  265. ;; cases 6., 7.
  266. ((ebnf-map-node-to-optional production)
  267. )
  268. ;; cases 8., 9., 10.
  269. ((ebnf-prefix-suffix nlist)
  270. )
  271. ;; none
  272. (t
  273. production)
  274. ))))
  275. prod))
  276. (defun ebnf-split-header-prefix (node-list header)
  277. (let* ((hlist (ebnf-split-header-prefix1 node-list header))
  278. (nlist (car hlist))
  279. zlist empty-p)
  280. (while (setq hlist (cdr hlist))
  281. (let ((elt (car hlist)))
  282. (if (eq (ebnf-node-kind elt) 'ebnf-generate-sequence)
  283. (setq zlist (cons
  284. (let ((seq (cdr (ebnf-node-list elt))))
  285. (if (= (length seq) 1)
  286. (car seq)
  287. (ebnf-node-list elt seq)
  288. elt))
  289. zlist))
  290. (setq empty-p t))))
  291. (and empty-p
  292. (setq zlist (cons (ebnf-make-empty)
  293. zlist)))
  294. (cons nlist (nreverse zlist))))
  295. (defun ebnf-split-header-prefix1 (node-list header)
  296. (let (hlist nlist)
  297. (while node-list
  298. (if (ebnf-node-equal-header (car node-list) header)
  299. (setq hlist (cons (car node-list) hlist))
  300. (setq nlist (cons (car node-list) nlist)))
  301. (setq node-list (cdr node-list)))
  302. (cons (nreverse nlist) (nreverse hlist))))
  303. (defun ebnf-node-equal-header (node header)
  304. (let ((kind (ebnf-node-kind node)))
  305. (cond
  306. ((eq kind 'ebnf-generate-sequence)
  307. (ebnf-node-equal-header (car (ebnf-node-list node)) header))
  308. ((eq kind 'ebnf-generate-non-terminal)
  309. (string= (ebnf-node-name node) header))
  310. (t
  311. nil)
  312. )))
  313. (defun ebnf-map-node-to-optional (node)
  314. (and (eq (ebnf-node-kind node) 'ebnf-generate-alternative)
  315. (ebnf-map-list-to-optional (ebnf-node-list node))))
  316. (defun ebnf-map-list-to-optional (nlist)
  317. (and (= (length nlist) 2)
  318. (let ((first (nth 0 nlist))
  319. (second (nth 1 nlist)))
  320. (cond
  321. ;; empty second
  322. ((eq (ebnf-node-kind first) 'ebnf-generate-empty)
  323. (ebnf-make-optional second))
  324. ;; first empty
  325. ((eq (ebnf-node-kind second) 'ebnf-generate-empty)
  326. (ebnf-make-optional first))
  327. ;; first second
  328. (t
  329. nil)
  330. ))))
  331. (defun ebnf-extract-empty (elist)
  332. (let ((now elist)
  333. before empty-p)
  334. (while now
  335. (if (not (eq (ebnf-node-kind (car now)) 'ebnf-generate-empty))
  336. (setq before now)
  337. (setq empty-p t)
  338. (if before
  339. (setcdr before (cdr now))
  340. (setq elist (cdr elist))))
  341. (setq now (cdr now)))
  342. (cons empty-p elist)))
  343. (defun ebnf-split-header-suffix (nlist zlist)
  344. (let (new empty-p)
  345. (and (cond
  346. ((= (length nlist) 1)
  347. (let ((ok t)
  348. (elt (car nlist)))
  349. (while (and ok zlist)
  350. (setq ok (ebnf-split-header-suffix1 elt (car zlist))
  351. zlist (cdr zlist))
  352. (if (eq ok t)
  353. (setq empty-p t)
  354. (setq new (cons ok new))))
  355. ok))
  356. ((= (length nlist) (length zlist))
  357. (let ((ok t))
  358. (while (and ok zlist)
  359. (setq ok (ebnf-split-header-suffix1 (car nlist) (car zlist))
  360. nlist (cdr nlist)
  361. zlist (cdr zlist))
  362. (if (eq ok t)
  363. (setq empty-p t)
  364. (setq new (cons ok new))))
  365. ok))
  366. (t
  367. nil)
  368. )
  369. (let* ((lis (ebnf-unique-list new))
  370. (len (length lis)))
  371. (cond
  372. ((zerop len)
  373. t)
  374. ((= len 1)
  375. (setq lis (car lis))
  376. (if empty-p
  377. (ebnf-make-optional lis)
  378. lis))
  379. (t
  380. (and empty-p
  381. (setq lis (cons (ebnf-make-empty) lis)))
  382. (ebnf-create-alternative (nreverse lis)))
  383. )))))
  384. (defun ebnf-split-header-suffix1 (ne ze)
  385. (cond
  386. ((eq (ebnf-node-kind ne) 'ebnf-generate-sequence)
  387. (and (eq (ebnf-node-kind ze) 'ebnf-generate-sequence)
  388. (let ((nl (ebnf-node-list ne))
  389. (zl (ebnf-node-list ze))
  390. len z)
  391. (and (>= (length zl) (length nl))
  392. (let ((ok t))
  393. (setq len (- (length zl) (length nl))
  394. z (nthcdr len zl))
  395. (while (and ok z)
  396. (setq ok (ebnf-node-equal (car z) (car nl))
  397. z (cdr z)
  398. nl (cdr nl)))
  399. ok)
  400. (if (zerop len)
  401. t
  402. (setcdr (nthcdr (1- len) zl) nil)
  403. ze)))))
  404. ((eq (ebnf-node-kind ze) 'ebnf-generate-sequence)
  405. (let* ((zl (ebnf-node-list ze))
  406. (len (length zl)))
  407. (and (ebnf-node-equal ne (car (nthcdr (1- len) zl)))
  408. (cond
  409. ((= len 1)
  410. t)
  411. ((= len 2)
  412. (car zl))
  413. (t
  414. (setcdr (nthcdr (- len 2) zl) nil)
  415. ze)
  416. ))))
  417. (t
  418. (ebnf-node-equal ne ze))
  419. ))
  420. (defun ebnf-prefix-suffix (lis)
  421. (and lis (listp lis)
  422. (let* ((prefix (ebnf-split-prefix lis))
  423. (suffix (ebnf-split-suffix (cdr prefix)))
  424. (middle (cdr suffix)))
  425. (setq prefix (car prefix)
  426. suffix (car suffix))
  427. (and (or prefix suffix)
  428. (ebnf-make-sequence
  429. (nconc prefix
  430. (and middle
  431. (list (or (ebnf-map-list-to-optional middle)
  432. (ebnf-create-alternative middle))))
  433. suffix))))))
  434. (defun ebnf-split-prefix (lis)
  435. (let* ((len (length lis))
  436. (tail lis)
  437. (head (if (eq (ebnf-node-kind (car lis)) 'ebnf-generate-sequence)
  438. (ebnf-node-list (car lis))
  439. (list (car lis))))
  440. (ipre (1+ len)))
  441. ;; determine prefix length
  442. (while (and (> ipre 0) (setq tail (cdr tail)))
  443. (let ((cur head)
  444. (this (if (eq (ebnf-node-kind (car tail)) 'ebnf-generate-sequence)
  445. (ebnf-node-list (car tail))
  446. (list (car tail))))
  447. (i 0))
  448. (while (and cur this
  449. (ebnf-node-equal (car cur) (car this)))
  450. (setq cur (cdr cur)
  451. this (cdr this)
  452. i (1+ i)))
  453. (setq ipre (min ipre i))))
  454. (if (or (zerop ipre) (> ipre len))
  455. ;; no prefix at all
  456. (cons nil lis)
  457. (let* ((tail (nthcdr ipre head))
  458. ;; get prefix
  459. (prefix (progn
  460. (and tail
  461. (setcdr (nthcdr (1- ipre) head) nil))
  462. head))
  463. empty-p before)
  464. ;; adjust first element
  465. (if (or (not (eq (ebnf-node-kind (car lis)) 'ebnf-generate-sequence))
  466. (null tail))
  467. (setq lis (cdr lis)
  468. tail lis
  469. empty-p t)
  470. (if (= (length tail) 1)
  471. (setcar lis (car tail))
  472. (ebnf-node-list (car lis) tail))
  473. (setq tail (cdr lis)))
  474. ;; eliminate prefix from lis based on ipre
  475. (while tail
  476. (let ((elt (car tail))
  477. rest)
  478. (if (and (eq (ebnf-node-kind elt) 'ebnf-generate-sequence)
  479. (setq rest (nthcdr ipre (ebnf-node-list elt))))
  480. (progn
  481. (if (= (length rest) 1)
  482. (setcar tail (car rest))
  483. (ebnf-node-list elt rest))
  484. (setq before tail))
  485. (setq empty-p t)
  486. (if before
  487. (setcdr before (cdr tail))
  488. (setq lis (cdr lis))))
  489. (setq tail (cdr tail))))
  490. (cons prefix (ebnf-unique-list
  491. (if empty-p
  492. (nconc lis (list (ebnf-make-empty)))
  493. lis)))))))
  494. (defun ebnf-split-suffix (lis)
  495. (let* ((len (length lis))
  496. (tail lis)
  497. (head (nreverse
  498. (if (eq (ebnf-node-kind (car lis)) 'ebnf-generate-sequence)
  499. (ebnf-node-list (car lis))
  500. (list (car lis)))))
  501. (isuf (1+ len)))
  502. ;; determine suffix length
  503. (while (and (> isuf 0) (setq tail (cdr tail)))
  504. (let* ((cur head)
  505. (tlis (nreverse
  506. (if (eq (ebnf-node-kind (car tail)) 'ebnf-generate-sequence)
  507. (ebnf-node-list (car tail))
  508. (list (car tail)))))
  509. (this tlis)
  510. (i 0))
  511. (while (and cur this
  512. (ebnf-node-equal (car cur) (car this)))
  513. (setq cur (cdr cur)
  514. this (cdr this)
  515. i (1+ i)))
  516. (nreverse tlis)
  517. (setq isuf (min isuf i))))
  518. (setq head (nreverse head))
  519. (if (or (zerop isuf) (> isuf len))
  520. ;; no suffix at all
  521. (cons nil lis)
  522. (let* ((n (- (length head) isuf))
  523. ;; get suffix
  524. (suffix (nthcdr n head))
  525. (tail (and (> n 0)
  526. (progn
  527. (setcdr (nthcdr (1- n) head) nil)
  528. head)))
  529. before empty-p)
  530. ;; adjust first element
  531. (if (or (not (eq (ebnf-node-kind (car lis)) 'ebnf-generate-sequence))
  532. (null tail))
  533. (setq lis (cdr lis)
  534. tail lis
  535. empty-p t)
  536. (if (= (length tail) 1)
  537. (setcar lis (car tail))
  538. (ebnf-node-list (car lis) tail))
  539. (setq tail (cdr lis)))
  540. ;; eliminate suffix from lis based on isuf
  541. (while tail
  542. (let ((elt (car tail))
  543. rest)
  544. (if (and (eq (ebnf-node-kind elt) 'ebnf-generate-sequence)
  545. (setq rest (ebnf-node-list elt)
  546. n (- (length rest) isuf))
  547. (> n 0))
  548. (progn
  549. (if (= n 1)
  550. (setcar tail (car rest))
  551. (setcdr (nthcdr (1- n) rest) nil)
  552. (ebnf-node-list elt rest))
  553. (setq before tail))
  554. (setq empty-p t)
  555. (if before
  556. (setcdr before (cdr tail))
  557. (setq lis (cdr lis))))
  558. (setq tail (cdr tail))))
  559. (cons suffix (ebnf-unique-list
  560. (if empty-p
  561. (nconc lis (list (ebnf-make-empty)))
  562. lis)))))))
  563. (defun ebnf-unique-list (nlist)
  564. (let ((current nlist)
  565. before)
  566. (while current
  567. (let ((tail (cdr current))
  568. (head (car current))
  569. remove-p)
  570. (while tail
  571. (if (not (ebnf-node-equal head (car tail)))
  572. (setq tail (cdr tail))
  573. (setq remove-p t
  574. tail nil)
  575. (if before
  576. (setcdr before (cdr current))
  577. (setq nlist (cdr nlist)))))
  578. (or remove-p
  579. (setq before current))
  580. (setq current (cdr current))))
  581. nlist))
  582. (defun ebnf-node-equal (A B)
  583. (let ((kindA (ebnf-node-kind A))
  584. (kindB (ebnf-node-kind B)))
  585. (and (eq kindA kindB)
  586. (cond
  587. ;; empty
  588. ((eq kindA 'ebnf-generate-empty)
  589. t)
  590. ;; non-terminal, terminal, special
  591. ((memq kindA '(ebnf-generate-non-terminal
  592. ebnf-generate-terminal
  593. ebnf-generate-special))
  594. (string= (ebnf-node-name A) (ebnf-node-name B)))
  595. ;; alternative, sequence
  596. ((memq kindA '(ebnf-generate-alternative ; any order
  597. ebnf-generate-sequence)) ; order is important
  598. (let ((listA (ebnf-node-list A))
  599. (listB (ebnf-node-list B)))
  600. (and (= (length listA) (length listB))
  601. (let ((ok t))
  602. (while (and ok listA)
  603. (setq ok (ebnf-node-equal (car listA) (car listB))
  604. listA (cdr listA)
  605. listB (cdr listB)))
  606. ok))))
  607. ;; production
  608. ((eq kindA 'ebnf-generate-production)
  609. (and (string= (ebnf-node-name A) (ebnf-node-name B))
  610. (ebnf-node-equal (ebnf-node-production A)
  611. (ebnf-node-production B))))
  612. ;; otherwise
  613. (t
  614. nil)
  615. ))))
  616. (defun ebnf-create-alternative (alt)
  617. (if (> (length alt) 1)
  618. (ebnf-make-alternative alt)
  619. (car alt)))
  620. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  621. (provide 'ebnf-otz)
  622. ;;; ebnf-otz.el ends here