rng-match.el 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693
  1. ;;; rng-match.el --- matching of RELAX NG patterns against XML events -*- lexical-binding:t -*-
  2. ;; Copyright (C) 2003, 2007-2017 Free Software Foundation, Inc.
  3. ;; Author: James Clark
  4. ;; Keywords: wp, hypermedia, languages, XML, RelaxNG
  5. ;; This file is part of GNU Emacs.
  6. ;; GNU Emacs is free software: you can redistribute it and/or modify
  7. ;; it under the terms of the GNU General Public License as published by
  8. ;; the Free Software Foundation, either version 3 of the License, or
  9. ;; (at your option) any later version.
  10. ;; GNU Emacs is distributed in the hope that it will be useful,
  11. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ;; GNU General Public License for more details.
  14. ;; You should have received a copy of the GNU General Public License
  15. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  16. ;;; Commentary:
  17. ;; This uses the algorithm described in
  18. ;; http://www.thaiopensource.com/relaxng/derivative.html
  19. ;;
  20. ;; The schema to be used is contained in the variable
  21. ;; rng-current-schema. It has the form described in the file
  22. ;; rng-pttrn.el.
  23. ;;
  24. ;;; Code:
  25. (require 'rng-pttrn)
  26. (require 'rng-util)
  27. (require 'rng-dt)
  28. (eval-when-compile (require 'cl-lib))
  29. (defvar rng-not-allowed-ipattern nil)
  30. (defvar rng-empty-ipattern nil)
  31. (defvar rng-text-ipattern nil)
  32. (defvar rng-compile-table nil)
  33. (defvar rng-being-compiled nil
  34. "Contains a list of ref patterns currently being compiled.
  35. Used to detect invalid recursive references.")
  36. (defvar rng-ipattern-table nil)
  37. (defvar rng-last-ipattern-index nil)
  38. (defvar rng-match-state nil
  39. "An ipattern representing the current state of validation.")
  40. ;;; Inline functions
  41. (defsubst rng-update-match-state (new-state)
  42. (if (eq new-state rng-not-allowed-ipattern)
  43. (eq rng-match-state rng-not-allowed-ipattern)
  44. (setq rng-match-state new-state)
  45. t))
  46. ;;; Interned patterns
  47. (cl-defstruct (rng--ipattern
  48. (:constructor nil)
  49. (:type vector)
  50. (:copier nil)
  51. (:constructor rng-make-ipattern
  52. (type index name-class child nullable)))
  53. type
  54. index
  55. name-class ;; Field also known as: `datatype' and `after'.
  56. child ;; Field also known as: `value-object'.
  57. nullable
  58. (memo-text-typed 'unknown)
  59. memo-map-start-tag-open-deriv
  60. memo-map-start-attribute-deriv
  61. memo-start-tag-close-deriv
  62. memo-text-only-deriv
  63. memo-mixed-text-deriv
  64. memo-map-data-deriv
  65. memo-end-tag-deriv)
  66. ;; I think depending on the value of `type' the two fields after `index'
  67. ;; are used sometimes for different purposes, hence the aliases here:
  68. (defalias 'rng--ipattern-datatype 'rng--ipattern-name-class)
  69. (defalias 'rng--ipattern-after 'rng--ipattern-name-class)
  70. (defalias 'rng--ipattern-value-object 'rng--ipattern-child)
  71. (defconst rng-memo-map-alist-max 10)
  72. (defsubst rng-memo-map-get (key mm)
  73. "Return the value associated with KEY in memo-map MM."
  74. (let ((found (assoc key mm)))
  75. (if found
  76. (cdr found)
  77. (and mm
  78. (let ((head (car mm)))
  79. (and (hash-table-p head)
  80. (gethash key head)))))))
  81. (defun rng-memo-map-add (key value mm &optional weakness)
  82. "Associate KEY with VALUE in memo-map MM and return the new memo-map.
  83. The new memo-map may or may not be a different object from MM.
  84. Alists are better for small maps. Hash tables are better for large
  85. maps. A memo-map therefore starts off as an alist and switches to a
  86. hash table for large memo-maps. A memo-map is always a list. An empty
  87. memo-map is represented by nil. A large memo-map is represented by a
  88. list containing just a hash-table. A small memo map is represented by
  89. a list whose cdr is an alist and whose car is the number of entries in
  90. the alist. The complete memo-map can be passed to `assoc' without
  91. problems: assoc ignores any members that are not cons cells. There is
  92. therefore minimal overhead in successful lookups on small lists
  93. \(which is the most common case)."
  94. (if (null mm)
  95. (list 1 (cons key value))
  96. (let ((head (car mm)))
  97. (cond ((hash-table-p head)
  98. (puthash key value head)
  99. mm)
  100. ((>= head rng-memo-map-alist-max)
  101. (let ((ht (make-hash-table :test 'equal
  102. :weakness weakness
  103. :size (* 2 rng-memo-map-alist-max))))
  104. (setq mm (cdr mm))
  105. (while mm
  106. (setq head (car mm))
  107. (puthash (car head) (cdr head) ht)
  108. (setq mm (cdr mm)))
  109. (cons ht nil)))
  110. (t (cons (1+ head)
  111. (cons (cons key value)
  112. (cdr mm))))))))
  113. (defun rng-ipattern-maybe-init ()
  114. (unless rng-ipattern-table
  115. (setq rng-ipattern-table (make-hash-table :test 'equal))
  116. (setq rng-last-ipattern-index -1)))
  117. (defun rng-ipattern-clear ()
  118. (when rng-ipattern-table
  119. (clrhash rng-ipattern-table))
  120. (setq rng-last-ipattern-index -1))
  121. (defsubst rng-gen-ipattern-index ()
  122. (setq rng-last-ipattern-index (1+ rng-last-ipattern-index)))
  123. (defun rng-put-ipattern (key type name-class child nullable)
  124. (let ((ipattern
  125. (rng-make-ipattern type
  126. (rng-gen-ipattern-index)
  127. name-class
  128. child
  129. nullable)))
  130. (puthash key ipattern rng-ipattern-table)
  131. ipattern))
  132. (defun rng-get-ipattern (key)
  133. (gethash key rng-ipattern-table))
  134. (or rng-not-allowed-ipattern
  135. (setq rng-not-allowed-ipattern
  136. (rng-make-ipattern 'not-allowed -3 nil nil nil)))
  137. (or rng-empty-ipattern
  138. (setq rng-empty-ipattern
  139. (rng-make-ipattern 'empty -2 nil nil t)))
  140. (or rng-text-ipattern
  141. (setq rng-text-ipattern
  142. (rng-make-ipattern 'text -1 nil nil t)))
  143. (defconst rng-const-ipatterns
  144. (list rng-not-allowed-ipattern
  145. rng-empty-ipattern
  146. rng-text-ipattern))
  147. (defun rng-intern-after (child after)
  148. (if (eq child rng-not-allowed-ipattern)
  149. rng-not-allowed-ipattern
  150. (let ((key (list 'after
  151. (rng--ipattern-index child)
  152. (rng--ipattern-index after))))
  153. (or (rng-get-ipattern key)
  154. (rng-put-ipattern key
  155. 'after
  156. after
  157. child
  158. nil)))))
  159. (defun rng-intern-attribute (name-class ipattern)
  160. (if (eq ipattern rng-not-allowed-ipattern)
  161. rng-not-allowed-ipattern
  162. (let ((key (list 'attribute
  163. name-class
  164. (rng--ipattern-index ipattern))))
  165. (or (rng-get-ipattern key)
  166. (rng-put-ipattern key
  167. 'attribute
  168. name-class
  169. ipattern
  170. nil)))))
  171. (defun rng-intern-data (dt matches-anything)
  172. (let ((key (list 'data dt)))
  173. (or (rng-get-ipattern key)
  174. (let ((ipattern (rng-put-ipattern key
  175. 'data
  176. dt
  177. nil
  178. matches-anything)))
  179. (setf (rng--ipattern-memo-text-typed ipattern)
  180. (not matches-anything))
  181. ipattern))))
  182. (defun rng-intern-data-except (dt ipattern)
  183. (let ((key (list 'data-except dt ipattern)))
  184. (or (rng-get-ipattern key)
  185. (rng-put-ipattern key
  186. 'data-except
  187. dt
  188. ipattern
  189. nil))))
  190. (defun rng-intern-value (dt obj)
  191. (let ((key (list 'value dt obj)))
  192. (or (rng-get-ipattern key)
  193. (rng-put-ipattern key
  194. 'value
  195. dt
  196. obj
  197. nil))))
  198. (defun rng-intern-one-or-more (ipattern)
  199. (or (rng-intern-one-or-more-shortcut ipattern)
  200. (let ((key (cons 'one-or-more
  201. (list (rng--ipattern-index ipattern)))))
  202. (or (rng-get-ipattern key)
  203. (rng-put-ipattern key
  204. 'one-or-more
  205. nil
  206. ipattern
  207. (rng--ipattern-nullable ipattern))))))
  208. (defun rng-intern-one-or-more-shortcut (ipattern)
  209. (cond ((eq ipattern rng-not-allowed-ipattern)
  210. rng-not-allowed-ipattern)
  211. ((eq ipattern rng-empty-ipattern)
  212. rng-empty-ipattern)
  213. ((eq (rng--ipattern-type ipattern) 'one-or-more)
  214. ipattern)
  215. (t nil)))
  216. (defun rng-intern-list (ipattern)
  217. (if (eq ipattern rng-not-allowed-ipattern)
  218. rng-not-allowed-ipattern
  219. (let ((key (cons 'list
  220. (list (rng--ipattern-index ipattern)))))
  221. (or (rng-get-ipattern key)
  222. (rng-put-ipattern key
  223. 'list
  224. nil
  225. ipattern
  226. nil)))))
  227. (defun rng-intern-group (ipatterns)
  228. "Return an ipattern for the list of group members in IPATTERNS."
  229. (or (rng-intern-group-shortcut ipatterns)
  230. (let* ((tem (rng-normalize-group-list ipatterns))
  231. (normalized (cdr tem)))
  232. (or (rng-intern-group-shortcut normalized)
  233. (let ((key (cons 'group
  234. (mapcar #'rng--ipattern-index normalized))))
  235. (or (rng-get-ipattern key)
  236. (rng-put-ipattern key
  237. 'group
  238. nil
  239. normalized
  240. (car tem))))))))
  241. (defun rng-intern-group-shortcut (ipatterns)
  242. "Try to shortcut interning a group list.
  243. If successful, return the interned pattern. Otherwise return nil."
  244. (while (and ipatterns
  245. (eq (car ipatterns) rng-empty-ipattern))
  246. (setq ipatterns (cdr ipatterns)))
  247. (if ipatterns
  248. (let ((ret (car ipatterns)))
  249. (if (eq ret rng-not-allowed-ipattern)
  250. rng-not-allowed-ipattern
  251. (setq ipatterns (cdr ipatterns))
  252. (while (and ipatterns ret)
  253. (let ((tem (car ipatterns)))
  254. (cond ((eq tem rng-not-allowed-ipattern)
  255. (setq ret tem)
  256. (setq ipatterns nil))
  257. ((eq tem rng-empty-ipattern)
  258. (setq ipatterns (cdr ipatterns)))
  259. (t
  260. ;; Stop here rather than continuing
  261. ;; looking for not-allowed patterns.
  262. ;; We do a complete scan elsewhere.
  263. (setq ret nil)))))
  264. ret))
  265. rng-empty-ipattern))
  266. (defun rng-normalize-group-list (ipatterns)
  267. "Normalize a list containing members of a group.
  268. Expands nested groups, removes empty members, handles notAllowed.
  269. Returns a pair whose car says whether the list is nullable and whose
  270. cdr is the normalized list."
  271. (let ((nullable t)
  272. (result nil)
  273. member)
  274. (while ipatterns
  275. (setq member (car ipatterns))
  276. (setq ipatterns (cdr ipatterns))
  277. (when nullable
  278. (setq nullable (rng--ipattern-nullable member)))
  279. (cond ((eq (rng--ipattern-type member) 'group)
  280. (setq result
  281. (nconc (reverse (rng--ipattern-child member))
  282. result)))
  283. ((eq member rng-not-allowed-ipattern)
  284. (setq result (list rng-not-allowed-ipattern))
  285. (setq ipatterns nil))
  286. ((not (eq member rng-empty-ipattern))
  287. (setq result (cons member result)))))
  288. (cons nullable (nreverse result))))
  289. (defun rng-intern-interleave (ipatterns)
  290. (or (rng-intern-group-shortcut ipatterns)
  291. (let* ((tem (rng-normalize-interleave-list ipatterns))
  292. (normalized (cdr tem)))
  293. (or (rng-intern-group-shortcut normalized)
  294. (let ((key (cons 'interleave
  295. (mapcar #'rng--ipattern-index normalized))))
  296. (or (rng-get-ipattern key)
  297. (rng-put-ipattern key
  298. 'interleave
  299. nil
  300. normalized
  301. (car tem))))))))
  302. (defun rng-normalize-interleave-list (ipatterns)
  303. "Normalize a list containing members of an interleave.
  304. Expands nested groups, removes empty members, handles notAllowed.
  305. Returns a pair whose car says whether the list is nullable and whose
  306. cdr is the normalized list."
  307. (let ((nullable t)
  308. (result nil)
  309. member)
  310. (while ipatterns
  311. (setq member (car ipatterns))
  312. (setq ipatterns (cdr ipatterns))
  313. (when nullable
  314. (setq nullable (rng--ipattern-nullable member)))
  315. (cond ((eq (rng--ipattern-type member) 'interleave)
  316. (setq result
  317. (append (rng--ipattern-child member)
  318. result)))
  319. ((eq member rng-not-allowed-ipattern)
  320. (setq result (list rng-not-allowed-ipattern))
  321. (setq ipatterns nil))
  322. ((not (eq member rng-empty-ipattern))
  323. (setq result (cons member result)))))
  324. (cons nullable (sort result 'rng-compare-ipattern))))
  325. ;; Would be cleaner if this didn't modify IPATTERNS.
  326. (defun rng-intern-choice (ipatterns)
  327. "Return a choice ipattern for the list of choices in IPATTERNS.
  328. May alter IPATTERNS."
  329. (or (rng-intern-choice-shortcut ipatterns)
  330. (let* ((tem (rng-normalize-choice-list ipatterns))
  331. (normalized (cdr tem)))
  332. (or (rng-intern-choice-shortcut normalized)
  333. (rng-intern-choice1 normalized (car tem))))))
  334. (defun rng-intern-optional (ipattern)
  335. (cond ((rng--ipattern-nullable ipattern) ipattern)
  336. ((eq ipattern rng-not-allowed-ipattern) rng-empty-ipattern)
  337. (t (rng-intern-choice1
  338. ;; This is sorted since the empty pattern
  339. ;; is before everything except not allowed.
  340. ;; It cannot have a duplicate empty pattern,
  341. ;; since it is not nullable.
  342. (cons rng-empty-ipattern
  343. (if (eq (rng--ipattern-type ipattern) 'choice)
  344. (rng--ipattern-child ipattern)
  345. (list ipattern)))
  346. t))))
  347. (defun rng-intern-choice1 (normalized nullable)
  348. (let ((key (cons 'choice
  349. (mapcar #'rng--ipattern-index normalized))))
  350. (or (rng-get-ipattern key)
  351. (rng-put-ipattern key
  352. 'choice
  353. nil
  354. normalized
  355. nullable))))
  356. (defun rng-intern-choice-shortcut (ipatterns)
  357. "Try to shortcut interning a choice list.
  358. If successful, return the interned pattern. Otherwise return nil."
  359. (while (and ipatterns
  360. (eq (car ipatterns)
  361. rng-not-allowed-ipattern))
  362. (setq ipatterns (cdr ipatterns)))
  363. (if ipatterns
  364. (let ((ret (car ipatterns)))
  365. (setq ipatterns (cdr ipatterns))
  366. (while (and ipatterns ret)
  367. (or (eq (car ipatterns) rng-not-allowed-ipattern)
  368. (eq (car ipatterns) ret)
  369. (setq ret nil))
  370. (setq ipatterns (cdr ipatterns)))
  371. ret)
  372. rng-not-allowed-ipattern))
  373. (defun rng-normalize-choice-list (ipatterns)
  374. "Normalize a list of choices.
  375. Expands nested choices, removes not-allowed members, sorts by index
  376. and removes duplicates. Return a pair whose car says whether the
  377. list is nullable and whose cdr is the normalized list."
  378. (let ((sorted t)
  379. (nullable nil)
  380. (head (cons nil ipatterns)))
  381. (let ((tail head)
  382. (final-tail nil)
  383. (prev-index -100)
  384. (cur ipatterns)
  385. member)
  386. ;; the cdr of tail is always cur
  387. (while cur
  388. (setq member (car cur))
  389. (or nullable
  390. (setq nullable (rng--ipattern-nullable member)))
  391. (cond ((eq (rng--ipattern-type member) 'choice)
  392. (setq final-tail
  393. (append (rng--ipattern-child member)
  394. final-tail))
  395. (setq cur (cdr cur))
  396. (setq sorted nil)
  397. (setcdr tail cur))
  398. ((eq member rng-not-allowed-ipattern)
  399. (setq cur (cdr cur))
  400. (setcdr tail cur))
  401. (t
  402. (if (and sorted
  403. (let ((cur-index (rng--ipattern-index member)))
  404. (if (>= prev-index cur-index)
  405. (or (= prev-index cur-index) ; will remove it
  406. (setq sorted nil)) ; won't remove it
  407. (setq prev-index cur-index)
  408. ;; won't remove it
  409. nil)))
  410. (progn
  411. ;; remove it
  412. (setq cur (cdr cur))
  413. (setcdr tail cur))
  414. ;; don't remove it
  415. (setq tail cur)
  416. (setq cur (cdr cur))))))
  417. (setcdr tail final-tail))
  418. (setq head (cdr head))
  419. (cons nullable
  420. (if sorted
  421. head
  422. (rng-uniquify-eq (sort head 'rng-compare-ipattern))))))
  423. (defun rng-compare-ipattern (p1 p2)
  424. (< (rng--ipattern-index p1)
  425. (rng--ipattern-index p2)))
  426. ;;; Name classes
  427. (defsubst rng-name-class-contains (nc nm)
  428. (if (consp nc)
  429. (equal nm nc)
  430. (rng-name-class-contains1 nc nm)))
  431. (defun rng-name-class-contains1 (nc nm)
  432. (let ((type (aref nc 0)))
  433. (cond ((eq type 'any-name) t)
  434. ((eq type 'any-name-except)
  435. (not (rng-name-class-contains (aref nc 1) nm)))
  436. ((eq type 'ns-name)
  437. (eq (car nm) (aref nc 1)))
  438. ((eq type 'ns-name-except)
  439. (and (eq (car nm) (aref nc 1))
  440. (not (rng-name-class-contains (aref nc 2) nm))))
  441. ((eq type 'choice)
  442. (let ((choices (aref nc 1))
  443. (ret nil))
  444. (while choices
  445. (if (rng-name-class-contains (car choices) nm)
  446. (progn
  447. (setq choices nil)
  448. (setq ret t))
  449. (setq choices (cdr choices))))
  450. ret)))))
  451. (defun rng-name-class-possible-names (nc accum)
  452. "Return a list of possible names that nameclass NC can match.
  453. Each possible name should be returned as a (NAMESPACE . LOCAL-NAME)
  454. pair, where NAMESPACE is a symbol or nil and LOCAL-NAME is a string.
  455. NAMESPACE, if nil, matches the absent namespace. ACCUM is a list of
  456. names which should be appended to the returned list. The returned
  457. list may contain duplicates."
  458. (if (consp nc)
  459. (cons nc accum)
  460. (when (eq (aref nc 0) 'choice)
  461. (let ((members (aref nc 1)) member)
  462. (while members
  463. (setq member (car members))
  464. (setq accum
  465. (if (consp member)
  466. (cons member accum)
  467. (rng-name-class-possible-names member
  468. accum)))
  469. (setq members (cdr members)))))
  470. accum))
  471. ;;; Debugging utilities
  472. (defun rng-ipattern-to-string (ipattern)
  473. (let ((type (rng--ipattern-type ipattern)))
  474. (cond ((eq type 'after)
  475. (concat (rng-ipattern-to-string
  476. (rng--ipattern-child ipattern))
  477. " </> "
  478. (rng-ipattern-to-string
  479. (rng--ipattern-after ipattern))))
  480. ((eq type 'element)
  481. (concat "element "
  482. (rng-name-class-to-string
  483. (rng--ipattern-name-class ipattern))
  484. ;; we can get cycles with elements so don't print it out
  485. " {...}"))
  486. ((eq type 'attribute)
  487. (concat "attribute "
  488. (rng-name-class-to-string
  489. (rng--ipattern-name-class ipattern))
  490. " { "
  491. (rng-ipattern-to-string
  492. (rng--ipattern-child ipattern))
  493. " } "))
  494. ((eq type 'empty) "empty")
  495. ((eq type 'text) "text")
  496. ((eq type 'not-allowed) "notAllowed")
  497. ((eq type 'one-or-more)
  498. (concat (rng-ipattern-to-string
  499. (rng--ipattern-child ipattern))
  500. "+"))
  501. ((eq type 'choice)
  502. (concat "("
  503. (mapconcat 'rng-ipattern-to-string
  504. (rng--ipattern-child ipattern)
  505. " | ")
  506. ")"))
  507. ((eq type 'group)
  508. (concat "("
  509. (mapconcat 'rng-ipattern-to-string
  510. (rng--ipattern-child ipattern)
  511. ", ")
  512. ")"))
  513. ((eq type 'interleave)
  514. (concat "("
  515. (mapconcat 'rng-ipattern-to-string
  516. (rng--ipattern-child ipattern)
  517. " & ")
  518. ")"))
  519. (t (symbol-name type)))))
  520. (defun rng-name-class-to-string (nc)
  521. (if (consp nc)
  522. (cdr nc)
  523. (let ((type (aref nc 0)))
  524. (cond ((eq type 'choice)
  525. (mapconcat 'rng-name-class-to-string
  526. (aref nc 1)
  527. "|"))
  528. (t (concat (symbol-name type) "*"))))))
  529. ;;; Compiling
  530. (defun rng-compile-maybe-init ()
  531. (unless rng-compile-table
  532. (setq rng-compile-table (make-hash-table :test 'eq))))
  533. (defun rng-compile-clear ()
  534. (when rng-compile-table
  535. (clrhash rng-compile-table)))
  536. (defun rng-compile (pattern)
  537. (or (gethash pattern rng-compile-table)
  538. (let ((ipattern (apply (get (car pattern) 'rng-compile)
  539. (cdr pattern))))
  540. (puthash pattern ipattern rng-compile-table)
  541. ipattern)))
  542. (put 'empty 'rng-compile 'rng-compile-empty)
  543. (put 'text 'rng-compile 'rng-compile-text)
  544. (put 'not-allowed 'rng-compile 'rng-compile-not-allowed)
  545. (put 'element 'rng-compile 'rng-compile-element)
  546. (put 'attribute 'rng-compile 'rng-compile-attribute)
  547. (put 'choice 'rng-compile 'rng-compile-choice)
  548. (put 'optional 'rng-compile 'rng-compile-optional)
  549. (put 'group 'rng-compile 'rng-compile-group)
  550. (put 'interleave 'rng-compile 'rng-compile-interleave)
  551. (put 'ref 'rng-compile 'rng-compile-ref)
  552. (put 'one-or-more 'rng-compile 'rng-compile-one-or-more)
  553. (put 'zero-or-more 'rng-compile 'rng-compile-zero-or-more)
  554. (put 'mixed 'rng-compile 'rng-compile-mixed)
  555. (put 'data 'rng-compile 'rng-compile-data)
  556. (put 'data-except 'rng-compile 'rng-compile-data-except)
  557. (put 'value 'rng-compile 'rng-compile-value)
  558. (put 'list 'rng-compile 'rng-compile-list)
  559. (defun rng-compile-not-allowed () rng-not-allowed-ipattern)
  560. (defun rng-compile-empty () rng-empty-ipattern)
  561. (defun rng-compile-text () rng-text-ipattern)
  562. (defun rng-compile-element (name-class pattern)
  563. ;; don't intern
  564. (rng-make-ipattern 'element
  565. (rng-gen-ipattern-index)
  566. (rng-compile-name-class name-class)
  567. pattern ; compile lazily
  568. nil))
  569. (defun rng-element-get-child (element)
  570. (let ((tem (rng--ipattern-child element)))
  571. (if (vectorp tem)
  572. tem
  573. (setf (rng--ipattern-child element) (rng-compile tem)))))
  574. (defun rng-compile-attribute (name-class pattern)
  575. (rng-intern-attribute (rng-compile-name-class name-class)
  576. (rng-compile pattern)))
  577. (defun rng-compile-ref (pattern name)
  578. (and (memq pattern rng-being-compiled)
  579. (rng-compile-error "Reference loop on symbol %s" name))
  580. (setq rng-being-compiled
  581. (cons pattern rng-being-compiled))
  582. (unwind-protect
  583. (rng-compile pattern)
  584. (setq rng-being-compiled
  585. (cdr rng-being-compiled))))
  586. (defun rng-compile-one-or-more (pattern)
  587. (rng-intern-one-or-more (rng-compile pattern)))
  588. (defun rng-compile-zero-or-more (pattern)
  589. (rng-intern-optional
  590. (rng-intern-one-or-more (rng-compile pattern))))
  591. (defun rng-compile-optional (pattern)
  592. (rng-intern-optional (rng-compile pattern)))
  593. (defun rng-compile-mixed (pattern)
  594. (rng-intern-interleave (cons rng-text-ipattern
  595. (list (rng-compile pattern)))))
  596. (defun rng-compile-list (pattern)
  597. (rng-intern-list (rng-compile pattern)))
  598. (defun rng-compile-choice (&rest patterns)
  599. (rng-intern-choice (mapcar 'rng-compile patterns)))
  600. (defun rng-compile-group (&rest patterns)
  601. (rng-intern-group (mapcar 'rng-compile patterns)))
  602. (defun rng-compile-interleave (&rest patterns)
  603. (rng-intern-interleave (mapcar 'rng-compile patterns)))
  604. (defun rng-compile-dt (name params)
  605. (let ((rng-dt-error-reporter 'rng-compile-error))
  606. (funcall (let ((uri (car name)))
  607. (or (get uri 'rng-dt-compile)
  608. (rng-compile-error "Unknown datatype library %s" uri)))
  609. (cdr name)
  610. params)))
  611. (defun rng-compile-data (name params)
  612. (let ((dt (rng-compile-dt name params)))
  613. (rng-intern-data (cdr dt) (car dt))))
  614. (defun rng-compile-data-except (name params pattern)
  615. (rng-intern-data-except (cdr (rng-compile-dt name params))
  616. (rng-compile pattern)))
  617. (defun rng-compile-value (name str context)
  618. (let* ((dt (cdr (rng-compile-dt name '())))
  619. (rng-dt-namespace-context-getter (list 'identity context))
  620. (obj (rng-dt-make-value dt str)))
  621. (if obj
  622. (rng-intern-value dt obj)
  623. (rng-compile-error "Value %s is not a valid instance of the datatype %s"
  624. str
  625. name))))
  626. (defun rng-compile-name-class (nc)
  627. (let ((type (car nc)))
  628. (cond ((eq type 'name) (nth 1 nc))
  629. ((eq type 'any-name) [any-name])
  630. ((eq type 'any-name-except)
  631. (vector 'any-name-except
  632. (rng-compile-name-class (nth 1 nc))))
  633. ((eq type 'ns-name)
  634. (vector 'ns-name (nth 1 nc)))
  635. ((eq type 'ns-name-except)
  636. (vector 'ns-name-except
  637. (nth 1 nc)
  638. (rng-compile-name-class (nth 2 nc))))
  639. ((eq type 'choice)
  640. (vector 'choice
  641. (mapcar 'rng-compile-name-class (cdr nc))))
  642. (t (error "Bad name-class type %s" type)))))
  643. ;;; Searching patterns
  644. ;; We write this non-recursively to avoid hitting max-lisp-eval-depth
  645. ;; on large schemas.
  646. (defun rng-map-element-attribute (function pattern accum &rest args)
  647. (let ((searched (make-hash-table :test 'eq))
  648. type todo patterns)
  649. (while (progn
  650. (setq type (car pattern))
  651. (cond ((memq type '(element attribute))
  652. (setq accum
  653. (apply function
  654. (cons pattern
  655. (cons accum args))))
  656. (setq pattern (nth 2 pattern)))
  657. ((eq type 'ref)
  658. (setq pattern (nth 1 pattern))
  659. (if (gethash pattern searched)
  660. (setq pattern nil)
  661. (puthash pattern t searched)))
  662. ((memq type '(choice group interleave))
  663. (setq todo (cons (cdr pattern) todo))
  664. (setq pattern nil))
  665. ((memq type '(one-or-more
  666. zero-or-more
  667. optional
  668. mixed))
  669. (setq pattern (nth 1 pattern)))
  670. (t (setq pattern nil)))
  671. (cond (pattern)
  672. (patterns
  673. (setq pattern (car patterns))
  674. (setq patterns (cdr patterns))
  675. t)
  676. (todo
  677. (setq patterns (car todo))
  678. (setq todo (cdr todo))
  679. (setq pattern (car patterns))
  680. (setq patterns (cdr patterns))
  681. t))))
  682. accum))
  683. (defun rng-find-element-content-pattern (pattern accum name)
  684. (if (and (eq (car pattern) 'element)
  685. (rng-search-name name (nth 1 pattern)))
  686. (cons (rng-compile (nth 2 pattern)) accum)
  687. accum))
  688. (defun rng-search-name (name nc)
  689. (let ((type (car nc)))
  690. (cond ((eq type 'name)
  691. (equal (cadr nc) name))
  692. ((eq type 'choice)
  693. (let ((choices (cdr nc))
  694. (found nil))
  695. (while (and choices (not found))
  696. (if (rng-search-name name (car choices))
  697. (setq found t)
  698. (setq choices (cdr choices))))
  699. found))
  700. (t nil))))
  701. (defun rng-find-name-class-uris (nc accum)
  702. (let ((type (car nc)))
  703. (cond ((eq type 'name)
  704. (rng-accum-namespace-uri (car (nth 1 nc)) accum))
  705. ((memq type '(ns-name ns-name-except))
  706. (rng-accum-namespace-uri (nth 1 nc) accum))
  707. ((eq type 'choice)
  708. (let ((choices (cdr nc)))
  709. (while choices
  710. (setq accum
  711. (rng-find-name-class-uris (car choices) accum))
  712. (setq choices (cdr choices))))
  713. accum)
  714. (t accum))))
  715. (defun rng-accum-namespace-uri (ns accum)
  716. (if (and ns (not (memq ns accum)))
  717. (cons ns accum)
  718. accum))
  719. ;;; Derivatives
  720. (defun rng-ipattern-text-typed-p (ipattern)
  721. (let ((memo (rng--ipattern-memo-text-typed ipattern)))
  722. (if (eq memo 'unknown)
  723. (setf (rng--ipattern-memo-text-typed ipattern)
  724. (rng-ipattern-compute-text-typed-p ipattern))
  725. memo)))
  726. (defun rng-ipattern-compute-text-typed-p (ipattern)
  727. (let ((type (rng--ipattern-type ipattern)))
  728. (cond ((eq type 'choice)
  729. (let ((cur (rng--ipattern-child ipattern))
  730. (ret nil))
  731. (while (and cur (not ret))
  732. (if (rng-ipattern-text-typed-p (car cur))
  733. (setq ret t)
  734. (setq cur (cdr cur))))
  735. ret))
  736. ((eq type 'group)
  737. (let ((cur (rng--ipattern-child ipattern))
  738. (ret nil)
  739. member)
  740. (while (and cur (not ret))
  741. (setq member (car cur))
  742. (if (rng-ipattern-text-typed-p member)
  743. (setq ret t))
  744. (setq cur
  745. (and (rng--ipattern-nullable member)
  746. (cdr cur))))
  747. ret))
  748. ((eq type 'after)
  749. (rng-ipattern-text-typed-p (rng--ipattern-child ipattern)))
  750. (t (and (memq type '(value list data data-except)) t)))))
  751. (defun rng-start-tag-open-deriv (ipattern nm)
  752. (or (rng-memo-map-get
  753. nm
  754. (rng--ipattern-memo-map-start-tag-open-deriv ipattern))
  755. (rng-ipattern-memo-start-tag-open-deriv
  756. ipattern
  757. nm
  758. (rng-compute-start-tag-open-deriv ipattern nm))))
  759. (defun rng-ipattern-memo-start-tag-open-deriv (ipattern nm deriv)
  760. (or (memq ipattern rng-const-ipatterns)
  761. (setf (rng--ipattern-memo-map-start-tag-open-deriv ipattern)
  762. (rng-memo-map-add nm
  763. deriv
  764. (rng--ipattern-memo-map-start-tag-open-deriv
  765. ipattern))))
  766. deriv)
  767. (defun rng-compute-start-tag-open-deriv (ipattern nm)
  768. (let ((type (rng--ipattern-type ipattern)))
  769. (cond ((eq type 'choice)
  770. (rng-transform-choice (lambda (p)
  771. (rng-start-tag-open-deriv p nm))
  772. ipattern))
  773. ((eq type 'element)
  774. (if (rng-name-class-contains
  775. (rng--ipattern-name-class ipattern)
  776. nm)
  777. (rng-intern-after (rng-element-get-child ipattern)
  778. rng-empty-ipattern)
  779. rng-not-allowed-ipattern))
  780. ((eq type 'group)
  781. (rng-transform-group-nullable
  782. (lambda (p) (rng-start-tag-open-deriv p nm))
  783. 'rng-cons-group-after
  784. ipattern))
  785. ((eq type 'interleave)
  786. (rng-transform-interleave-single
  787. (lambda (p) (rng-start-tag-open-deriv p nm))
  788. 'rng-subst-interleave-after
  789. ipattern))
  790. ((eq type 'one-or-more)
  791. (let ((ip (rng-intern-optional ipattern)))
  792. (rng-apply-after
  793. (lambda (p) (rng-intern-group (list p ip)))
  794. (rng-start-tag-open-deriv (rng--ipattern-child ipattern)
  795. nm))))
  796. ((eq type 'after)
  797. (let ((nip (rng--ipattern-after ipattern)))
  798. (rng-apply-after
  799. (lambda (p) (rng-intern-after p nip))
  800. (rng-start-tag-open-deriv (rng--ipattern-child ipattern)
  801. nm))))
  802. (t rng-not-allowed-ipattern))))
  803. (defun rng-start-attribute-deriv (ipattern nm)
  804. (or (rng-memo-map-get
  805. nm
  806. (rng--ipattern-memo-map-start-attribute-deriv ipattern))
  807. (rng-ipattern-memo-start-attribute-deriv
  808. ipattern
  809. nm
  810. (rng-compute-start-attribute-deriv ipattern nm))))
  811. (defun rng-ipattern-memo-start-attribute-deriv (ipattern nm deriv)
  812. (or (memq ipattern rng-const-ipatterns)
  813. (setf (rng--ipattern-memo-map-start-attribute-deriv ipattern)
  814. (rng-memo-map-add
  815. nm
  816. deriv
  817. (rng--ipattern-memo-map-start-attribute-deriv ipattern))))
  818. deriv)
  819. (defun rng-compute-start-attribute-deriv (ipattern nm)
  820. (let ((type (rng--ipattern-type ipattern)))
  821. (cond ((eq type 'choice)
  822. (rng-transform-choice (lambda (p)
  823. (rng-start-attribute-deriv p nm))
  824. ipattern))
  825. ((eq type 'attribute)
  826. (if (rng-name-class-contains
  827. (rng--ipattern-name-class ipattern)
  828. nm)
  829. (rng-intern-after (rng--ipattern-child ipattern)
  830. rng-empty-ipattern)
  831. rng-not-allowed-ipattern))
  832. ((eq type 'group)
  833. (rng-transform-interleave-single
  834. (lambda (p) (rng-start-attribute-deriv p nm))
  835. 'rng-subst-group-after
  836. ipattern))
  837. ((eq type 'interleave)
  838. (rng-transform-interleave-single
  839. (lambda (p) (rng-start-attribute-deriv p nm))
  840. 'rng-subst-interleave-after
  841. ipattern))
  842. ((eq type 'one-or-more)
  843. (let ((ip (rng-intern-optional ipattern)))
  844. (rng-apply-after
  845. (lambda (p) (rng-intern-group (list p ip)))
  846. (rng-start-attribute-deriv (rng--ipattern-child ipattern)
  847. nm))))
  848. ((eq type 'after)
  849. (let ((nip (rng--ipattern-after ipattern)))
  850. (rng-apply-after
  851. (lambda (p) (rng-intern-after p nip))
  852. (rng-start-attribute-deriv (rng--ipattern-child ipattern)
  853. nm))))
  854. (t rng-not-allowed-ipattern))))
  855. (defun rng-cons-group-after (x y)
  856. (rng-apply-after (lambda (p) (rng-intern-group (cons p y)))
  857. x))
  858. (defun rng-subst-group-after (new old list)
  859. (rng-apply-after (lambda (p)
  860. (rng-intern-group (rng-substq p old list)))
  861. new))
  862. (defun rng-subst-interleave-after (new old list)
  863. (rng-apply-after (lambda (p)
  864. (rng-intern-interleave (rng-substq p old list)))
  865. new))
  866. (defun rng-apply-after (f ipattern)
  867. (let ((type (rng--ipattern-type ipattern)))
  868. (cond ((eq type 'after)
  869. (rng-intern-after
  870. (rng--ipattern-child ipattern)
  871. (funcall f (rng--ipattern-after ipattern))))
  872. ((eq type 'choice)
  873. (rng-transform-choice (lambda (x) (rng-apply-after f x))
  874. ipattern))
  875. (t rng-not-allowed-ipattern))))
  876. (defun rng-start-tag-close-deriv (ipattern)
  877. (or (rng--ipattern-memo-start-tag-close-deriv ipattern)
  878. (setf (rng--ipattern-memo-start-tag-close-deriv ipattern)
  879. (rng-compute-start-tag-close-deriv ipattern))))
  880. (defconst rng-transform-map
  881. '((choice . rng-transform-choice)
  882. (group . rng-transform-group)
  883. (interleave . rng-transform-interleave)
  884. (one-or-more . rng-transform-one-or-more)
  885. (after . rng-transform-after-child)))
  886. (defun rng-compute-start-tag-close-deriv (ipattern)
  887. (let* ((type (rng--ipattern-type ipattern)))
  888. (if (eq type 'attribute)
  889. rng-not-allowed-ipattern
  890. (let ((transform (assq type rng-transform-map)))
  891. (if transform
  892. (funcall (cdr transform)
  893. 'rng-start-tag-close-deriv
  894. ipattern)
  895. ipattern)))))
  896. (defun rng-ignore-attributes-deriv (ipattern)
  897. (let* ((type (rng--ipattern-type ipattern)))
  898. (if (eq type 'attribute)
  899. rng-empty-ipattern
  900. (let ((transform (assq type rng-transform-map)))
  901. (if transform
  902. (funcall (cdr transform)
  903. 'rng-ignore-attributes-deriv
  904. ipattern)
  905. ipattern)))))
  906. (defun rng-text-only-deriv (ipattern)
  907. (or (rng--ipattern-memo-text-only-deriv ipattern)
  908. (setf (rng--ipattern-memo-text-only-deriv ipattern)
  909. (rng-compute-text-only-deriv ipattern))))
  910. (defun rng-compute-text-only-deriv (ipattern)
  911. (let* ((type (rng--ipattern-type ipattern)))
  912. (if (eq type 'element)
  913. rng-not-allowed-ipattern
  914. (let ((transform (assq type
  915. '((choice . rng-transform-choice)
  916. (group . rng-transform-group)
  917. (interleave . rng-transform-interleave)
  918. (one-or-more . rng-transform-one-or-more)
  919. (after . rng-transform-after-child)))))
  920. (if transform
  921. (funcall (cdr transform)
  922. 'rng-text-only-deriv
  923. ipattern)
  924. ipattern)))))
  925. (defun rng-mixed-text-deriv (ipattern)
  926. (or (rng--ipattern-memo-mixed-text-deriv ipattern)
  927. (setf (rng--ipattern-memo-mixed-text-deriv ipattern)
  928. (rng-compute-mixed-text-deriv ipattern))))
  929. (defun rng-compute-mixed-text-deriv (ipattern)
  930. (let ((type (rng--ipattern-type ipattern)))
  931. (cond ((eq type 'text) ipattern)
  932. ((eq type 'after)
  933. (rng-transform-after-child 'rng-mixed-text-deriv
  934. ipattern))
  935. ((eq type 'choice)
  936. (rng-transform-choice 'rng-mixed-text-deriv
  937. ipattern))
  938. ((eq type 'one-or-more)
  939. (rng-intern-group
  940. (list (rng-mixed-text-deriv
  941. (rng--ipattern-child ipattern))
  942. (rng-intern-optional ipattern))))
  943. ((eq type 'group)
  944. (rng-transform-group-nullable
  945. 'rng-mixed-text-deriv
  946. (lambda (x y) (rng-intern-group (cons x y)))
  947. ipattern))
  948. ((eq type 'interleave)
  949. (rng-transform-interleave-single
  950. 'rng-mixed-text-deriv
  951. (lambda (new old list) (rng-intern-interleave
  952. (rng-substq new old list)))
  953. ipattern))
  954. ((and (eq type 'data)
  955. (not (rng--ipattern-memo-text-typed ipattern)))
  956. ipattern)
  957. (t rng-not-allowed-ipattern))))
  958. (defun rng-end-tag-deriv (ipattern)
  959. (or (rng--ipattern-memo-end-tag-deriv ipattern)
  960. (setf (rng--ipattern-memo-end-tag-deriv ipattern)
  961. (rng-compute-end-tag-deriv ipattern))))
  962. (defun rng-compute-end-tag-deriv (ipattern)
  963. (let ((type (rng--ipattern-type ipattern)))
  964. (cond ((eq type 'choice)
  965. (rng-intern-choice
  966. (mapcar 'rng-end-tag-deriv
  967. (rng--ipattern-child ipattern))))
  968. ((eq type 'after)
  969. (if (rng--ipattern-nullable
  970. (rng--ipattern-child ipattern))
  971. (rng--ipattern-after ipattern)
  972. rng-not-allowed-ipattern))
  973. (t rng-not-allowed-ipattern))))
  974. (defun rng-data-deriv (ipattern value)
  975. (or (rng-memo-map-get value
  976. (rng--ipattern-memo-map-data-deriv ipattern))
  977. (and (rng-memo-map-get
  978. (cons value (rng-namespace-context-get-no-trace))
  979. (rng--ipattern-memo-map-data-deriv ipattern))
  980. (rng-memo-map-get
  981. (cons value (apply (car rng-dt-namespace-context-getter)
  982. (cdr rng-dt-namespace-context-getter)))
  983. (rng--ipattern-memo-map-data-deriv ipattern)))
  984. (let* ((used-context (vector nil))
  985. (rng-dt-namespace-context-getter
  986. (cons 'rng-namespace-context-tracer
  987. (cons used-context
  988. rng-dt-namespace-context-getter)))
  989. (deriv (rng-compute-data-deriv ipattern value)))
  990. (rng-ipattern-memo-data-deriv ipattern
  991. value
  992. (aref used-context 0)
  993. deriv))))
  994. (defun rng-namespace-context-tracer (used getter &rest args)
  995. (let ((context (apply getter args)))
  996. (aset used 0 context)
  997. context))
  998. (defun rng-namespace-context-get-no-trace ()
  999. (let ((tem rng-dt-namespace-context-getter))
  1000. (while (and tem (eq (car tem) 'rng-namespace-context-tracer))
  1001. (setq tem (cddr tem)))
  1002. (apply (car tem) (cdr tem))))
  1003. (defconst rng-memo-data-deriv-max-length 80
  1004. "Don't memoize data-derivs for values longer than this.")
  1005. (defun rng-ipattern-memo-data-deriv (ipattern value context deriv)
  1006. (or (memq ipattern rng-const-ipatterns)
  1007. (> (length value) rng-memo-data-deriv-max-length)
  1008. (setf (rng--ipattern-memo-map-data-deriv ipattern)
  1009. (rng-memo-map-add (if context (cons value context) value)
  1010. deriv
  1011. (rng--ipattern-memo-map-data-deriv ipattern)
  1012. t)))
  1013. deriv)
  1014. (defun rng-compute-data-deriv (ipattern value)
  1015. (let ((type (rng--ipattern-type ipattern)))
  1016. (cond ((eq type 'text) ipattern)
  1017. ((eq type 'choice)
  1018. (rng-transform-choice (lambda (p) (rng-data-deriv p value))
  1019. ipattern))
  1020. ((eq type 'group)
  1021. (rng-transform-group-nullable
  1022. (lambda (p) (rng-data-deriv p value))
  1023. (lambda (x y) (rng-intern-group (cons x y)))
  1024. ipattern))
  1025. ((eq type 'one-or-more)
  1026. (rng-intern-group (list (rng-data-deriv
  1027. (rng--ipattern-child ipattern)
  1028. value)
  1029. (rng-intern-optional ipattern))))
  1030. ((eq type 'after)
  1031. (let ((child (rng--ipattern-child ipattern)))
  1032. (if (or (rng--ipattern-nullable
  1033. (rng-data-deriv child value))
  1034. (and (rng--ipattern-nullable child)
  1035. (rng-blank-p value)))
  1036. (rng--ipattern-after ipattern)
  1037. rng-not-allowed-ipattern)))
  1038. ((eq type 'data)
  1039. (if (rng-dt-make-value (rng--ipattern-datatype ipattern)
  1040. value)
  1041. rng-empty-ipattern
  1042. rng-not-allowed-ipattern))
  1043. ((eq type 'data-except)
  1044. (if (and (rng-dt-make-value (rng--ipattern-datatype ipattern)
  1045. value)
  1046. (not (rng--ipattern-nullable
  1047. (rng-data-deriv
  1048. (rng--ipattern-child ipattern)
  1049. value))))
  1050. rng-empty-ipattern
  1051. rng-not-allowed-ipattern))
  1052. ((eq type 'value)
  1053. (if (equal (rng-dt-make-value (rng--ipattern-datatype ipattern)
  1054. value)
  1055. (rng--ipattern-value-object ipattern))
  1056. rng-empty-ipattern
  1057. rng-not-allowed-ipattern))
  1058. ((eq type 'list)
  1059. (let ((tokens (split-string value))
  1060. (state (rng--ipattern-child ipattern)))
  1061. (while (and tokens
  1062. (not (eq state rng-not-allowed-ipattern)))
  1063. (setq state (rng-data-deriv state (car tokens)))
  1064. (setq tokens (cdr tokens)))
  1065. (if (rng--ipattern-nullable state)
  1066. rng-empty-ipattern
  1067. rng-not-allowed-ipattern)))
  1068. ;; don't think interleave can occur
  1069. ;; since we do text-only-deriv first
  1070. (t rng-not-allowed-ipattern))))
  1071. (defun rng-transform-multi (f ipattern interner)
  1072. (let* ((members (rng--ipattern-child ipattern))
  1073. (transformed (mapcar f members)))
  1074. (if (rng-members-eq members transformed)
  1075. ipattern
  1076. (funcall interner transformed))))
  1077. (defun rng-transform-choice (f ipattern)
  1078. (rng-transform-multi f ipattern 'rng-intern-choice))
  1079. (defun rng-transform-group (f ipattern)
  1080. (rng-transform-multi f ipattern 'rng-intern-group))
  1081. (defun rng-transform-interleave (f ipattern)
  1082. (rng-transform-multi f ipattern 'rng-intern-interleave))
  1083. (defun rng-transform-one-or-more (f ipattern)
  1084. (let* ((child (rng--ipattern-child ipattern))
  1085. (transformed (funcall f child)))
  1086. (if (eq child transformed)
  1087. ipattern
  1088. (rng-intern-one-or-more transformed))))
  1089. (defun rng-transform-after-child (f ipattern)
  1090. (let* ((child (rng--ipattern-child ipattern))
  1091. (transformed (funcall f child)))
  1092. (if (eq child transformed)
  1093. ipattern
  1094. (rng-intern-after transformed
  1095. (rng--ipattern-after ipattern)))))
  1096. (defun rng-transform-interleave-single (f subster ipattern)
  1097. (let ((children (rng--ipattern-child ipattern))
  1098. found)
  1099. (while (and children (not found))
  1100. (let* ((child (car children))
  1101. (transformed (funcall f child)))
  1102. (if (eq transformed rng-not-allowed-ipattern)
  1103. (setq children (cdr children))
  1104. (setq found
  1105. (funcall subster
  1106. transformed
  1107. child
  1108. (rng--ipattern-child ipattern))))))
  1109. (or found
  1110. rng-not-allowed-ipattern)))
  1111. (defun rng-transform-group-nullable (f conser ipattern)
  1112. "Given a group x1,...,xn,y1,...,yn where the xs are all
  1113. nullable and y1 isn't, return a choice
  1114. (conser f(x1) x2,...,xm,y1,...,yn)
  1115. |(conser f(x2) x3,...,xm,y1,...,yn)
  1116. |...
  1117. |(conser f(xm) y1,...,yn)
  1118. |(conser f(y1) y2,...,yn)"
  1119. (rng-intern-choice
  1120. (rng-transform-group-nullable-gen-choices
  1121. f
  1122. conser
  1123. (rng--ipattern-child ipattern))))
  1124. (defun rng-transform-group-nullable-gen-choices (f conser members)
  1125. (let ((head (car members))
  1126. (tail (cdr members)))
  1127. (if tail
  1128. (cons (funcall conser (funcall f head) tail)
  1129. (if (rng--ipattern-nullable head)
  1130. (rng-transform-group-nullable-gen-choices f conser tail)
  1131. nil))
  1132. (list (funcall f head)))))
  1133. (defun rng-members-eq (list1 list2)
  1134. (while (and list1
  1135. list2
  1136. (eq (car list1) (car list2)))
  1137. (setq list1 (cdr list1))
  1138. (setq list2 (cdr list2)))
  1139. (and (null list1) (null list2)))
  1140. (defun rng-ipattern-after (ipattern)
  1141. (let ((type (rng--ipattern-type ipattern)))
  1142. (cond ((eq type 'choice)
  1143. (rng-transform-choice 'rng-ipattern-after ipattern))
  1144. ((eq type 'after)
  1145. (rng--ipattern-after ipattern))
  1146. ((eq type 'not-allowed)
  1147. ipattern)
  1148. (t (error "Internal error in rng-ipattern-after: unexpected type %s" type)))))
  1149. (defun rng-unknown-start-tag-open-deriv (ipattern)
  1150. (rng-intern-after (rng-compile rng-any-content) ipattern))
  1151. (defun rng-ipattern-optionalize-elements (ipattern)
  1152. (let* ((type (rng--ipattern-type ipattern))
  1153. (transform (assq type rng-transform-map)))
  1154. (cond (transform
  1155. (funcall (cdr transform)
  1156. 'rng-ipattern-optionalize-elements
  1157. ipattern))
  1158. ((eq type 'element)
  1159. (rng-intern-optional ipattern))
  1160. (t ipattern))))
  1161. (defun rng-ipattern-empty-before-p (ipattern)
  1162. (let ((type (rng--ipattern-type ipattern)))
  1163. (cond ((eq type 'after)
  1164. (eq (rng--ipattern-child ipattern) rng-empty-ipattern))
  1165. ((eq type 'choice)
  1166. (let ((members (rng--ipattern-child ipattern))
  1167. (ret t))
  1168. (while (and members ret)
  1169. (or (rng-ipattern-empty-before-p (car members))
  1170. (setq ret nil))
  1171. (setq members (cdr members)))
  1172. ret))
  1173. (t nil))))
  1174. (defun rng-ipattern-possible-start-tags (ipattern accum)
  1175. (let ((type (rng--ipattern-type ipattern)))
  1176. (cond ((eq type 'after)
  1177. (rng-ipattern-possible-start-tags
  1178. (rng--ipattern-child ipattern)
  1179. accum))
  1180. ((memq type '(choice interleave))
  1181. (let ((members (rng--ipattern-child ipattern)))
  1182. (while members
  1183. (setq accum
  1184. (rng-ipattern-possible-start-tags (car members)
  1185. accum))
  1186. (setq members (cdr members))))
  1187. accum)
  1188. ((eq type 'group)
  1189. (let ((members (rng--ipattern-child ipattern)))
  1190. (while members
  1191. (setq accum
  1192. (rng-ipattern-possible-start-tags (car members)
  1193. accum))
  1194. (setq members
  1195. (and (rng--ipattern-nullable (car members))
  1196. (cdr members)))))
  1197. accum)
  1198. ((eq type 'element)
  1199. (if (eq (rng-element-get-child ipattern) rng-not-allowed-ipattern)
  1200. accum
  1201. (rng-name-class-possible-names
  1202. (rng--ipattern-name-class ipattern)
  1203. accum)))
  1204. ((eq type 'one-or-more)
  1205. (rng-ipattern-possible-start-tags
  1206. (rng--ipattern-child ipattern)
  1207. accum))
  1208. (t accum))))
  1209. (defun rng-ipattern-start-tag-possible-p (ipattern)
  1210. (let ((type (rng--ipattern-type ipattern)))
  1211. (cond ((memq type '(after one-or-more))
  1212. (rng-ipattern-start-tag-possible-p
  1213. (rng--ipattern-child ipattern)))
  1214. ((memq type '(choice interleave))
  1215. (let ((members (rng--ipattern-child ipattern))
  1216. (possible nil))
  1217. (while (and members (not possible))
  1218. (setq possible
  1219. (rng-ipattern-start-tag-possible-p (car members)))
  1220. (setq members (cdr members)))
  1221. possible))
  1222. ((eq type 'group)
  1223. (let ((members (rng--ipattern-child ipattern))
  1224. (possible nil))
  1225. (while (and members (not possible))
  1226. (setq possible
  1227. (rng-ipattern-start-tag-possible-p (car members)))
  1228. (setq members
  1229. (and (rng--ipattern-nullable (car members))
  1230. (cdr members))))
  1231. possible))
  1232. ((eq type 'element)
  1233. (not (eq (rng-element-get-child ipattern)
  1234. rng-not-allowed-ipattern)))
  1235. (t nil))))
  1236. (defun rng-ipattern-possible-attributes (ipattern accum)
  1237. (let ((type (rng--ipattern-type ipattern)))
  1238. (cond ((eq type 'after)
  1239. (rng-ipattern-possible-attributes (rng--ipattern-child ipattern)
  1240. accum))
  1241. ((memq type '(choice interleave group))
  1242. (let ((members (rng--ipattern-child ipattern)))
  1243. (while members
  1244. (setq accum
  1245. (rng-ipattern-possible-attributes (car members)
  1246. accum))
  1247. (setq members (cdr members))))
  1248. accum)
  1249. ((eq type 'attribute)
  1250. (rng-name-class-possible-names
  1251. (rng--ipattern-name-class ipattern)
  1252. accum))
  1253. ((eq type 'one-or-more)
  1254. (rng-ipattern-possible-attributes
  1255. (rng--ipattern-child ipattern)
  1256. accum))
  1257. (t accum))))
  1258. (defun rng-ipattern-possible-values (ipattern accum)
  1259. (let ((type (rng--ipattern-type ipattern)))
  1260. (cond ((eq type 'after)
  1261. (rng-ipattern-possible-values (rng--ipattern-child ipattern)
  1262. accum))
  1263. ((eq type 'choice)
  1264. (let ((members (rng--ipattern-child ipattern)))
  1265. (while members
  1266. (setq accum
  1267. (rng-ipattern-possible-values (car members)
  1268. accum))
  1269. (setq members (cdr members))))
  1270. accum)
  1271. ((eq type 'value)
  1272. (let ((value-object (rng--ipattern-value-object ipattern)))
  1273. (if (stringp value-object)
  1274. (cons value-object accum)
  1275. accum)))
  1276. (t accum))))
  1277. (defun rng-ipattern-required-element (ipattern)
  1278. (let ((type (rng--ipattern-type ipattern)))
  1279. (cond ((memq type '(after one-or-more))
  1280. (rng-ipattern-required-element (rng--ipattern-child ipattern)))
  1281. ((eq type 'choice)
  1282. (let* ((members (rng--ipattern-child ipattern))
  1283. (required (rng-ipattern-required-element (car members))))
  1284. (while (and required
  1285. (setq members (cdr members)))
  1286. (unless (equal required
  1287. (rng-ipattern-required-element (car members)))
  1288. (setq required nil)))
  1289. required))
  1290. ((eq type 'group)
  1291. (let ((members (rng--ipattern-child ipattern))
  1292. required)
  1293. (while (and (not (setq required
  1294. (rng-ipattern-required-element
  1295. (car members))))
  1296. (rng--ipattern-nullable (car members))
  1297. (setq members (cdr members))))
  1298. required))
  1299. ((eq type 'interleave)
  1300. (let ((members (rng--ipattern-child ipattern))
  1301. required)
  1302. (while members
  1303. (let ((tem (rng-ipattern-required-element (car members))))
  1304. (cond ((not tem)
  1305. (setq members (cdr members)))
  1306. ((not required)
  1307. (setq required tem)
  1308. (setq members (cdr members)))
  1309. ((equal required tem)
  1310. (setq members (cdr members)))
  1311. (t
  1312. (setq required nil)
  1313. (setq members nil)))))
  1314. required))
  1315. ((eq type 'element)
  1316. (let ((nc (rng--ipattern-name-class ipattern)))
  1317. (and (consp nc)
  1318. (not (eq (rng-element-get-child ipattern)
  1319. rng-not-allowed-ipattern))
  1320. nc))))))
  1321. (defun rng-ipattern-required-attributes (ipattern accum)
  1322. (let ((type (rng--ipattern-type ipattern)))
  1323. (cond ((eq type 'after)
  1324. (rng-ipattern-required-attributes (rng--ipattern-child ipattern)
  1325. accum))
  1326. ((memq type '(interleave group))
  1327. (let ((members (rng--ipattern-child ipattern)))
  1328. (while members
  1329. (setq accum
  1330. (rng-ipattern-required-attributes (car members)
  1331. accum))
  1332. (setq members (cdr members))))
  1333. accum)
  1334. ((eq type 'choice)
  1335. (let ((members (rng--ipattern-child ipattern))
  1336. in-all in-this new-in-all)
  1337. (setq in-all
  1338. (rng-ipattern-required-attributes (car members)
  1339. nil))
  1340. (while (and in-all (setq members (cdr members)))
  1341. (setq in-this
  1342. (rng-ipattern-required-attributes (car members) nil))
  1343. (setq new-in-all nil)
  1344. (while in-this
  1345. (when (member (car in-this) in-all)
  1346. (setq new-in-all
  1347. (cons (car in-this) new-in-all)))
  1348. (setq in-this (cdr in-this)))
  1349. (setq in-all new-in-all))
  1350. (append in-all accum)))
  1351. ((eq type 'attribute)
  1352. (let ((nc (rng--ipattern-name-class ipattern)))
  1353. (if (consp nc)
  1354. (cons nc accum)
  1355. accum)))
  1356. ((eq type 'one-or-more)
  1357. (rng-ipattern-required-attributes (rng--ipattern-child ipattern)
  1358. accum))
  1359. (t accum))))
  1360. (defun rng-compile-error (&rest args)
  1361. (signal 'rng-compile-error
  1362. (list (apply #'format-message args))))
  1363. (define-error 'rng-compile-error "Incorrect schema" 'rng-error)
  1364. ;;; External API
  1365. (defsubst rng-match-state () rng-match-state)
  1366. (defsubst rng-set-match-state (state)
  1367. (setq rng-match-state state))
  1368. (defsubst rng-match-state-equal (state)
  1369. (eq state rng-match-state))
  1370. (defun rng-schema-changed ()
  1371. (rng-ipattern-clear)
  1372. (rng-compile-clear))
  1373. (defun rng-match-init-buffer ()
  1374. (make-local-variable 'rng-compile-table)
  1375. (make-local-variable 'rng-ipattern-table)
  1376. (make-local-variable 'rng-last-ipattern-index))
  1377. (defun rng-match-start-document ()
  1378. (rng-ipattern-maybe-init)
  1379. (rng-compile-maybe-init)
  1380. (add-hook 'rng-schema-change-hook 'rng-schema-changed nil t)
  1381. (setq rng-match-state (rng-compile rng-current-schema)))
  1382. (defun rng-match-start-tag-open (name)
  1383. (rng-update-match-state (rng-start-tag-open-deriv rng-match-state
  1384. name)))
  1385. (defun rng-match-attribute-name (name)
  1386. (rng-update-match-state (rng-start-attribute-deriv rng-match-state
  1387. name)))
  1388. (defun rng-match-attribute-value (value)
  1389. (rng-update-match-state (rng-data-deriv rng-match-state
  1390. value)))
  1391. (defun rng-match-element-value (value)
  1392. (and (rng-update-match-state (rng-text-only-deriv rng-match-state))
  1393. (rng-update-match-state (rng-data-deriv rng-match-state
  1394. value))))
  1395. (defun rng-match-start-tag-close ()
  1396. (rng-update-match-state (rng-start-tag-close-deriv rng-match-state)))
  1397. (defun rng-match-mixed-text ()
  1398. (rng-update-match-state (rng-mixed-text-deriv rng-match-state)))
  1399. (defun rng-match-end-tag ()
  1400. (rng-update-match-state (rng-end-tag-deriv rng-match-state)))
  1401. (defun rng-match-after ()
  1402. (rng-update-match-state
  1403. (rng-ipattern-after rng-match-state)))
  1404. (defun rng-match-out-of-context-start-tag-open (name)
  1405. (let* ((found (rng-map-element-attribute 'rng-find-element-content-pattern
  1406. rng-current-schema
  1407. nil
  1408. name))
  1409. (content-pattern (if found
  1410. (rng-intern-choice found)
  1411. rng-not-allowed-ipattern)))
  1412. (rng-update-match-state
  1413. (rng-intern-after content-pattern rng-match-state))))
  1414. (defun rng-match-possible-namespace-uris ()
  1415. "Return a list of all the namespace URIs used in the current schema.
  1416. The absent URI is not included, so the result is always a list of symbols."
  1417. (rng-map-element-attribute (lambda (pattern accum)
  1418. (rng-find-name-class-uris (nth 1 pattern)
  1419. accum))
  1420. rng-current-schema
  1421. nil))
  1422. (defun rng-match-unknown-start-tag-open ()
  1423. (rng-update-match-state
  1424. (rng-unknown-start-tag-open-deriv rng-match-state)))
  1425. (defun rng-match-optionalize-elements ()
  1426. (rng-update-match-state
  1427. (rng-ipattern-optionalize-elements rng-match-state)))
  1428. (defun rng-match-ignore-attributes ()
  1429. (rng-update-match-state
  1430. (rng-ignore-attributes-deriv rng-match-state)))
  1431. (defun rng-match-text-typed-p ()
  1432. (rng-ipattern-text-typed-p rng-match-state))
  1433. (defun rng-match-empty-content ()
  1434. (if (rng-match-text-typed-p)
  1435. (rng-match-element-value "")
  1436. (rng-match-end-tag)))
  1437. (defun rng-match-empty-before-p ()
  1438. "Return non-nil if what can be matched before an end-tag is empty.
  1439. In other words, return non-nil if the pattern for what can be matched
  1440. for an end-tag is equivalent to empty."
  1441. (rng-ipattern-empty-before-p rng-match-state))
  1442. (defun rng-match-infer-start-tag-namespace (local-name)
  1443. (let ((ncs (rng-ipattern-possible-start-tags rng-match-state nil))
  1444. (nc nil)
  1445. (ns nil))
  1446. (while ncs
  1447. (setq nc (car ncs))
  1448. (if (and (equal (cdr nc) local-name)
  1449. (symbolp (car nc)))
  1450. (cond ((not ns)
  1451. ;; first possible namespace
  1452. (setq ns (car nc))
  1453. (setq ncs (cdr ncs)))
  1454. ((equal ns (car nc))
  1455. ;; same as first namespace
  1456. (setq ncs (cdr ncs)))
  1457. (t
  1458. ;; more than one possible namespace
  1459. (setq ns nil)
  1460. (setq ncs nil)))
  1461. (setq ncs (cdr ncs))))
  1462. ns))
  1463. (defun rng-match-nullable-p ()
  1464. (rng--ipattern-nullable rng-match-state))
  1465. (defun rng-match-possible-start-tag-names ()
  1466. "Return a list of possible names that would be valid for start-tags.
  1467. Each possible name is returned as a (NAMESPACE . LOCAL-NAME) pair,
  1468. where NAMESPACE is a symbol or nil (meaning the absent namespace) and
  1469. LOCAL-NAME is a string. The returned list may contain duplicates."
  1470. (rng-ipattern-possible-start-tags rng-match-state nil))
  1471. ;; This is no longer used. It might be useful so leave it in for now.
  1472. (defun rng-match-start-tag-possible-p ()
  1473. "Return non-nil if a start-tag is possible."
  1474. (rng-ipattern-start-tag-possible-p rng-match-state))
  1475. (defun rng-match-possible-attribute-names ()
  1476. "Return a list of possible names that would be valid for attributes.
  1477. See the function `rng-match-possible-start-tag-names' for
  1478. more information."
  1479. (rng-ipattern-possible-attributes rng-match-state nil))
  1480. (defun rng-match-possible-value-strings ()
  1481. "Return a list of strings that would be valid as content.
  1482. The list may contain duplicates. Typically, the list will not
  1483. be exhaustive."
  1484. (rng-ipattern-possible-values rng-match-state nil))
  1485. (defun rng-match-required-element-name ()
  1486. "Return the name of an element which must occur, or nil if none."
  1487. (rng-ipattern-required-element rng-match-state))
  1488. (defun rng-match-required-attribute-names ()
  1489. "Return a list of names of attributes which must all occur."
  1490. (rng-ipattern-required-attributes rng-match-state nil))
  1491. (defmacro rng-match-save (&rest body)
  1492. (declare (indent 0) (debug t))
  1493. (let ((state (make-symbol "state")))
  1494. `(let ((,state rng-match-state))
  1495. (unwind-protect
  1496. (progn ,@body)
  1497. (setq rng-match-state ,state)))))
  1498. (defmacro rng-match-with-schema (schema &rest body)
  1499. (declare (indent 1) (debug t))
  1500. `(let ((rng-current-schema ,schema)
  1501. rng-match-state
  1502. rng-compile-table
  1503. rng-ipattern-table
  1504. rng-last-ipattern-index)
  1505. (rng-ipattern-maybe-init)
  1506. (rng-compile-maybe-init)
  1507. (setq rng-match-state (rng-compile rng-current-schema))
  1508. ,@body))
  1509. (provide 'rng-match)
  1510. ;;; rng-match.el ends here