grammar.el 69 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897
  1. ;;; semantic/grammar.el --- Major mode framework for Semantic grammars
  2. ;; Copyright (C) 2002-2005, 2007-2012 Free Software Foundation, Inc.
  3. ;; Author: David Ponce <david@dponce.com>
  4. ;; Maintainer: David Ponce <david@dponce.com>
  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. ;;
  18. ;; Major mode framework for editing Semantic's input grammar files.
  19. ;;; History:
  20. ;;
  21. ;;; Code:
  22. (require 'semantic)
  23. (require 'semantic/ctxt)
  24. (require 'semantic/format)
  25. (require 'semantic/grammar-wy)
  26. (require 'semantic/idle)
  27. (declare-function semantic-momentary-highlight-tag "semantic/decorate")
  28. (declare-function semantic-analyze-context "semantic/analyze")
  29. (declare-function semantic-analyze-tags-of-class-list
  30. "semantic/analyze/complete")
  31. (eval-when-compile
  32. (require 'eldoc)
  33. (require 'semantic/edit)
  34. (require 'semantic/find))
  35. ;;;;
  36. ;;;; Set up lexer
  37. ;;;;
  38. (defconst semantic-grammar-lex-c-char-re "'\\s\\?.'"
  39. "Regexp matching C-like character literals.")
  40. ;; Most of the analyzers are auto-generated from the grammar, but the
  41. ;; following which need special handling code.
  42. ;;
  43. (define-lex-regex-analyzer semantic-grammar-lex-prologue
  44. "Detect and create a prologue token."
  45. "\\<%{"
  46. ;; Zing to the end of this brace block.
  47. (semantic-lex-push-token
  48. (semantic-lex-token
  49. 'PROLOGUE (point)
  50. (save-excursion
  51. (semantic-lex-unterminated-syntax-protection 'PROLOGUE
  52. (forward-char)
  53. (forward-sexp 1)
  54. (point))))))
  55. (defsubst semantic-grammar-epilogue-start ()
  56. "Return the start position of the grammar epilogue."
  57. (save-excursion
  58. (goto-char (point-min))
  59. (if (re-search-forward "^\\s-*\\<%%\\>\\s-*$" nil t 2)
  60. (match-beginning 0)
  61. (1+ (point-max)))))
  62. (define-lex-regex-analyzer semantic-grammar-lex-epilogue
  63. "Detect and create an epilogue or percent-percent token."
  64. "\\<%%\\>"
  65. (let ((start (match-beginning 0))
  66. (end (match-end 0))
  67. (class 'PERCENT_PERCENT))
  68. (when (>= start (semantic-grammar-epilogue-start))
  69. (setq class 'EPILOGUE
  70. end (point-max)))
  71. (semantic-lex-push-token
  72. (semantic-lex-token class start end))))
  73. (define-lex semantic-grammar-lexer
  74. "Lexical analyzer that handles Semantic grammar buffers.
  75. It ignores whitespaces, newlines and comments."
  76. semantic-lex-ignore-newline
  77. semantic-lex-ignore-whitespace
  78. ;; Must detect prologue/epilogue before other symbols/keywords!
  79. semantic-grammar-lex-prologue
  80. semantic-grammar-lex-epilogue
  81. semantic-grammar-wy--<keyword>-keyword-analyzer
  82. semantic-grammar-wy--<symbol>-regexp-analyzer
  83. semantic-grammar-wy--<char>-regexp-analyzer
  84. semantic-grammar-wy--<string>-sexp-analyzer
  85. ;; Must detect comments after strings because `comment-start-skip'
  86. ;; regexp match semicolons inside strings!
  87. semantic-lex-ignore-comments
  88. ;; Must detect prefixed list before punctuation because prefix chars
  89. ;; are also punctuation!
  90. semantic-grammar-wy--<qlist>-sexp-analyzer
  91. ;; Must detect punctuation after comments because the semicolon can
  92. ;; be punctuation or a comment start!
  93. semantic-grammar-wy--<punctuation>-string-analyzer
  94. semantic-grammar-wy--<block>-block-analyzer
  95. semantic-grammar-wy--<sexp>-sexp-analyzer)
  96. ;;; Test the lexer
  97. ;;
  98. (defun semantic-grammar-lex-buffer ()
  99. "Run `semantic-grammar-lex' on current buffer."
  100. (interactive)
  101. (semantic-lex-init)
  102. (setq semantic-lex-analyzer 'semantic-grammar-lexer)
  103. (let ((token-stream
  104. (semantic-lex (point-min) (point-max))))
  105. (with-current-buffer (get-buffer-create "*semantic-grammar-lex*")
  106. (erase-buffer)
  107. (pp token-stream (current-buffer))
  108. (goto-char (point-min))
  109. (pop-to-buffer (current-buffer)))))
  110. ;;;;
  111. ;;;; Semantic action expansion
  112. ;;;;
  113. (defun semantic-grammar-ASSOC (&rest args)
  114. "Return expansion of built-in ASSOC expression.
  115. ARGS are ASSOC's key value list."
  116. (let ((key t))
  117. `(semantic-tag-make-assoc-list
  118. ,@(mapcar #'(lambda (i)
  119. (prog1
  120. (if key
  121. (list 'quote i)
  122. i)
  123. (setq key (not key))))
  124. args))))
  125. (defsubst semantic-grammar-quote-p (sym)
  126. "Return non-nil if SYM is bound to the `quote' function."
  127. (condition-case nil
  128. (eq (indirect-function sym)
  129. (indirect-function 'quote))
  130. (error nil)))
  131. (defsubst semantic-grammar-backquote-p (sym)
  132. "Return non-nil if SYM is bound to the `backquote' function."
  133. (condition-case nil
  134. (eq (indirect-function sym)
  135. (indirect-function 'backquote))
  136. (error nil)))
  137. ;;;;
  138. ;;;; API to access grammar tags
  139. ;;;;
  140. (define-mode-local-override semantic-tag-components
  141. semantic-grammar-mode (tag)
  142. "Return the children of tag TAG."
  143. (semantic-tag-get-attribute tag :children))
  144. (defun semantic-grammar-first-tag-name (class)
  145. "Return the name of the first tag of class CLASS found.
  146. Warn if other tags of class CLASS exist."
  147. (let* ((tags (semantic-find-tags-by-class
  148. class (current-buffer))))
  149. (if tags
  150. (prog1
  151. (semantic-tag-name (car tags))
  152. (if (cdr tags)
  153. (message "*** Ignore all but first declared %s"
  154. class))))))
  155. (defun semantic-grammar-tag-symbols (class)
  156. "Return the list of symbols defined in tags of class CLASS.
  157. That is tag names plus names defined in tag attribute `:rest'."
  158. (let* ((tags (semantic-find-tags-by-class
  159. class (current-buffer))))
  160. (apply 'append
  161. (mapcar
  162. #'(lambda (tag)
  163. (mapcar
  164. 'intern
  165. (cons (semantic-tag-name tag)
  166. (semantic-tag-get-attribute tag :rest))))
  167. tags))))
  168. (defsubst semantic-grammar-item-text (item)
  169. "Return the readable string form of ITEM."
  170. (if (string-match semantic-grammar-lex-c-char-re item)
  171. (concat "?" (substring item 1 -1))
  172. item))
  173. (defsubst semantic-grammar-item-value (item)
  174. "Return symbol or character value of ITEM string."
  175. (if (string-match semantic-grammar-lex-c-char-re item)
  176. (let ((c (read (concat "?" (substring item 1 -1)))))
  177. (if (featurep 'xemacs)
  178. ;; Handle characters as integers in XEmacs like in GNU Emacs.
  179. (char-int c)
  180. c))
  181. (intern item)))
  182. (defun semantic-grammar-prologue ()
  183. "Return grammar prologue code as a string value."
  184. (let ((tag (semantic-find-first-tag-by-name
  185. "prologue"
  186. (semantic-find-tags-by-class 'code (current-buffer)))))
  187. (if tag
  188. (save-excursion
  189. (concat
  190. (buffer-substring
  191. (progn
  192. (goto-char (semantic-tag-start tag))
  193. (skip-chars-forward "%{\r\n\t ")
  194. (point))
  195. (progn
  196. (goto-char (semantic-tag-end tag))
  197. (skip-chars-backward "\r\n\t %}")
  198. (point)))
  199. "\n"))
  200. "")))
  201. (defun semantic-grammar-epilogue ()
  202. "Return grammar epilogue code as a string value."
  203. (let ((tag (semantic-find-first-tag-by-name
  204. "epilogue"
  205. (semantic-find-tags-by-class 'code (current-buffer)))))
  206. (if tag
  207. (save-excursion
  208. (concat
  209. (buffer-substring
  210. (progn
  211. (goto-char (semantic-tag-start tag))
  212. (skip-chars-forward "%\r\n\t ")
  213. (point))
  214. (progn
  215. (goto-char (semantic-tag-end tag))
  216. (skip-chars-backward "\r\n\t")
  217. ;; If a grammar footer is found, skip it.
  218. (re-search-backward "^;;;\\s-+\\S-+\\s-+ends here"
  219. (point-at-bol) t)
  220. (skip-chars-backward "\r\n\t")
  221. (point)))
  222. "\n"))
  223. "")))
  224. (defsubst semantic-grammar-buffer-file (&optional buffer)
  225. "Return name of file sans directory BUFFER is visiting.
  226. No argument or nil as argument means use the current buffer."
  227. (file-name-nondirectory (buffer-file-name buffer)))
  228. (defun semantic-grammar-package ()
  229. "Return the %package value as a string.
  230. If there is no %package statement in the grammar, return a default
  231. package name derived from the grammar file name. For example, the
  232. default package name for the grammar file foo.wy is foo-wy, and for
  233. foo.by it is foo-by."
  234. (or (semantic-grammar-first-tag-name 'package)
  235. (let* ((file (semantic-grammar-buffer-file))
  236. (ext (file-name-extension file))
  237. (i (string-match (format "\\([.]\\)%s\\'" ext) file)))
  238. (concat (substring file 0 i) "-" ext))))
  239. (defsubst semantic-grammar-languagemode ()
  240. "Return the %languagemode value as a list of symbols or nil."
  241. (semantic-grammar-tag-symbols 'languagemode))
  242. (defsubst semantic-grammar-start ()
  243. "Return the %start value as a list of symbols or nil."
  244. (semantic-grammar-tag-symbols 'start))
  245. (defsubst semantic-grammar-scopestart ()
  246. "Return the %scopestart value as a symbol or nil."
  247. (intern (or (semantic-grammar-first-tag-name 'scopestart) "nil")))
  248. (defsubst semantic-grammar-quotemode ()
  249. "Return the %quotemode value as a symbol or nil."
  250. (intern (or (semantic-grammar-first-tag-name 'quotemode) "nil")))
  251. (defsubst semantic-grammar-keywords ()
  252. "Return the language keywords.
  253. That is an alist of (VALUE . TOKEN) where VALUE is the string value of
  254. the keyword and TOKEN is the terminal symbol identifying the keyword."
  255. (mapcar
  256. #'(lambda (key)
  257. (cons (semantic-tag-get-attribute key :value)
  258. (intern (semantic-tag-name key))))
  259. (semantic-find-tags-by-class 'keyword (current-buffer))))
  260. (defun semantic-grammar-keyword-properties (keywords)
  261. "Return the list of KEYWORDS properties."
  262. (let ((puts (semantic-find-tags-by-class
  263. 'put (current-buffer)))
  264. put keys key plist assoc pkey pval props)
  265. (while puts
  266. (setq put (car puts)
  267. puts (cdr puts)
  268. keys (mapcar
  269. 'intern
  270. (cons (semantic-tag-name put)
  271. (semantic-tag-get-attribute put :rest))))
  272. (while keys
  273. (setq key (car keys)
  274. keys (cdr keys)
  275. assoc (rassq key keywords))
  276. (if (null assoc)
  277. nil ;;(message "*** %%put to undefined keyword %s ignored" key)
  278. (setq key (car assoc)
  279. plist (semantic-tag-get-attribute put :value))
  280. (while plist
  281. (setq pkey (intern (caar plist))
  282. pval (read (cdar plist))
  283. props (cons (list key pkey pval) props)
  284. plist (cdr plist))))))
  285. props))
  286. (defun semantic-grammar-tokens ()
  287. "Return defined lexical tokens.
  288. That is an alist (TYPE . DEFS) where type is a %token <type> symbol
  289. and DEFS is an alist of (TOKEN . VALUE). TOKEN is the terminal symbol
  290. identifying the token and VALUE is the string value of the token or
  291. nil."
  292. (let (tags alist assoc tag type term names value)
  293. ;; Check for <type> in %left, %right & %nonassoc declarations
  294. (setq tags (semantic-find-tags-by-class
  295. 'assoc (current-buffer)))
  296. (while tags
  297. (setq tag (car tags)
  298. tags (cdr tags))
  299. (when (setq type (semantic-tag-type tag))
  300. (setq names (semantic-tag-get-attribute tag :value)
  301. assoc (assoc type alist))
  302. (or assoc (setq assoc (list type)
  303. alist (cons assoc alist)))
  304. (while names
  305. (setq term (car names)
  306. names (cdr names))
  307. (or (string-match semantic-grammar-lex-c-char-re term)
  308. (setcdr assoc (cons (list (intern term))
  309. (cdr assoc)))))))
  310. ;; Then process %token declarations so they can override any
  311. ;; previous specifications
  312. (setq tags (semantic-find-tags-by-class
  313. 'token (current-buffer)))
  314. (while tags
  315. (setq tag (car tags)
  316. tags (cdr tags))
  317. (setq names (cons (semantic-tag-name tag)
  318. (semantic-tag-get-attribute tag :rest))
  319. type (or (semantic-tag-type tag) "<no-type>")
  320. value (semantic-tag-get-attribute tag :value)
  321. assoc (assoc type alist))
  322. (or assoc (setq assoc (list type)
  323. alist (cons assoc alist)))
  324. (while names
  325. (setq term (intern (car names))
  326. names (cdr names))
  327. (setcdr assoc (cons (cons term value) (cdr assoc)))))
  328. alist))
  329. (defun semantic-grammar-token-%type-properties (&optional props)
  330. "Return properties set by %type statements.
  331. This declare a new type if necessary.
  332. If optional argument PROPS is non-nil, it is an existing list of
  333. properties where to add new properties."
  334. (let (type)
  335. (dolist (tag (semantic-find-tags-by-class 'type (current-buffer)))
  336. (setq type (semantic-tag-name tag))
  337. ;; Indicate to auto-generate the analyzer for this type
  338. (push (list type :declared t) props)
  339. (dolist (e (semantic-tag-get-attribute tag :value))
  340. (push (list type (intern (car e)) (read (or (cdr e) "nil")))
  341. props)))
  342. props))
  343. (defun semantic-grammar-token-%put-properties (tokens)
  344. "For types found in TOKENS, return properties set by %put statements."
  345. (let (found props)
  346. (dolist (put (semantic-find-tags-by-class 'put (current-buffer)))
  347. (dolist (type (cons (semantic-tag-name put)
  348. (semantic-tag-get-attribute put :rest)))
  349. (setq found (assoc type tokens))
  350. (if (null found)
  351. nil ;; %put <type> ignored, no token defined
  352. (setq type (car found))
  353. (dolist (e (semantic-tag-get-attribute put :value))
  354. (push (list type (intern (car e)) (read (or (cdr e) "nil")))
  355. props)))))
  356. props))
  357. (defsubst semantic-grammar-token-properties (tokens)
  358. "Return properties of declared types.
  359. Types are explicitly declared by %type statements. Types found in
  360. TOKENS are those declared implicitly by %token statements.
  361. Properties can be set by %put and %type statements.
  362. Properties set by %type statements take precedence over those set by
  363. %put statements."
  364. (let ((props (semantic-grammar-token-%put-properties tokens)))
  365. (semantic-grammar-token-%type-properties props)))
  366. (defun semantic-grammar-use-macros ()
  367. "Return macro definitions from %use-macros statements.
  368. Also load the specified macro libraries."
  369. (let (lib defs)
  370. (dolist (tag (semantic-find-tags-by-class 'macro (current-buffer)))
  371. (setq lib (intern (semantic-tag-type tag)))
  372. (condition-case nil
  373. ;;(load lib) ;; Be sure to use the latest macro library.
  374. (require lib)
  375. (error nil))
  376. (dolist (mac (semantic-tag-get-attribute tag :value))
  377. (push (cons (intern mac)
  378. (intern (format "%s-%s" lib mac)))
  379. defs)))
  380. (nreverse defs)))
  381. (defvar semantic-grammar-macros nil
  382. "List of associations (MACRO-NAME . EXPANDER).")
  383. (make-variable-buffer-local 'semantic-grammar-macros)
  384. (defun semantic-grammar-macros ()
  385. "Build and return the alist of defined macros."
  386. (append
  387. ;; Definitions found in tags.
  388. (semantic-grammar-use-macros)
  389. ;; Other pre-installed definitions.
  390. semantic-grammar-macros))
  391. ;;;;
  392. ;;;; Overloaded functions that build parser data.
  393. ;;;;
  394. ;;; Keyword table builder
  395. ;;
  396. (defun semantic-grammar-keywordtable-builder-default ()
  397. "Return the default value of the keyword table."
  398. (let ((keywords (semantic-grammar-keywords)))
  399. `(semantic-lex-make-keyword-table
  400. ',keywords
  401. ',(semantic-grammar-keyword-properties keywords))))
  402. (define-overloadable-function semantic-grammar-keywordtable-builder ()
  403. "Return the keyword table value.")
  404. ;;; Token table builder
  405. ;;
  406. (defun semantic-grammar-tokentable-builder-default ()
  407. "Return the default value of the table of lexical tokens."
  408. (let ((tokens (semantic-grammar-tokens)))
  409. `(semantic-lex-make-type-table
  410. ',tokens
  411. ',(semantic-grammar-token-properties tokens))))
  412. (define-overloadable-function semantic-grammar-tokentable-builder ()
  413. "Return the value of the table of lexical tokens.")
  414. ;;; Parser table builder
  415. ;;
  416. (defun semantic-grammar-parsetable-builder-default ()
  417. "Return the default value of the parse table."
  418. (error "`semantic-grammar-parsetable-builder' not defined"))
  419. (define-overloadable-function semantic-grammar-parsetable-builder ()
  420. "Return the parser table value.")
  421. ;;; Parser setup code builder
  422. ;;
  423. (defun semantic-grammar-setupcode-builder-default ()
  424. "Return the default value of the setup code form."
  425. (error "`semantic-grammar-setupcode-builder' not defined"))
  426. (define-overloadable-function semantic-grammar-setupcode-builder ()
  427. "Return the parser setup code form.")
  428. ;;;;
  429. ;;;; Lisp code generation
  430. ;;;;
  431. (defvar semantic--grammar-input-buffer nil)
  432. (defvar semantic--grammar-output-buffer nil)
  433. (defsubst semantic-grammar-keywordtable ()
  434. "Return the variable name of the keyword table."
  435. (concat (file-name-sans-extension
  436. (semantic-grammar-buffer-file
  437. semantic--grammar-output-buffer))
  438. "--keyword-table"))
  439. (defsubst semantic-grammar-tokentable ()
  440. "Return the variable name of the token table."
  441. (concat (file-name-sans-extension
  442. (semantic-grammar-buffer-file
  443. semantic--grammar-output-buffer))
  444. "--token-table"))
  445. (defsubst semantic-grammar-parsetable ()
  446. "Return the variable name of the parse table."
  447. (concat (file-name-sans-extension
  448. (semantic-grammar-buffer-file
  449. semantic--grammar-output-buffer))
  450. "--parse-table"))
  451. (defsubst semantic-grammar-setupfunction ()
  452. "Return the name of the parser setup function."
  453. (concat (file-name-sans-extension
  454. (semantic-grammar-buffer-file
  455. semantic--grammar-output-buffer))
  456. "--install-parser"))
  457. (defmacro semantic-grammar-as-string (object)
  458. "Return OBJECT as a string value."
  459. `(if (stringp ,object)
  460. ,object
  461. ;;(require 'pp)
  462. (pp-to-string ,object)))
  463. (defun semantic-grammar-insert-defconst (name value docstring)
  464. "Insert declaration of constant NAME with VALUE and DOCSTRING."
  465. (let ((start (point)))
  466. (insert (format "(defconst %s\n%s%S)\n\n" name value docstring))
  467. (save-excursion
  468. (goto-char start)
  469. (indent-sexp))))
  470. (defun semantic-grammar-insert-defun (name body docstring)
  471. "Insert declaration of function NAME with BODY and DOCSTRING."
  472. (let ((start (point)))
  473. (insert (format "(defun %s ()\n%S\n%s)\n\n" name docstring body))
  474. (save-excursion
  475. (goto-char start)
  476. (indent-sexp))))
  477. (defun semantic-grammar-insert-define (define)
  478. "Insert the declaration specified by DEFINE expression.
  479. Typically a DEFINE expression should look like this:
  480. \(define-thing name docstring expression1 ...)"
  481. ;;(require 'pp)
  482. (let ((start (point)))
  483. (insert (format "(%S %S" (car define) (nth 1 define)))
  484. (dolist (item (nthcdr 2 define))
  485. (insert "\n")
  486. (delete-blank-lines)
  487. (pp item (current-buffer)))
  488. (insert ")\n\n")
  489. (save-excursion
  490. (goto-char start)
  491. (indent-sexp))))
  492. (defconst semantic-grammar-header-template
  493. '("\
  494. ;;; " file " --- Generated parser support file
  495. " copy "
  496. ;; Author: " user-full-name " <" user-mail-address ">
  497. ;; Created: " date "
  498. ;; Keywords: syntax
  499. ;; X-RCS: " vcid "
  500. ;; This file is not part of GNU Emacs.
  501. ;; This program is free software; you can redistribute it and/or
  502. ;; modify it under the terms of the GNU General Public License as
  503. ;; published by the Free Software Foundation, either version 3 of
  504. ;; the License, or (at your option) any later version.
  505. ;; This software is distributed in the hope that it will be useful,
  506. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  507. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  508. ;; General Public License for more details.
  509. ;;
  510. ;; You should have received a copy of the GNU General Public License
  511. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  512. ;;; Commentary:
  513. ;;
  514. ;; PLEASE DO NOT MANUALLY EDIT THIS FILE! It is automatically
  515. ;; generated from the grammar file " gram ".
  516. ;;; History:
  517. ;;
  518. ;;; Code:
  519. ")
  520. "Generated header template.
  521. The symbols in the template are local variables in
  522. `semantic-grammar-header'")
  523. (defconst semantic-grammar-footer-template
  524. '("\
  525. \(provide '" libr ")
  526. ;;; " file " ends here
  527. ")
  528. "Generated footer template.
  529. The symbols in the list are local variables in
  530. `semantic-grammar-footer'.")
  531. (defun semantic-grammar-copyright-line ()
  532. "Return the grammar copyright line, or nil if not found."
  533. (save-excursion
  534. (goto-char (point-min))
  535. (when (re-search-forward "^;;+[ \t]+Copyright (C) .*$"
  536. ;; Search only in the four top lines
  537. (save-excursion (forward-line 4) (point))
  538. t)
  539. (match-string 0))))
  540. (defun semantic-grammar-header ()
  541. "Return text of a generated standard header."
  542. (let ((file (semantic-grammar-buffer-file
  543. semantic--grammar-output-buffer))
  544. (gram (semantic-grammar-buffer-file))
  545. (date (format-time-string "%Y-%m-%d %T%z"))
  546. (vcid (concat "$" "Id" "$")) ;; Avoid expansion
  547. ;; Try to get the copyright from the input grammar, or
  548. ;; generate a new one if not found.
  549. (copy (or (semantic-grammar-copyright-line)
  550. (concat (format-time-string ";; Copyright (C) %Y ")
  551. user-full-name)))
  552. (out ""))
  553. (dolist (S semantic-grammar-header-template)
  554. (cond ((stringp S)
  555. (setq out (concat out S)))
  556. ((symbolp S)
  557. (setq out (concat out (symbol-value S))))))
  558. out))
  559. (defun semantic-grammar-footer ()
  560. "Return text of a generated standard footer."
  561. (let* ((file (semantic-grammar-buffer-file
  562. semantic--grammar-output-buffer))
  563. (libr (file-name-sans-extension file))
  564. (out ""))
  565. (dolist (S semantic-grammar-footer-template)
  566. (cond ((stringp S)
  567. (setq out (concat out S)))
  568. ((symbolp S)
  569. (setq out (concat out (symbol-value S))))))
  570. out))
  571. (defun semantic-grammar-token-data ()
  572. "Return the string value of the table of lexical tokens."
  573. (semantic-grammar-as-string
  574. (semantic-grammar-tokentable-builder)))
  575. (defun semantic-grammar-keyword-data ()
  576. "Return the string value of the table of keywords."
  577. (semantic-grammar-as-string
  578. (semantic-grammar-keywordtable-builder)))
  579. (defun semantic-grammar-parser-data ()
  580. "Return the parser table as a string value."
  581. (semantic-grammar-as-string
  582. (semantic-grammar-parsetable-builder)))
  583. (defun semantic-grammar-setup-data ()
  584. "Return the parser setup code form as a string value."
  585. (semantic-grammar-as-string
  586. (semantic-grammar-setupcode-builder)))
  587. ;;; Generation of lexical analyzers.
  588. ;;
  589. (defvar semantic-grammar--lex-block-specs)
  590. (defsubst semantic-grammar--lex-delim-spec (block-spec)
  591. "Return delimiters specification from BLOCK-SPEC."
  592. (condition-case nil
  593. (let* ((standard-input (cdr block-spec))
  594. (delim-spec (read)))
  595. (if (and (consp delim-spec)
  596. (car delim-spec) (symbolp (car delim-spec))
  597. (cadr delim-spec) (symbolp (cadr delim-spec)))
  598. delim-spec
  599. (error "Invalid delimiter")))
  600. (error
  601. (error "Invalid delimiters specification %s in block token %s"
  602. (cdr block-spec) (car block-spec)))))
  603. (defun semantic-grammar--lex-block-specs ()
  604. "Compute lexical block specifications for the current buffer.
  605. Block definitions are read from the current table of lexical types."
  606. (cond
  607. ;; Block specifications have been parsed and are invalid.
  608. ((eq semantic-grammar--lex-block-specs 'error)
  609. nil
  610. )
  611. ;; Parse block specifications.
  612. ((null semantic-grammar--lex-block-specs)
  613. (condition-case err
  614. (let* ((blocks (cdr (semantic-lex-type-value "block" t)))
  615. (open-delims (cdr (semantic-lex-type-value "open-paren" t)))
  616. (close-delims (cdr (semantic-lex-type-value "close-paren" t)))
  617. olist clist block-spec delim-spec open-spec close-spec)
  618. (dolist (block-spec blocks)
  619. (setq delim-spec (semantic-grammar--lex-delim-spec block-spec)
  620. open-spec (assq (car delim-spec) open-delims)
  621. close-spec (assq (cadr delim-spec) close-delims))
  622. (or open-spec
  623. (error "Missing open-paren token %s required by block %s"
  624. (car delim-spec) (car block-spec)))
  625. (or close-spec
  626. (error "Missing close-paren token %s required by block %s"
  627. (cdr delim-spec) (car block-spec)))
  628. ;; build alist ((OPEN-DELIM OPEN-SYM BLOCK-SYM) ...)
  629. (push (list (cdr open-spec) (car open-spec) (car block-spec))
  630. olist)
  631. ;; build alist ((CLOSE-DELIM CLOSE-SYM) ...)
  632. (push (list (cdr close-spec) (car close-spec))
  633. clist))
  634. (setq semantic-grammar--lex-block-specs (cons olist clist)))
  635. (error
  636. (setq semantic-grammar--lex-block-specs 'error)
  637. (message "%s" (error-message-string err))
  638. nil))
  639. )
  640. ;; Block specifications already parsed.
  641. (t
  642. semantic-grammar--lex-block-specs)))
  643. (defsubst semantic-grammar-quoted-form (exp)
  644. "Return a quoted form of EXP if it isn't a self evaluating form."
  645. (if (and (not (null exp))
  646. (or (listp exp) (symbolp exp)))
  647. (list 'quote exp)
  648. exp))
  649. (defun semantic-grammar-insert-defanalyzer (type)
  650. "Insert declaration of the lexical analyzer defined with TYPE."
  651. (let* ((type-name (symbol-name type))
  652. (type-value (symbol-value type))
  653. (syntax (get type 'syntax))
  654. (declared (get type :declared))
  655. spec mtype prefix name doc)
  656. ;; Generate an analyzer if the corresponding type has been
  657. ;; explicitly declared in a %type statement, and if at least the
  658. ;; syntax property has been provided.
  659. (when (and declared syntax)
  660. (setq prefix (file-name-sans-extension
  661. (semantic-grammar-buffer-file
  662. semantic--grammar-output-buffer))
  663. mtype (or (get type 'matchdatatype) 'regexp)
  664. name (intern (format "%s--<%s>-%s-analyzer" prefix type mtype))
  665. doc (format "%s analyzer for <%s> tokens." mtype type))
  666. (cond
  667. ;; Regexp match analyzer
  668. ((eq mtype 'regexp)
  669. (semantic-grammar-insert-define
  670. `(define-lex-regex-type-analyzer ,name
  671. ,doc ,syntax
  672. ,(semantic-grammar-quoted-form (cdr type-value))
  673. ',(or (car type-value) (intern type-name))))
  674. )
  675. ;; String compare analyzer
  676. ((eq mtype 'string)
  677. (semantic-grammar-insert-define
  678. `(define-lex-string-type-analyzer ,name
  679. ,doc ,syntax
  680. ,(semantic-grammar-quoted-form (cdr type-value))
  681. ',(or (car type-value) (intern type-name))))
  682. )
  683. ;; Block analyzer
  684. ((and (eq mtype 'block)
  685. (setq spec (semantic-grammar--lex-block-specs)))
  686. (semantic-grammar-insert-define
  687. `(define-lex-block-type-analyzer ,name
  688. ,doc ,syntax
  689. ,(semantic-grammar-quoted-form spec)))
  690. )
  691. ;; Sexp analyzer
  692. ((eq mtype 'sexp)
  693. (semantic-grammar-insert-define
  694. `(define-lex-sexp-type-analyzer ,name
  695. ,doc ,syntax
  696. ',(or (car type-value) (intern type-name))))
  697. )
  698. ;; keyword analyzer
  699. ((eq mtype 'keyword)
  700. (semantic-grammar-insert-define
  701. `(define-lex-keyword-type-analyzer ,name
  702. ,doc ,syntax))
  703. )
  704. ))
  705. ))
  706. (defun semantic-grammar-insert-defanalyzers ()
  707. "Insert declarations of lexical analyzers."
  708. (let (tokens props)
  709. (with-current-buffer semantic--grammar-input-buffer
  710. (setq tokens (semantic-grammar-tokens)
  711. props (semantic-grammar-token-properties tokens)))
  712. (insert "(require 'semantic/lex)\n\n")
  713. (let ((semantic-lex-types-obarray
  714. (semantic-lex-make-type-table tokens props))
  715. semantic-grammar--lex-block-specs)
  716. (mapatoms 'semantic-grammar-insert-defanalyzer
  717. semantic-lex-types-obarray))))
  718. ;;; Generation of the grammar support file.
  719. ;;
  720. (defcustom semantic-grammar-file-regexp "\\.[wb]y$"
  721. "Regexp which matches grammar source files."
  722. :group 'semantic
  723. :type 'regexp)
  724. (defsubst semantic-grammar-noninteractive ()
  725. "Return non-nil if running without interactive terminal."
  726. (if (featurep 'xemacs)
  727. (noninteractive)
  728. noninteractive))
  729. (defun semantic-grammar-create-package (&optional force)
  730. "Create package Lisp code from grammar in current buffer.
  731. Does nothing if the Lisp code seems up to date.
  732. If optional argument FORCE is non-nil, unconditionally re-generate the
  733. Lisp code."
  734. (interactive "P")
  735. (setq force (or force current-prefix-arg))
  736. (semantic-fetch-tags)
  737. (let* (
  738. ;; Values of the following local variables are obtained from
  739. ;; the grammar parsed tree in current buffer, that is before
  740. ;; switching to the output file.
  741. (package (semantic-grammar-package))
  742. (output (concat package ".el"))
  743. (semantic--grammar-input-buffer (current-buffer))
  744. (semantic--grammar-output-buffer (find-file-noselect output))
  745. (header (semantic-grammar-header))
  746. (prologue (semantic-grammar-prologue))
  747. (epilogue (semantic-grammar-epilogue))
  748. (footer (semantic-grammar-footer))
  749. )
  750. (if (and (not force)
  751. (not (buffer-modified-p))
  752. (file-newer-than-file-p
  753. (buffer-file-name semantic--grammar-output-buffer)
  754. (buffer-file-name semantic--grammar-input-buffer)))
  755. (message "Package `%s' is up to date." package)
  756. ;; Create the package
  757. (set-buffer semantic--grammar-output-buffer)
  758. ;; Use Unix EOLs, so that the file is portable to all platforms.
  759. (setq buffer-file-coding-system 'raw-text-unix)
  760. (erase-buffer)
  761. (unless (eq major-mode 'emacs-lisp-mode)
  762. (emacs-lisp-mode))
  763. ;;;; Header + Prologue
  764. (insert header
  765. " \n;;; Prologue\n;;\n"
  766. prologue
  767. )
  768. ;; Evaluate the prologue now, because it might provide definition
  769. ;; of grammar macro expanders.
  770. (eval-region (point-min) (point))
  771. (save-excursion
  772. ;;;; Declarations
  773. (insert " \n;;; Declarations\n;;\n")
  774. ;; `eval-defun' is not necessary to reset `defconst' values.
  775. (semantic-grammar-insert-defconst
  776. (semantic-grammar-keywordtable)
  777. (with-current-buffer semantic--grammar-input-buffer
  778. (semantic-grammar-keyword-data))
  779. "Table of language keywords.")
  780. (semantic-grammar-insert-defconst
  781. (semantic-grammar-tokentable)
  782. (with-current-buffer semantic--grammar-input-buffer
  783. (semantic-grammar-token-data))
  784. "Table of lexical tokens.")
  785. (semantic-grammar-insert-defconst
  786. (semantic-grammar-parsetable)
  787. (with-current-buffer semantic--grammar-input-buffer
  788. (semantic-grammar-parser-data))
  789. "Parser table.")
  790. (semantic-grammar-insert-defun
  791. (semantic-grammar-setupfunction)
  792. (with-current-buffer semantic--grammar-input-buffer
  793. (semantic-grammar-setup-data))
  794. "Setup the Semantic Parser.")
  795. ;;;; Analyzers
  796. (insert " \n;;; Analyzers\n;;\n")
  797. (semantic-grammar-insert-defanalyzers)
  798. ;;;; Epilogue & Footer
  799. (insert " \n;;; Epilogue\n;;\n"
  800. epilogue
  801. footer
  802. )
  803. )
  804. (save-buffer 16)
  805. ;; If running in batch mode, there is nothing more to do.
  806. ;; Save the generated file and quit.
  807. (if (semantic-grammar-noninteractive)
  808. (let ((version-control t)
  809. (delete-old-versions t)
  810. (make-backup-files t)
  811. (vc-make-backup-files t))
  812. (kill-buffer (current-buffer)))
  813. ;; If running interactively, eval declarations and epilogue
  814. ;; code, then pop to the buffer visiting the generated file.
  815. (eval-region (point) (point-max))
  816. ;; Loop over the defvars and eval them explicitly to force
  817. ;; them to be evaluated and ready to use.
  818. (goto-char (point-min))
  819. (while (re-search-forward "(defvar " nil t)
  820. (eval-defun nil))
  821. ;; Move cursor to a logical spot in the generated code.
  822. (goto-char (point-min))
  823. (pop-to-buffer (current-buffer))
  824. ;; The generated code has been evaluated and updated into
  825. ;; memory. Now find all buffers that match the major modes we
  826. ;; have created this language for, and force them to call our
  827. ;; setup function again, refreshing all semantic data, and
  828. ;; enabling them to work with the new code just created.
  829. ;;;; FIXME?
  830. ;; At this point, I don't know any user's defined setup code :-(
  831. ;; At least, what I can do for now, is to run the generated
  832. ;; parser-install function.
  833. (semantic-map-mode-buffers
  834. (semantic-grammar-setupfunction)
  835. (semantic-grammar-languagemode)))
  836. )
  837. ;; Return the name of the generated package file.
  838. output))
  839. (defun semantic-grammar-recreate-package ()
  840. "Unconditionally create Lisp code from grammar in current buffer.
  841. Like \\[universal-argument] \\[semantic-grammar-create-package]."
  842. (interactive)
  843. (semantic-grammar-create-package t))
  844. (defun semantic-grammar-batch-build-one-package (file)
  845. "Build a Lisp package from the grammar in FILE.
  846. That is, generate Lisp code from FILE, and `byte-compile' it.
  847. Return non-nil if there were no errors, nil if errors."
  848. ;; We need this require so that we can find `byte-compile-dest-file'.
  849. (require 'bytecomp)
  850. (unless (auto-save-file-name-p file)
  851. ;; Create the package
  852. (let ((packagename
  853. (condition-case err
  854. (with-current-buffer (find-file-noselect file)
  855. (semantic-grammar-create-package))
  856. (error
  857. (message "%s" (error-message-string err))
  858. nil))))
  859. (when packagename
  860. ;; Only byte compile if out of date
  861. (if (file-newer-than-file-p
  862. packagename (byte-compile-dest-file packagename))
  863. (let (;; Some complex grammar table expressions need a few
  864. ;; more resources than the default.
  865. (max-specpdl-size (max 3000 max-specpdl-size))
  866. (max-lisp-eval-depth (max 1000 max-lisp-eval-depth))
  867. )
  868. ;; byte compile the resultant file
  869. (byte-compile-file packagename))
  870. t)))))
  871. (defun semantic-grammar-batch-build-packages ()
  872. "Build Lisp packages from grammar files on the command line.
  873. That is, run `semantic-grammar-batch-build-one-package' for each file.
  874. Each file is processed even if an error occurred previously.
  875. Must be used from the command line, with `-batch'.
  876. For example, to process grammar files in current directory, invoke:
  877. \"emacs -batch -f semantic-grammar-batch-build-packages .\".
  878. See also the variable `semantic-grammar-file-regexp'."
  879. (or (semantic-grammar-noninteractive)
  880. (error "\
  881. `semantic-grammar-batch-build-packages' must be used with -batch"
  882. ))
  883. (let ((status 0)
  884. ;; Remove vc from find-file-hook. It causes bad stuff to
  885. ;; happen in Emacs 20.
  886. (find-file-hook (delete 'vc-find-file-hook find-file-hook)))
  887. (message "Compiling Grammars from: %s" (locate-library "semantic-grammar"))
  888. (dolist (arg command-line-args-left)
  889. (unless (and arg (file-exists-p arg))
  890. (error "Argument %s is not a valid file name" arg))
  891. (setq arg (expand-file-name arg))
  892. (if (file-directory-p arg)
  893. ;; Directory as argument
  894. (dolist (src (condition-case nil
  895. (directory-files
  896. arg nil semantic-grammar-file-regexp)
  897. (error
  898. (error "Unable to read directory files"))))
  899. (or (semantic-grammar-batch-build-one-package
  900. (expand-file-name src arg))
  901. (setq status 1)))
  902. ;; Specific file argument
  903. (or (semantic-grammar-batch-build-one-package arg)
  904. (setq status 1))))
  905. (kill-emacs status)
  906. ))
  907. ;;;;
  908. ;;;; Macros highlighting
  909. ;;;;
  910. (defvar semantic--grammar-macros-regexp-1 nil)
  911. (make-variable-buffer-local 'semantic--grammar-macros-regexp-1)
  912. (defun semantic--grammar-macros-regexp-1 ()
  913. "Return font-lock keyword regexp for pre-installed macro names."
  914. (and semantic-grammar-macros
  915. (not semantic--grammar-macros-regexp-1)
  916. (condition-case nil
  917. (setq semantic--grammar-macros-regexp-1
  918. (concat "(\\s-*"
  919. (regexp-opt
  920. (mapcar #'(lambda (e) (symbol-name (car e)))
  921. semantic-grammar-macros)
  922. t)
  923. "\\>"))
  924. (error nil)))
  925. semantic--grammar-macros-regexp-1)
  926. (defconst semantic--grammar-macdecl-re
  927. "\\<%use-macros\\>[ \t\r\n]+\\(\\sw\\|\\s_\\)+[ \t\r\n]+{"
  928. "Regexp that matches a macro declaration statement.")
  929. (defvar semantic--grammar-macros-regexp-2 nil)
  930. (make-variable-buffer-local 'semantic--grammar-macros-regexp-2)
  931. (defun semantic--grammar-clear-macros-regexp-2 (&rest ignore)
  932. "Clear the cached regexp that match macros local in this grammar.
  933. IGNORE arguments.
  934. Added to `before-change-functions' hooks to be run before each text
  935. change."
  936. (setq semantic--grammar-macros-regexp-2 nil))
  937. (defun semantic--grammar-macros-regexp-2 ()
  938. "Return the regexp that match macros local in this grammar."
  939. (unless semantic--grammar-macros-regexp-2
  940. (let (macs)
  941. (save-excursion
  942. (goto-char (point-min))
  943. (while (re-search-forward semantic--grammar-macdecl-re nil t)
  944. (condition-case nil
  945. (setq macs (nconc macs
  946. (split-string
  947. (buffer-substring-no-properties
  948. (point)
  949. (progn
  950. (backward-char)
  951. (forward-list 1)
  952. (down-list -1)
  953. (point))))))
  954. (error nil)))
  955. (when macs
  956. (setq semantic--grammar-macros-regexp-2
  957. (concat "(\\s-*" (regexp-opt macs t) "\\>"))))))
  958. semantic--grammar-macros-regexp-2)
  959. (defun semantic--grammar-macros-matcher (end)
  960. "Search for a grammar macro name to highlight.
  961. END is the limit of the search."
  962. (let ((regexp (semantic--grammar-macros-regexp-1)))
  963. (or (and regexp (re-search-forward regexp end t))
  964. (and (setq regexp (semantic--grammar-macros-regexp-2))
  965. (re-search-forward regexp end t)))))
  966. ;;;;
  967. ;;;; Define major mode
  968. ;;;;
  969. (defvar semantic-grammar-syntax-table
  970. (let ((table (make-syntax-table (standard-syntax-table))))
  971. (modify-syntax-entry ?\: "." table) ;; COLON
  972. (modify-syntax-entry ?\> "." table) ;; GT
  973. (modify-syntax-entry ?\< "." table) ;; LT
  974. (modify-syntax-entry ?\| "." table) ;; OR
  975. (modify-syntax-entry ?\; ". 12" table) ;; SEMI, Comment start ;;
  976. (modify-syntax-entry ?\n ">" table) ;; Comment end
  977. (modify-syntax-entry ?\" "\"" table) ;; String
  978. (modify-syntax-entry ?\% "w" table) ;; Word
  979. (modify-syntax-entry ?\- "_" table) ;; Symbol
  980. (modify-syntax-entry ?\. "_" table) ;; Symbol
  981. (modify-syntax-entry ?\\ "\\" table) ;; Quote
  982. (modify-syntax-entry ?\` "'" table) ;; Prefix ` (backquote)
  983. (modify-syntax-entry ?\' "'" table) ;; Prefix ' (quote)
  984. (modify-syntax-entry ?\, "'" table) ;; Prefix , (comma)
  985. (modify-syntax-entry ?\# "'" table) ;; Prefix # (sharp)
  986. table)
  987. "Syntax table used in a Semantic grammar buffers.")
  988. (defvar semantic-grammar-mode-hook nil
  989. "Hook run when starting Semantic grammar mode.")
  990. (defvar semantic-grammar-mode-keywords-1
  991. `(("\\(\\<%%\\>\\|\\<%[{}]\\)"
  992. 0 font-lock-reference-face)
  993. ("\\(%\\)\\(\\(\\sw\\|\\s_\\)+\\)"
  994. (1 font-lock-reference-face)
  995. (2 font-lock-keyword-face))
  996. ("\\<error\\>"
  997. 0 (unless (semantic-grammar-in-lisp-p) 'bold))
  998. ("^\\(\\(\\sw\\|\\s_\\)+\\)[ \n\r\t]*:"
  999. 1 font-lock-function-name-face)
  1000. (semantic--grammar-macros-matcher
  1001. 1 ,(if (boundp 'font-lock-builtin-face)
  1002. 'font-lock-builtin-face
  1003. 'font-lock-preprocessor-face))
  1004. ("\\$\\(\\sw\\|\\s_\\)*"
  1005. 0 font-lock-variable-name-face)
  1006. ("<\\(\\(\\sw\\|\\s_\\)+\\)>"
  1007. 1 font-lock-type-face)
  1008. (,semantic-grammar-lex-c-char-re
  1009. 0 ,(if (boundp 'font-lock-constant-face)
  1010. 'font-lock-constant-face
  1011. 'font-lock-string-face) t)
  1012. ;; Must highlight :keyword here, because ':' is a punctuation in
  1013. ;; grammar mode!
  1014. ("[\r\n\t ]+:\\sw+\\>"
  1015. 0 font-lock-builtin-face)
  1016. ;; ;; Append the Semantic keywords
  1017. ;; ,@semantic-fw-font-lock-keywords
  1018. )
  1019. "Font Lock keywords used to highlight Semantic grammar buffers.")
  1020. (defvar semantic-grammar-mode-keywords-2
  1021. (append semantic-grammar-mode-keywords-1
  1022. lisp-font-lock-keywords-1)
  1023. "Font Lock keywords used to highlight Semantic grammar buffers.")
  1024. (defvar semantic-grammar-mode-keywords-3
  1025. (append semantic-grammar-mode-keywords-1
  1026. lisp-font-lock-keywords-2)
  1027. "Font Lock keywords used to highlight Semantic grammar buffers.")
  1028. (defvar semantic-grammar-mode-keywords
  1029. semantic-grammar-mode-keywords-1
  1030. "Font Lock keywords used to highlight Semantic grammar buffers.")
  1031. (defvar semantic-grammar-map
  1032. (let ((km (make-sparse-keymap)))
  1033. (define-key km "|" 'semantic-grammar-electric-punctuation)
  1034. (define-key km ";" 'semantic-grammar-electric-punctuation)
  1035. (define-key km "%" 'semantic-grammar-electric-punctuation)
  1036. (define-key km "(" 'semantic-grammar-electric-punctuation)
  1037. (define-key km ")" 'semantic-grammar-electric-punctuation)
  1038. (define-key km ":" 'semantic-grammar-electric-punctuation)
  1039. (define-key km "\t" 'semantic-grammar-indent)
  1040. (define-key km "\M-\t" 'semantic-grammar-complete)
  1041. (define-key km "\C-c\C-c" 'semantic-grammar-create-package)
  1042. (define-key km "\C-cm" 'semantic-grammar-find-macro-expander)
  1043. (define-key km "\C-cik" 'semantic-grammar-insert-keyword)
  1044. ;; (define-key km "\C-cc" 'semantic-grammar-generate-and-load)
  1045. ;; (define-key km "\C-cr" 'semantic-grammar-generate-one-rule)
  1046. km)
  1047. "Keymap used in `semantic-grammar-mode'.")
  1048. (defvar semantic-grammar-menu
  1049. '("Grammar"
  1050. ["Indent Line" semantic-grammar-indent]
  1051. ["Complete Symbol" semantic-grammar-complete]
  1052. ["Find Macro" semantic-grammar-find-macro-expander]
  1053. "--"
  1054. ["Insert %keyword" semantic-grammar-insert-keyword]
  1055. "--"
  1056. ["Update Lisp Package" semantic-grammar-create-package]
  1057. ["Recreate Lisp Package" semantic-grammar-recreate-package]
  1058. )
  1059. "Common semantic grammar menu.")
  1060. (defun semantic-grammar-setup-menu-emacs (symbol mode-menu)
  1061. "Setup a GNU Emacs grammar menu in variable SYMBOL.
  1062. MODE-MENU is an optional specific menu whose items are appended to the
  1063. common grammar menu."
  1064. (let ((items (make-symbol "items")))
  1065. `(unless (boundp ',symbol)
  1066. (easy-menu-define ,symbol (current-local-map)
  1067. "Grammar Menu" semantic-grammar-menu)
  1068. (let ((,items (cdr ,mode-menu)))
  1069. (when ,items
  1070. (easy-menu-add-item ,symbol nil "--")
  1071. (while ,items
  1072. (easy-menu-add-item ,symbol nil (car ,items))
  1073. (setq ,items (cdr ,items))))))
  1074. ))
  1075. (defun semantic-grammar-setup-menu-xemacs (symbol mode-menu)
  1076. "Setup an XEmacs grammar menu in variable SYMBOL.
  1077. MODE-MENU is an optional specific menu whose items are appended to the
  1078. common grammar menu."
  1079. (let ((items (make-symbol "items"))
  1080. (path (make-symbol "path")))
  1081. `(progn
  1082. (unless (boundp ',symbol)
  1083. (easy-menu-define ,symbol nil
  1084. "Grammar Menu" (copy-sequence semantic-grammar-menu)))
  1085. (easy-menu-add ,symbol)
  1086. (let ((,items (cdr ,mode-menu))
  1087. (,path (list (car ,symbol))))
  1088. (when ,items
  1089. (easy-menu-add-item nil ,path "--")
  1090. (while ,items
  1091. (easy-menu-add-item nil ,path (car ,items))
  1092. (setq ,items (cdr ,items))))))
  1093. ))
  1094. (defmacro semantic-grammar-setup-menu (&optional mode-menu)
  1095. "Setup a mode local grammar menu.
  1096. MODE-MENU is an optional specific menu whose items are appended to the
  1097. common grammar menu."
  1098. (let ((menu (intern (format "%s-menu" major-mode))))
  1099. (if (featurep 'xemacs)
  1100. (semantic-grammar-setup-menu-xemacs menu mode-menu)
  1101. (semantic-grammar-setup-menu-emacs menu mode-menu))))
  1102. (defsubst semantic-grammar-in-lisp-p ()
  1103. "Return non-nil if point is in Lisp code."
  1104. (or (>= (point) (semantic-grammar-epilogue-start))
  1105. (condition-case nil
  1106. (save-excursion
  1107. (up-list -1)
  1108. t)
  1109. (error nil))))
  1110. (defun semantic-grammar-edits-new-change-hook-fcn (overlay)
  1111. "Function set into `semantic-edits-new-change-hook'.
  1112. Argument OVERLAY is the overlay created to mark the change.
  1113. When OVERLAY marks a change in the scope of a nonterminal tag extend
  1114. the change bounds to encompass the whole nonterminal tag."
  1115. (let ((outer (car (semantic-find-tag-by-overlay-in-region
  1116. (semantic-edits-os overlay)
  1117. (semantic-edits-oe overlay)))))
  1118. (if (semantic-tag-of-class-p outer 'nonterminal)
  1119. (semantic-overlay-move overlay
  1120. (semantic-tag-start outer)
  1121. (semantic-tag-end outer)))))
  1122. (defun semantic-grammar-mode ()
  1123. "Initialize a buffer for editing Semantic grammars.
  1124. \\{semantic-grammar-map}"
  1125. (interactive)
  1126. (kill-all-local-variables)
  1127. (setq major-mode 'semantic-grammar-mode
  1128. mode-name "Semantic Grammar Framework")
  1129. (set (make-local-variable 'parse-sexp-ignore-comments) t)
  1130. (set (make-local-variable 'comment-start) ";;")
  1131. ;; Look within the line for a ; following an even number of backslashes
  1132. ;; after either a non-backslash or the line beginning.
  1133. (set (make-local-variable 'comment-start-skip)
  1134. "\\(\\(^\\|[^\\\\\n]\\)\\(\\\\\\\\\\)*\\);+ *")
  1135. (set-syntax-table semantic-grammar-syntax-table)
  1136. (use-local-map semantic-grammar-map)
  1137. (set (make-local-variable 'indent-line-function)
  1138. 'semantic-grammar-indent)
  1139. (set (make-local-variable 'fill-paragraph-function)
  1140. 'lisp-fill-paragraph)
  1141. (set (make-local-variable 'font-lock-multiline)
  1142. 'undecided)
  1143. (set (make-local-variable 'font-lock-defaults)
  1144. '((semantic-grammar-mode-keywords
  1145. semantic-grammar-mode-keywords-1
  1146. semantic-grammar-mode-keywords-2
  1147. semantic-grammar-mode-keywords-3)
  1148. nil ;; perform string/comment fontification
  1149. nil ;; keywords are case sensitive.
  1150. ;; This puts _ & - as a word constituent,
  1151. ;; simplifying our keywords significantly
  1152. ((?_ . "w") (?- . "w"))))
  1153. ;; Setup Semantic to parse grammar
  1154. (semantic-grammar-wy--install-parser)
  1155. (setq semantic-lex-comment-regex ";;"
  1156. semantic-lex-analyzer 'semantic-grammar-lexer
  1157. semantic-type-relation-separator-character '(":")
  1158. semantic-symbol->name-assoc-list
  1159. '(
  1160. (code . "Setup Code")
  1161. (keyword . "Keyword")
  1162. (token . "Token")
  1163. (nonterminal . "Nonterminal")
  1164. (rule . "Rule")
  1165. ))
  1166. (set (make-local-variable 'semantic-format-face-alist)
  1167. '(
  1168. (code . default)
  1169. (keyword . font-lock-keyword-face)
  1170. (token . font-lock-type-face)
  1171. (nonterminal . font-lock-function-name-face)
  1172. (rule . default)
  1173. ))
  1174. (set (make-local-variable 'semantic-stickyfunc-sticky-classes)
  1175. '(nonterminal))
  1176. ;; Before each change, clear the cached regexp used to highlight
  1177. ;; macros local in this grammar.
  1178. (semantic-make-local-hook 'before-change-functions)
  1179. (add-hook 'before-change-functions
  1180. 'semantic--grammar-clear-macros-regexp-2 nil t)
  1181. ;; Handle safe re-parse of grammar rules.
  1182. (semantic-make-local-hook 'semantic-edits-new-change-hooks)
  1183. (add-hook 'semantic-edits-new-change-hooks
  1184. 'semantic-grammar-edits-new-change-hook-fcn
  1185. nil t)
  1186. (semantic-run-mode-hooks 'semantic-grammar-mode-hook))
  1187. ;;;;
  1188. ;;;; Useful commands
  1189. ;;;;
  1190. (defvar semantic-grammar-skip-quoted-syntax-table
  1191. (let ((st (copy-syntax-table semantic-grammar-syntax-table)))
  1192. (modify-syntax-entry ?\' "$" st)
  1193. st)
  1194. "Syntax table to skip a whole quoted expression in grammar code.
  1195. Consider quote as a \"paired delimiter\", so `forward-sexp' will skip
  1196. whole quoted expression.")
  1197. (defsubst semantic-grammar-backward-item ()
  1198. "Move point to beginning of the previous grammar item."
  1199. (forward-comment (- (point-max)))
  1200. (if (zerop (skip-syntax-backward "."))
  1201. (if (eq (char-before) ?\')
  1202. (with-syntax-table
  1203. ;; Can't be Lisp code here! Temporarily consider quote
  1204. ;; as a "paired delimiter", so `forward-sexp' can skip
  1205. ;; the whole quoted expression.
  1206. semantic-grammar-skip-quoted-syntax-table
  1207. (forward-sexp -1))
  1208. (forward-sexp -1))))
  1209. (defun semantic-grammar-anchored-indentation ()
  1210. "Return indentation based on previous anchor character found."
  1211. (let (indent)
  1212. (save-excursion
  1213. (while (not indent)
  1214. (semantic-grammar-backward-item)
  1215. (cond
  1216. ((bobp)
  1217. (setq indent 0))
  1218. ((looking-at ":\\(\\s-\\|$\\)")
  1219. (setq indent (current-column))
  1220. (forward-char)
  1221. (skip-syntax-forward "-")
  1222. (if (eolp) (setq indent 2))
  1223. )
  1224. ((and (looking-at "[;%]")
  1225. (not (looking-at "\\<%prec\\>")))
  1226. (setq indent 0)
  1227. ))))
  1228. indent))
  1229. (defun semantic-grammar-do-grammar-indent ()
  1230. "Indent a line of grammar.
  1231. When called the point is not in Lisp code."
  1232. (let (indent n)
  1233. (save-excursion
  1234. (beginning-of-line)
  1235. (skip-syntax-forward "-")
  1236. (setq indent (current-column))
  1237. (cond
  1238. ((or (bobp)
  1239. (looking-at "\\(\\w\\|\\s_\\)+\\s-*:")
  1240. (and (looking-at "%")
  1241. (not (looking-at "%prec\\>"))))
  1242. (setq n 0))
  1243. ((looking-at ":")
  1244. (setq n 2))
  1245. ((and (looking-at ";;")
  1246. (save-excursion (forward-comment (point-max))
  1247. (looking-at ":")))
  1248. (setq n 1))
  1249. (t
  1250. (setq n (semantic-grammar-anchored-indentation))
  1251. (unless (zerop n)
  1252. (cond
  1253. ((looking-at ";;")
  1254. (setq n (1- n)))
  1255. ((looking-at "[|;]")
  1256. )
  1257. (t
  1258. (setq n (+ n 2)))))))
  1259. (when (/= n indent)
  1260. (beginning-of-line)
  1261. (delete-horizontal-space)
  1262. (indent-to n)))))
  1263. (defvar semantic-grammar-brackets-as-parens-syntax-table
  1264. (let ((st (copy-syntax-table emacs-lisp-mode-syntax-table)))
  1265. (modify-syntax-entry ?\{ "(} " st)
  1266. (modify-syntax-entry ?\} "){ " st)
  1267. st)
  1268. "Syntax table that consider brackets as parenthesis.
  1269. So `lisp-indent-line' will work inside bracket blocks.")
  1270. (defun semantic-grammar-do-lisp-indent ()
  1271. "Maybe run the Emacs Lisp indenter on a line of code.
  1272. Return nil if not in a Lisp expression."
  1273. (condition-case nil
  1274. (save-excursion
  1275. (beginning-of-line)
  1276. (skip-chars-forward "\t ")
  1277. (let ((first (point)))
  1278. (or (>= first (semantic-grammar-epilogue-start))
  1279. (up-list -1))
  1280. (condition-case nil
  1281. (while t
  1282. (up-list -1))
  1283. (error nil))
  1284. (beginning-of-line)
  1285. (save-restriction
  1286. (narrow-to-region (point) first)
  1287. (goto-char (point-max))
  1288. (with-syntax-table
  1289. ;; Temporarily consider brackets as parenthesis so
  1290. ;; `lisp-indent-line' can indent Lisp code inside
  1291. ;; brackets.
  1292. semantic-grammar-brackets-as-parens-syntax-table
  1293. (lisp-indent-line))))
  1294. t)
  1295. (error nil)))
  1296. (defun semantic-grammar-indent ()
  1297. "Indent the current line.
  1298. Use the Lisp or grammar indenter depending on point location."
  1299. (interactive)
  1300. (let ((orig (point))
  1301. first)
  1302. (or (semantic-grammar-do-lisp-indent)
  1303. (semantic-grammar-do-grammar-indent))
  1304. (setq first (save-excursion
  1305. (beginning-of-line)
  1306. (skip-chars-forward "\t ")
  1307. (point)))
  1308. (if (or (< orig first) (/= orig (point)))
  1309. (goto-char first))))
  1310. (defun semantic-grammar-electric-punctuation ()
  1311. "Insert and reindent for the symbol just typed in."
  1312. (interactive)
  1313. (self-insert-command 1)
  1314. (save-excursion
  1315. (semantic-grammar-indent)))
  1316. (defun semantic-grammar-complete ()
  1317. "Attempt to complete the symbol under point.
  1318. Completion is position sensitive. If the cursor is in a match section of
  1319. a rule, then nonterminals symbols are scanned. If the cursor is in a Lisp
  1320. expression then Lisp symbols are completed."
  1321. (interactive)
  1322. (if (semantic-grammar-in-lisp-p)
  1323. ;; We are in lisp code. Do lisp completion.
  1324. (lisp-complete-symbol)
  1325. ;; We are not in lisp code. Do rule completion.
  1326. (let* ((nonterms (semantic-find-tags-by-class 'nonterminal (current-buffer)))
  1327. (sym (car (semantic-ctxt-current-symbol)))
  1328. (ans (try-completion sym nonterms)))
  1329. (cond ((eq ans t)
  1330. ;; All done
  1331. (message "Symbols is already complete"))
  1332. ((and (stringp ans) (string= ans sym))
  1333. ;; Max matchable. Show completions.
  1334. (with-output-to-temp-buffer "*Completions*"
  1335. (display-completion-list (all-completions sym nonterms)))
  1336. )
  1337. ((stringp ans)
  1338. ;; Expand the completions
  1339. (forward-sexp -1)
  1340. (delete-region (point) (progn (forward-sexp 1) (point)))
  1341. (insert ans))
  1342. (t (message "No Completions."))
  1343. ))
  1344. ))
  1345. (defun semantic-grammar-insert-keyword (name)
  1346. "Insert a new %keyword declaration with NAME.
  1347. Assumes it is typed in with the correct casing."
  1348. (interactive "sKeyword: ")
  1349. (if (not (bolp)) (insert "\n"))
  1350. (insert "%keyword " (upcase name) " \"" name "\"
  1351. %put " (upcase name) " summary
  1352. \"\"\n")
  1353. (forward-char -2))
  1354. ;;; Macro facilities
  1355. ;;
  1356. (defsubst semantic--grammar-macro-function-tag (name)
  1357. "Search for a function tag for the grammar macro with name NAME.
  1358. Return the tag found or nil if not found."
  1359. (car (semantic-find-tags-by-class
  1360. 'function
  1361. (or (semantic-find-tags-by-name name (current-buffer))
  1362. (and (featurep 'semantic/db)
  1363. semanticdb-current-database
  1364. (cdar (semanticdb-find-tags-by-name name nil t)))))))
  1365. (defsubst semantic--grammar-macro-lib-part (def)
  1366. "Return the library part of the grammar macro defined by DEF."
  1367. (let ((suf (format "-%s\\'" (regexp-quote (symbol-name (car def)))))
  1368. (fun (symbol-name (cdr def))))
  1369. (substring fun 0 (string-match suf fun))))
  1370. (defun semantic--grammar-macro-compl-elt (def &optional full)
  1371. "Return a completion entry for the grammar macro defined by DEF.
  1372. If optional argument FULL is non-nil qualify the macro name with the
  1373. library found in DEF."
  1374. (let ((mac (car def))
  1375. (lib (semantic--grammar-macro-lib-part def)))
  1376. (cons (if full
  1377. (format "%s/%s" mac lib)
  1378. (symbol-name mac))
  1379. (list mac lib))))
  1380. (defun semantic--grammar-macro-compl-dict ()
  1381. "Return a completion dictionary of macro definitions."
  1382. (let ((defs (semantic-grammar-macros))
  1383. def dups dict)
  1384. (while defs
  1385. (setq def (car defs)
  1386. defs (cdr defs))
  1387. (if (or (assoc (car def) defs) (assoc (car def) dups))
  1388. (push def dups)
  1389. (push (semantic--grammar-macro-compl-elt def) dict)))
  1390. (while dups
  1391. (setq def (car dups)
  1392. dups (cdr dups))
  1393. (push (semantic--grammar-macro-compl-elt def t) dict))
  1394. dict))
  1395. (defun semantic-grammar-find-macro-expander (macro-name library)
  1396. "Visit the Emacs Lisp library where a grammar macro is implemented.
  1397. MACRO-NAME is a symbol that identifies a grammar macro.
  1398. LIBRARY is the name (sans extension) of the Emacs Lisp library where
  1399. to start searching the macro implementation. Lookup in included
  1400. libraries, if necessary.
  1401. Find a function tag (in current tags table) whose name contains MACRO-NAME.
  1402. Select the buffer containing the tag's definition, and move point there."
  1403. (interactive
  1404. (let* ((dic (semantic--grammar-macro-compl-dict))
  1405. (def (assoc (completing-read "Macro: " dic nil 1) dic)))
  1406. (or (cdr def) '(nil nil))))
  1407. (when (and macro-name library)
  1408. (let* ((lib (format "%s.el" library))
  1409. (buf (find-file-noselect (or (locate-library lib t) lib)))
  1410. (tag (with-current-buffer buf
  1411. (semantic--grammar-macro-function-tag
  1412. (format "%s-%s" library macro-name)))))
  1413. (if tag
  1414. (progn
  1415. (require 'semantic/decorate)
  1416. (pop-to-buffer (semantic-tag-buffer tag))
  1417. (goto-char (semantic-tag-start tag))
  1418. (semantic-momentary-highlight-tag tag))
  1419. (pop-to-buffer buf)
  1420. (message "No expander found in library %s for macro %s"
  1421. library macro-name)))))
  1422. ;;; Additional help
  1423. ;;
  1424. (defvar semantic-grammar-syntax-help
  1425. `(
  1426. ;; Lexical Symbols
  1427. ("symbol" . "Syntax: A symbol of alpha numeric and symbol characters")
  1428. ("number" . "Syntax: Numeric characters.")
  1429. ("punctuation" . "Syntax: Punctuation character.")
  1430. ("semantic-list" . "Syntax: A list delimited by any valid list characters")
  1431. ("open-paren" . "Syntax: Open Parenthesis character")
  1432. ("close-paren" . "Syntax: Close Parenthesis character")
  1433. ("string" . "Syntax: String character delimited text")
  1434. ("comment" . "Syntax: Comment character delimited text")
  1435. ;; Special Macros
  1436. ("EMPTY" . "Syntax: Match empty text")
  1437. ("ASSOC" . "Lambda Key: (ASSOC key1 value1 key2 value2 ...)")
  1438. ("EXPAND" . "Lambda Key: (EXPAND <list id> <rule>)")
  1439. ("EXPANDFULL" . "Lambda Key: (EXPANDFULL <list id> <rule>)")
  1440. ;; Tag Generator Macros
  1441. ("TAG" . "Generic Tag Generation: (TAG <name> <tag-class> [ :key value ]*)")
  1442. ("VARIABLE-TAG" . "(VARIABLE-TAG <name> <lang-type> <default-value> [ :key value ]*)")
  1443. ("FUNCTION-TAG" . "(FUNCTION-TAG <name> <lang-type> <arg-list> [ :key value ]*)")
  1444. ("TYPE-TAG" . "(TYPE-TAG <name> <lang-type> <part-list> <parents> [ :key value ]*)")
  1445. ("INCLUDE-TAG" . "(INCLUDE-TAG <name> <system-flag> [ :key value ]*)")
  1446. ("PACKAGE-TAG" . "(PACKAGE-TAG <name> <detail> [ :key value ]*)")
  1447. ("CODE-TAG" . "(CODE-TAG <name> <detail> [ :key value ]*)")
  1448. ("ALIAS-TAG" . "(ALIAS-TAG <name> <aliasclass> <definition> [:key value]*)")
  1449. ;; Special value macros
  1450. ("$1" . "Match Value: Value from match list in slot 1")
  1451. ("$2" . "Match Value: Value from match list in slot 2")
  1452. ("$3" . "Match Value: Value from match list in slot 3")
  1453. ("$4" . "Match Value: Value from match list in slot 4")
  1454. ("$5" . "Match Value: Value from match list in slot 5")
  1455. ("$6" . "Match Value: Value from match list in slot 6")
  1456. ("$7" . "Match Value: Value from match list in slot 7")
  1457. ("$8" . "Match Value: Value from match list in slot 8")
  1458. ("$9" . "Match Value: Value from match list in slot 9")
  1459. ;; Same, but with annoying , in front.
  1460. (",$1" . "Match Value: Value from match list in slot 1")
  1461. (",$2" . "Match Value: Value from match list in slot 2")
  1462. (",$3" . "Match Value: Value from match list in slot 3")
  1463. (",$4" . "Match Value: Value from match list in slot 4")
  1464. (",$5" . "Match Value: Value from match list in slot 5")
  1465. (",$6" . "Match Value: Value from match list in slot 6")
  1466. (",$7" . "Match Value: Value from match list in slot 7")
  1467. (",$8" . "Match Value: Value from match list in slot 8")
  1468. (",$9" . "Match Value: Value from match list in slot 9")
  1469. )
  1470. "Association of syntax elements, and the corresponding help.")
  1471. (defun semantic-grammar-eldoc-get-macro-docstring (macro expander)
  1472. "Return a one-line docstring for the given grammar MACRO.
  1473. EXPANDER is the name of the function that expands MACRO."
  1474. (require 'eldoc)
  1475. (if (and (eq expander (aref eldoc-last-data 0))
  1476. (eq 'function (aref eldoc-last-data 2)))
  1477. (aref eldoc-last-data 1)
  1478. (let ((doc (help-split-fundoc (documentation expander t) expander)))
  1479. (cond
  1480. (doc
  1481. (setq doc (car doc))
  1482. (string-match "\\`[^ )]* ?" doc)
  1483. (setq doc (concat "(" (substring doc (match-end 0)))))
  1484. (t
  1485. (setq doc (eldoc-function-argstring expander))))
  1486. (when doc
  1487. (setq doc
  1488. (eldoc-docstring-format-sym-doc
  1489. macro (format "==> %s %s" expander doc) 'default))
  1490. (eldoc-last-data-store expander doc 'function))
  1491. doc)))
  1492. (define-mode-local-override semantic-idle-summary-current-symbol-info
  1493. semantic-grammar-mode ()
  1494. "Display additional eldoc information about grammar syntax elements.
  1495. Syntax element is the current symbol at point.
  1496. If it is associated a help string in `semantic-grammar-syntax-help',
  1497. return that string.
  1498. If it is a macro name, return a description of the associated expander
  1499. function parameter list.
  1500. If it is a function name, return a description of this function
  1501. parameter list.
  1502. It it is a variable name, return a brief (one-line) documentation
  1503. string for the variable.
  1504. If a default description of the current context can be obtained,
  1505. return it.
  1506. Otherwise return nil."
  1507. (require 'eldoc)
  1508. (let* ((elt (car (semantic-ctxt-current-symbol)))
  1509. (val (and elt (cdr (assoc elt semantic-grammar-syntax-help)))))
  1510. (when (and (not val) elt (semantic-grammar-in-lisp-p))
  1511. ;; Ensure to load macro definitions before doing `intern-soft'.
  1512. (setq val (semantic-grammar-macros)
  1513. elt (intern-soft elt)
  1514. val (and elt (cdr (assq elt val))))
  1515. (cond
  1516. ;; Grammar macro
  1517. ((and val (fboundp val))
  1518. (setq val (semantic-grammar-eldoc-get-macro-docstring elt val)))
  1519. ;; Function
  1520. ((and elt (fboundp elt))
  1521. (setq val (eldoc-get-fnsym-args-string elt)))
  1522. ;; Variable
  1523. ((and elt (boundp elt))
  1524. (setq val (eldoc-get-var-docstring elt)))
  1525. (t nil)))
  1526. (or val (semantic-idle-summary-current-symbol-info-default))))
  1527. (define-mode-local-override semantic-tag-boundary-p
  1528. semantic-grammar-mode (tag)
  1529. "Return non-nil for tags that should have a boundary drawn.
  1530. Only tags of type 'nonterminal will be so marked."
  1531. (let ((c (semantic-tag-class tag)))
  1532. (eq c 'nonterminal)))
  1533. (define-mode-local-override semantic-ctxt-current-function
  1534. semantic-grammar-mode (&optional point)
  1535. "Determine the name of the current function at POINT."
  1536. (save-excursion
  1537. (and point (goto-char point))
  1538. (when (semantic-grammar-in-lisp-p)
  1539. (with-mode-local emacs-lisp-mode
  1540. (semantic-ctxt-current-function)))))
  1541. (define-mode-local-override semantic-ctxt-current-argument
  1542. semantic-grammar-mode (&optional point)
  1543. "Determine the argument index of the called function at POINT."
  1544. (save-excursion
  1545. (and point (goto-char point))
  1546. (when (semantic-grammar-in-lisp-p)
  1547. (with-mode-local emacs-lisp-mode
  1548. (semantic-ctxt-current-argument)))))
  1549. (define-mode-local-override semantic-ctxt-current-assignment
  1550. semantic-grammar-mode (&optional point)
  1551. "Determine the tag being assigned into at POINT."
  1552. (save-excursion
  1553. (and point (goto-char point))
  1554. (when (semantic-grammar-in-lisp-p)
  1555. (with-mode-local emacs-lisp-mode
  1556. (semantic-ctxt-current-assignment)))))
  1557. (define-mode-local-override semantic-ctxt-current-class-list
  1558. semantic-grammar-mode (&optional point)
  1559. "Determine the class of tags that can be used at POINT."
  1560. (save-excursion
  1561. (and point (goto-char point))
  1562. (if (semantic-grammar-in-lisp-p)
  1563. (with-mode-local emacs-lisp-mode
  1564. (semantic-ctxt-current-class-list))
  1565. '(nonterminal keyword))))
  1566. (define-mode-local-override semantic-ctxt-current-mode
  1567. semantic-grammar-mode (&optional point)
  1568. "Return the major mode active at POINT.
  1569. POINT defaults to the value of point in current buffer.
  1570. Return `emacs-lisp-mode' is POINT is within Lisp code, otherwise
  1571. return the current major mode."
  1572. (save-excursion
  1573. (and point (goto-char point))
  1574. (if (semantic-grammar-in-lisp-p)
  1575. 'emacs-lisp-mode
  1576. (semantic-ctxt-current-mode-default))))
  1577. (define-mode-local-override semantic-format-tag-abbreviate
  1578. semantic-grammar-mode (tag &optional parent color)
  1579. "Return a string abbreviation of TAG.
  1580. Optional PARENT is not used.
  1581. Optional COLOR is used to flag if color is added to the text."
  1582. (let ((class (semantic-tag-class tag))
  1583. (name (semantic-format-tag-name tag parent color)))
  1584. (cond
  1585. ((eq class 'nonterminal)
  1586. (concat name ":"))
  1587. ((eq class 'setting)
  1588. "%settings%")
  1589. ((memq class '(rule keyword))
  1590. name)
  1591. (t
  1592. (concat "%" (symbol-name class) " " name)))))
  1593. (define-mode-local-override semantic-format-tag-summarize
  1594. semantic-grammar-mode (tag &optional parent color)
  1595. "Return a string summarizing TAG.
  1596. Optional PARENT is not used.
  1597. Optional argument COLOR determines if color is added to the text."
  1598. (let ((class (semantic-tag-class tag))
  1599. (name (semantic-format-tag-name tag parent color))
  1600. (label nil)
  1601. (desc nil))
  1602. (cond
  1603. ((eq class 'nonterminal)
  1604. (setq label "Nonterminal: "
  1605. desc (format
  1606. " with %d match lists."
  1607. (length (semantic-tag-components tag)))))
  1608. ((eq class 'keyword)
  1609. (setq label "Keyword: ")
  1610. (let (summary)
  1611. (semantic--find-tags-by-function
  1612. #'(lambda (put)
  1613. (unless summary
  1614. (setq summary (cdr (assoc "summary"
  1615. (semantic-tag-get-attribute
  1616. put :value))))))
  1617. ;; Get `put' tag with TAG name.
  1618. (semantic-find-tags-by-name-regexp
  1619. (regexp-quote (semantic-tag-name tag))
  1620. (semantic-find-tags-by-class 'put (current-buffer))))
  1621. (setq desc (concat " = "
  1622. (semantic-tag-get-attribute tag :value)
  1623. (if summary
  1624. (concat " - " (read summary))
  1625. "")))))
  1626. ((eq class 'token)
  1627. (setq label "Token: ")
  1628. (let ((val (semantic-tag-get-attribute tag :value))
  1629. (names (semantic-tag-get-attribute tag :rest))
  1630. (type (semantic-tag-type tag)))
  1631. (if names
  1632. (setq name (mapconcat 'identity (cons name names) " ")))
  1633. (setq desc (concat
  1634. (if type
  1635. (format " <%s>" type)
  1636. "")
  1637. (if val
  1638. (format "%s%S" val (if type " " ""))
  1639. "")))))
  1640. ((eq class 'assoc)
  1641. (setq label "Assoc: ")
  1642. (let ((val (semantic-tag-get-attribute tag :value))
  1643. (type (semantic-tag-type tag)))
  1644. (setq desc (concat
  1645. (if type
  1646. (format " <%s>" type)
  1647. "")
  1648. (if val
  1649. (concat " " (mapconcat 'identity val " "))
  1650. "")))))
  1651. (t
  1652. (setq desc (semantic-format-tag-abbreviate tag parent color))))
  1653. (if (and color label)
  1654. (setq label (semantic--format-colorize-text label 'label)))
  1655. (if (and color label desc)
  1656. (setq desc (semantic--format-colorize-text desc 'comment)))
  1657. (if label
  1658. (concat label name desc)
  1659. ;; Just a description is the abbreviated version
  1660. desc)))
  1661. ;;; Semantic Analysis
  1662. (define-mode-local-override semantic-analyze-current-context
  1663. semantic-grammar-mode (point)
  1664. "Provide a semantic analysis object describing a context in a grammar."
  1665. (require 'semantic/analyze)
  1666. (if (semantic-grammar-in-lisp-p)
  1667. (with-mode-local emacs-lisp-mode
  1668. (semantic-analyze-current-context point))
  1669. (let* ((context-return nil)
  1670. (prefixandbounds (semantic-ctxt-current-symbol-and-bounds))
  1671. (prefix (car prefixandbounds))
  1672. (bounds (nth 2 prefixandbounds))
  1673. (prefixsym nil)
  1674. (prefixclass (semantic-ctxt-current-class-list))
  1675. )
  1676. ;; Do context for rules when in a match list.
  1677. (setq prefixsym
  1678. (semantic-find-first-tag-by-name
  1679. (car prefix)
  1680. (current-buffer)))
  1681. (setq context-return
  1682. (semantic-analyze-context
  1683. "context-for-semantic-grammar"
  1684. :buffer (current-buffer)
  1685. :scope nil
  1686. :bounds bounds
  1687. :prefix (if prefixsym
  1688. (list prefixsym)
  1689. prefix)
  1690. :prefixtypes nil
  1691. :prefixclass prefixclass
  1692. ))
  1693. context-return)))
  1694. (define-mode-local-override semantic-analyze-possible-completions
  1695. semantic-grammar-mode (context)
  1696. "Return a list of possible completions based on CONTEXT."
  1697. (require 'semantic/analyze/complete)
  1698. (if (semantic-grammar-in-lisp-p)
  1699. (with-mode-local emacs-lisp-mode
  1700. (semantic-analyze-possible-completions context))
  1701. (with-current-buffer (oref context buffer)
  1702. (let* ((prefix (car (oref context :prefix)))
  1703. (completetext (cond ((semantic-tag-p prefix)
  1704. (semantic-tag-name prefix))
  1705. ((stringp prefix)
  1706. prefix)
  1707. ((stringp (car prefix))
  1708. (car prefix))))
  1709. (tags (semantic-find-tags-for-completion completetext
  1710. (current-buffer))))
  1711. (semantic-analyze-tags-of-class-list
  1712. tags (oref context prefixclass)))
  1713. )))
  1714. (provide 'semantic/grammar)
  1715. ;;; semantic/grammar.el ends here