Commit | Line | Data |
---|---|---|
469d2149 CY |
1 | ;;; bovine-grammar.el --- Bovine's input grammar mode |
2 | ;; | |
acaf905b | 3 | ;; Copyright (C) 2002-2012 Free Software Foundation, Inc. |
469d2149 CY |
4 | ;; |
5 | ;; Author: David Ponce <david@dponce.com> | |
6 | ;; Maintainer: David Ponce <david@dponce.com> | |
7 | ;; Created: 26 Aug 2002 | |
8 | ;; Keywords: syntax | |
9 | ||
10 | ;; This file is part of GNU Emacs. | |
11 | ||
12 | ;; GNU Emacs is free software: you can redistribute it and/or modify | |
13 | ;; it under the terms of the GNU General Public License as published by | |
14 | ;; the Free Software Foundation, either version 3 of the License, or | |
15 | ;; (at your option) any later version. | |
16 | ||
17 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
18 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 | ;; GNU General Public License for more details. | |
21 | ||
22 | ;; You should have received a copy of the GNU General Public License | |
23 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |
24 | ||
25 | ;;; Commentary: | |
26 | ;; | |
27 | ;; Major mode for editing Bovine's input grammar (.by) files. | |
28 | ||
29 | ;;; History: | |
30 | ||
31 | ;;; Code: | |
32 | (require 'semantic) | |
33 | (require 'semantic/grammar) | |
34 | (require 'semantic/find) | |
f79fbbc7 CY |
35 | (require 'semantic/lex) |
36 | (require 'semantic/wisent) | |
37 | (require 'semantic/bovine) | |
469d2149 CY |
38 | |
39 | (defun bovine-grammar-EXPAND (bounds nonterm) | |
40 | "Expand call to EXPAND grammar macro. | |
41 | Return the form to parse from within a nonterminal between BOUNDS. | |
42 | NONTERM is the nonterminal symbol to start with." | |
43 | `(semantic-bovinate-from-nonterminal | |
44 | (car ,bounds) (cdr ,bounds) ',nonterm)) | |
45 | ||
46 | (defun bovine-grammar-EXPANDFULL (bounds nonterm) | |
47 | "Expand call to EXPANDFULL grammar macro. | |
48 | Return the form to recursively parse the area between BOUNDS. | |
49 | NONTERM is the nonterminal symbol to start with." | |
50 | `(semantic-parse-region | |
51 | (car ,bounds) (cdr ,bounds) ',nonterm 1)) | |
52 | ||
53 | (defun bovine-grammar-TAG (name class &rest attributes) | |
54 | "Expand call to TAG grammar macro. | |
55 | Return the form to create a generic semantic tag. | |
56 | See the function `semantic-tag' for the meaning of arguments NAME, | |
57 | CLASS and ATTRIBUTES." | |
58 | `(semantic-tag ,name ,class ,@attributes)) | |
59 | ||
60 | (defun bovine-grammar-VARIABLE-TAG (name type default-value &rest attributes) | |
61 | "Expand call to VARIABLE-TAG grammar macro. | |
62 | Return the form to create a semantic tag of class variable. | |
63 | See the function `semantic-tag-new-variable' for the meaning of | |
64 | arguments NAME, TYPE, DEFAULT-VALUE and ATTRIBUTES." | |
65 | `(semantic-tag-new-variable ,name ,type ,default-value ,@attributes)) | |
66 | ||
67 | (defun bovine-grammar-FUNCTION-TAG (name type arg-list &rest attributes) | |
68 | "Expand call to FUNCTION-TAG grammar macro. | |
69 | Return the form to create a semantic tag of class function. | |
70 | See the function `semantic-tag-new-function' for the meaning of | |
71 | arguments NAME, TYPE, ARG-LIST and ATTRIBUTES." | |
72 | `(semantic-tag-new-function ,name ,type ,arg-list ,@attributes)) | |
73 | ||
74 | (defun bovine-grammar-TYPE-TAG (name type members parents &rest attributes) | |
75 | "Expand call to TYPE-TAG grammar macro. | |
76 | Return the form to create a semantic tag of class type. | |
77 | See the function `semantic-tag-new-type' for the meaning of arguments | |
78 | NAME, TYPE, MEMBERS, PARENTS and ATTRIBUTES." | |
79 | `(semantic-tag-new-type ,name ,type ,members ,parents ,@attributes)) | |
80 | ||
81 | (defun bovine-grammar-INCLUDE-TAG (name system-flag &rest attributes) | |
82 | "Expand call to INCLUDE-TAG grammar macro. | |
83 | Return the form to create a semantic tag of class include. | |
84 | See the function `semantic-tag-new-include' for the meaning of | |
85 | arguments NAME, SYSTEM-FLAG and ATTRIBUTES." | |
86 | `(semantic-tag-new-include ,name ,system-flag ,@attributes)) | |
87 | ||
88 | (defun bovine-grammar-PACKAGE-TAG (name detail &rest attributes) | |
89 | "Expand call to PACKAGE-TAG grammar macro. | |
90 | Return the form to create a semantic tag of class package. | |
91 | See the function `semantic-tag-new-package' for the meaning of | |
92 | arguments NAME, DETAIL and ATTRIBUTES." | |
93 | `(semantic-tag-new-package ,name ,detail ,@attributes)) | |
94 | ||
95 | (defun bovine-grammar-CODE-TAG (name detail &rest attributes) | |
96 | "Expand call to CODE-TAG grammar macro. | |
97 | Return the form to create a semantic tag of class code. | |
98 | See the function `semantic-tag-new-code' for the meaning of arguments | |
99 | NAME, DETAIL and ATTRIBUTES." | |
100 | `(semantic-tag-new-code ,name ,detail ,@attributes)) | |
101 | ||
102 | (defun bovine-grammar-ALIAS-TAG (name aliasclass definition &rest attributes) | |
103 | "Expand call to ALIAS-TAG grammar macro. | |
104 | Return the form to create a semantic tag of class alias. | |
105 | See the function `semantic-tag-new-alias' for the meaning of arguments | |
106 | NAME, ALIASCLASS, DEFINITION and ATTRIBUTES." | |
107 | `(semantic-tag-new-alias ,name ,aliasclass ,definition ,@attributes)) | |
108 | ||
109 | ;; Cache of macro definitions currently in use. | |
110 | (defvar bovine--grammar-macros nil) | |
111 | ||
72b8747b DE |
112 | ;; Detect if we have an Emacs with newstyle unquotes allowed outside |
113 | ;; of backquote. | |
114 | ;; This should probably be changed to a test to (= emacs-major-version 24) | |
115 | ;; when it is released, but at the moment it might be possible that people | |
116 | ;; are using an older snapshot. | |
117 | (defvar bovine--grammar-newstyle-unquote | |
303d001f | 118 | (equal '(\, test) (read ",test"))) |
72b8747b | 119 | |
469d2149 CY |
120 | (defun bovine-grammar-expand-form (form quotemode &optional inplace) |
121 | "Expand FORM into a new one suitable to the bovine parser. | |
122 | FORM is a list in which we are substituting. | |
123 | Argument QUOTEMODE is non-nil if we are in backquote mode. | |
124 | When non-nil, optional argument INPLACE indicates that FORM is being | |
125 | expanded from elsewhere." | |
469d2149 CY |
126 | (when (eq (car form) 'quote) |
127 | (setq form (cdr form)) | |
128 | (cond | |
129 | ((and (= (length form) 1) (listp (car form))) | |
130 | (insert "\n(append") | |
131 | (bovine-grammar-expand-form (car form) quotemode nil) | |
132 | (insert ")") | |
133 | (setq form nil inplace nil) | |
134 | ) | |
135 | ((and (= (length form) 1) (symbolp (car form))) | |
136 | (insert "\n'" (symbol-name (car form))) | |
137 | (setq form nil inplace nil) | |
138 | ) | |
139 | (t | |
140 | (insert "\n(list") | |
141 | (setq inplace t) | |
142 | ))) | |
143 | (let ((macro (assq (car form) bovine--grammar-macros)) | |
144 | inlist first n q x) | |
145 | (if macro | |
146 | (bovine-grammar-expand-form | |
147 | (apply (cdr macro) (cdr form)) | |
148 | quotemode t) | |
149 | (if inplace (insert "\n(")) | |
150 | (while form | |
151 | (setq first (car form) | |
152 | form (cdr form)) | |
72b8747b DE |
153 | ;; Hack for dealing with new reading of unquotes outside of |
154 | ;; backquote (introduced in rev. 102591 in emacs-bzr). | |
155 | (when (and bovine--grammar-newstyle-unquote | |
156 | (listp first) | |
157 | (or (equal (car first) '\,) | |
158 | (equal (car first) '\,@))) | |
159 | (if (listp (cadr first)) | |
160 | (setq form (append (cdr first) form) | |
161 | first (car first)) | |
162 | (setq first (intern (concat (symbol-name (car first)) | |
163 | (symbol-name (cadr first))))))) | |
469d2149 CY |
164 | (cond |
165 | ((eq first nil) | |
166 | (when (and (not inlist) (not inplace)) | |
167 | (insert "\n(list") | |
168 | (setq inlist t)) | |
169 | (insert " nil") | |
170 | ) | |
171 | ((listp first) | |
172 | ;;(let ((fn (and (symbolp (caar form)) (fboundp (caar form))))) | |
173 | (when (and (not inlist) (not inplace)) | |
174 | (insert "\n(list") | |
175 | (setq inlist t)) | |
176 | ;;(if (and inplace (not fn) (not (eq (caar form) 'EXPAND))) | |
177 | ;; (insert " (append")) | |
178 | (bovine-grammar-expand-form | |
179 | first quotemode t) ;;(and fn (not (eq fn 'quote)))) | |
180 | ;;(if (and inplace (not fn) (not (eq (caar form) 'EXPAND))) | |
181 | ;; (insert ")")) | |
182 | ;;) | |
183 | ) | |
184 | ((symbolp first) | |
185 | (setq n (symbol-name first) ;the name | |
186 | q quotemode ;implied quote flag | |
187 | x nil) ;expand flag | |
188 | (if (eq (aref n 0) ?,) | |
189 | (if quotemode | |
190 | ;; backquote mode needs the @ | |
191 | (if (eq (aref n 1) ?@) | |
192 | (setq n (substring n 2) | |
193 | q nil | |
194 | x t) | |
195 | ;; non backquote mode behaves normally. | |
196 | (setq n (substring n 1) | |
197 | q nil)) | |
198 | (setq n (substring n 1) | |
199 | x t))) | |
200 | (if (string= n "") | |
201 | (progn | |
202 | ;; We expand only the next item in place (a list?) | |
203 | ;; A regular inline-list... | |
204 | (bovine-grammar-expand-form (car form) quotemode t) | |
205 | (setq form (cdr form))) | |
206 | (if (and (eq (aref n 0) ?$) | |
207 | ;; Don't expand $ tokens in implied quote mode. | |
208 | ;; This acts like quoting in other symbols. | |
209 | (not q)) | |
210 | (progn | |
211 | (cond | |
212 | ((and (not x) (not inlist) (not inplace)) | |
213 | (insert "\n(list")) | |
214 | ((and x inlist (not inplace)) | |
215 | (insert ")") | |
216 | (setq inlist nil))) | |
217 | (insert "\n(nth " (int-to-string | |
218 | (1- (string-to-number | |
219 | (substring n 1)))) | |
220 | " vals)") | |
221 | (and (not x) (not inplace) | |
222 | (setq inlist t))) | |
223 | ||
224 | (when (and (not inlist) (not inplace)) | |
225 | (insert "\n(list") | |
226 | (setq inlist t)) | |
227 | (or (char-equal (char-before) ?\() | |
228 | (insert " ")) | |
229 | (insert (if (or inplace (eq first t)) | |
230 | "" "'") | |
231 | n))) ;; " " | |
232 | ) | |
233 | (t | |
234 | (when (and (not inlist) (not inplace)) | |
235 | (insert "\n(list") | |
236 | (setq inlist t)) | |
237 | (insert (format "\n%S" first)) | |
238 | ) | |
239 | )) | |
240 | (if inlist (insert ")")) | |
241 | (if inplace (insert ")"))) | |
f79fbbc7 | 242 | )) |
469d2149 CY |
243 | |
244 | (defun bovine-grammar-expand-action (textform quotemode) | |
245 | "Expand semantic action string TEXTFORM into Lisp code. | |
246 | QUOTEMODE is the mode in which quoted symbols are slurred." | |
247 | (if (string= "" textform) | |
248 | nil | |
249 | (let ((sexp (read textform))) | |
469d2149 CY |
250 | ;; We converted the lambda string into a list. Now write it |
251 | ;; out as the bovine lambda expression, and do macro-like | |
252 | ;; conversion upon it. | |
253 | (insert "\n") | |
254 | (cond | |
255 | ((eq (car sexp) 'EXPAND) | |
256 | (insert ",(lambda (vals start end)") | |
257 | ;; The EXPAND macro definition is mandatory | |
258 | (bovine-grammar-expand-form | |
259 | (apply (cdr (assq 'EXPAND bovine--grammar-macros)) (cdr sexp)) | |
260 | quotemode t) | |
261 | ) | |
262 | ((and (listp (car sexp)) (eq (caar sexp) 'EVAL)) | |
263 | ;; The user wants to evaluate the following args. | |
264 | ;; Use a simpler expander | |
265 | ) | |
266 | (t | |
267 | (insert ",(semantic-lambda") | |
268 | (bovine-grammar-expand-form sexp quotemode) | |
269 | )) | |
270 | (insert ")\n"))) | |
271 | ) | |
272 | ||
273 | (defun bovine-grammar-parsetable-builder () | |
274 | "Return the parser table expression as a string value. | |
275 | The format of a bovine parser table is: | |
276 | ||
277 | ( ( NONTERMINAL-SYMBOL1 MATCH-LIST1 ) | |
278 | ( NONTERMINAL-SYMBOL2 MATCH-LIST2 ) | |
279 | ... | |
280 | ( NONTERMINAL-SYMBOLn MATCH-LISTn ) | |
281 | ||
282 | Where each NONTERMINAL-SYMBOL is an artificial symbol which can appear | |
283 | in any child state. As a starting place, one of the NONTERMINAL-SYMBOLS | |
284 | must be `bovine-toplevel'. | |
285 | ||
286 | A MATCH-LIST is a list of possible matches of the form: | |
287 | ||
288 | ( STATE-LIST1 | |
289 | STATE-LIST2 | |
290 | ... | |
291 | STATE-LISTN ) | |
292 | ||
293 | where STATE-LIST is of the form: | |
294 | ( TYPE1 [ \"VALUE1\" ] TYPE2 [ \"VALUE2\" ] ... LAMBDA ) | |
295 | ||
296 | where TYPE is one of the returned types of the token stream. | |
297 | VALUE is a value, or range of values to match against. For | |
298 | example, a SYMBOL might need to match \"foo\". Some TYPES will not | |
299 | have matching criteria. | |
300 | ||
99d99081 | 301 | LAMBDA is a lambda expression which is evalled with the text of the |
469d2149 CY |
302 | type when it is found. It is passed the list of all buffer text |
303 | elements found since the last lambda expression. It should return a | |
304 | semantic element (see below.) | |
305 | ||
306 | For consistency between languages, try to use common return values | |
307 | from your parser. Please reference the chapter \"Writing Parsers\" in | |
308 | the \"Language Support Developer's Guide -\" in the semantic texinfo | |
309 | manual." | |
310 | (let* ((start (semantic-grammar-start)) | |
311 | (scopestart (semantic-grammar-scopestart)) | |
312 | (quotemode (semantic-grammar-quotemode)) | |
313 | (tags (semantic-find-tags-by-class | |
314 | 'token (current-buffer))) | |
315 | (nterms (semantic-find-tags-by-class | |
316 | 'nonterminal (current-buffer))) | |
317 | ;; Setup the cache of macro definitions. | |
318 | (bovine--grammar-macros (semantic-grammar-macros)) | |
319 | nterm rules items item actn prec tag type regex) | |
320 | ||
321 | ;; Check some trivial things | |
322 | (cond | |
323 | ((null nterms) | |
324 | (error "Bad input grammar")) | |
325 | (start | |
326 | (if (cdr start) | |
327 | (message "Extra start symbols %S ignored" (cdr start))) | |
328 | (setq start (symbol-name (car start))) | |
329 | (unless (semantic-find-first-tag-by-name start nterms) | |
330 | (error "start symbol `%s' has no rule" start))) | |
331 | (t | |
332 | ;; Default to the first grammar rule. | |
333 | (setq start (semantic-tag-name (car nterms))))) | |
334 | (when scopestart | |
335 | (setq scopestart (symbol-name scopestart)) | |
336 | (unless (semantic-find-first-tag-by-name scopestart nterms) | |
337 | (error "scopestart symbol `%s' has no rule" scopestart))) | |
338 | ||
339 | ;; Generate the grammar Lisp form. | |
340 | (with-temp-buffer | |
341 | (erase-buffer) | |
342 | (insert "`(") | |
343 | ;; Insert the start/scopestart rules | |
344 | (insert "\n(bovine-toplevel \n(" | |
345 | start | |
346 | ")\n) ;; end bovine-toplevel\n") | |
347 | (when scopestart | |
348 | (insert "\n(bovine-inner-scope \n(" | |
349 | scopestart | |
350 | ")\n) ;; end bovine-inner-scope\n")) | |
351 | ;; Process each nonterminal | |
352 | (while nterms | |
353 | (setq nterm (car nterms) | |
354 | ;; We can't use the override form because the current buffer | |
355 | ;; is not the originator of the tag. | |
356 | rules (semantic-tag-components-semantic-grammar-mode nterm) | |
357 | nterm (semantic-tag-name nterm) | |
358 | nterms (cdr nterms)) | |
359 | (when (member nterm '("bovine-toplevel" "bovine-inner-scope")) | |
360 | (error "`%s' is a reserved internal name" nterm)) | |
361 | (insert "\n(" nterm) | |
469d2149 CY |
362 | ;; Process each rule |
363 | (while rules | |
364 | (setq items (semantic-tag-get-attribute (car rules) :value) | |
365 | prec (semantic-tag-get-attribute (car rules) :prec) | |
366 | actn (semantic-tag-get-attribute (car rules) :expr) | |
367 | rules (cdr rules)) | |
368 | ;; Process each item | |
369 | (insert "\n(") | |
370 | (if (null items) | |
371 | ;; EMPTY rule | |
372 | (insert ";;EMPTY" (if actn "" "\n")) | |
373 | ;; Expand items | |
374 | (while items | |
375 | (setq item (car items) | |
376 | items (cdr items)) | |
377 | (if (consp item) ;; mid-rule action | |
378 | (message "Mid-rule action %S ignored" item) | |
379 | (or (char-equal (char-before) ?\() | |
380 | (insert "\n")) | |
381 | (cond | |
382 | ((member item '("bovine-toplevel" "bovine-inner-scope")) | |
383 | (error "`%s' is a reserved internal name" item)) | |
384 | ;; Replace ITEM by its %token definition. | |
385 | ;; If a '%token TYPE ITEM [REGEX]' definition exists | |
386 | ;; in the grammar, ITEM is replaced by TYPE [REGEX]. | |
387 | ((setq tag (semantic-find-first-tag-by-name | |
388 | item tags) | |
389 | type (semantic-tag-get-attribute tag :type)) | |
390 | (insert type) | |
391 | (if (setq regex (semantic-tag-get-attribute tag :value)) | |
392 | (insert (format "\n%S" regex)))) | |
393 | ;; Don't change ITEM | |
394 | (t | |
395 | (insert (semantic-grammar-item-text item))) | |
396 | )))) | |
469d2149 CY |
397 | (if prec |
398 | (message "%%prec %S ignored" prec)) | |
399 | (if actn | |
400 | (bovine-grammar-expand-action actn quotemode)) | |
401 | (insert ")")) | |
402 | (insert "\n) ;; end " nterm "\n")) | |
403 | (insert ")\n") | |
404 | (buffer-string)))) | |
405 | ||
406 | (defun bovine-grammar-setupcode-builder () | |
407 | "Return the text of the setup code." | |
408 | (format | |
409 | "(setq semantic--parse-table %s\n\ | |
410 | semantic-debug-parser-source %S\n\ | |
411 | semantic-debug-parser-class 'semantic-bovine-debug-parser | |
412 | semantic-flex-keywords-obarray %s\n\ | |
413 | %s)" | |
414 | (semantic-grammar-parsetable) | |
415 | (buffer-name) | |
416 | (semantic-grammar-keywordtable) | |
417 | (let ((mode (semantic-grammar-languagemode))) | |
418 | ;; Is there more than one major mode? | |
419 | (if (and (listp mode) (> (length mode) 1)) | |
420 | (format "semantic-equivalent-major-modes '%S\n" mode) | |
421 | "")))) | |
422 | ||
423 | (defvar bovine-grammar-menu | |
424 | '("BY Grammar" | |
425 | ) | |
426 | "BY mode specific grammar menu. | |
427 | Menu items are appended to the common grammar menu.") | |
428 | ||
429 | (define-derived-mode bovine-grammar-mode semantic-grammar-mode "BY" | |
430 | "Major mode for editing Bovine grammars." | |
431 | (semantic-grammar-setup-menu bovine-grammar-menu) | |
432 | (semantic-install-function-overrides | |
433 | '((grammar-parsetable-builder . bovine-grammar-parsetable-builder) | |
434 | (grammar-setupcode-builder . bovine-grammar-setupcode-builder) | |
435 | ))) | |
436 | ||
509c74bd | 437 | (add-to-list 'auto-mode-alist '("\\.by\\'" . bovine-grammar-mode)) |
469d2149 CY |
438 | |
439 | (defvar-mode-local bovine-grammar-mode semantic-grammar-macros | |
440 | '( | |
441 | (ASSOC . semantic-grammar-ASSOC) | |
442 | (EXPAND . bovine-grammar-EXPAND) | |
443 | (EXPANDFULL . bovine-grammar-EXPANDFULL) | |
444 | (TAG . bovine-grammar-TAG) | |
445 | (VARIABLE-TAG . bovine-grammar-VARIABLE-TAG) | |
446 | (FUNCTION-TAG . bovine-grammar-FUNCTION-TAG) | |
447 | (TYPE-TAG . bovine-grammar-TYPE-TAG) | |
448 | (INCLUDE-TAG . bovine-grammar-INCLUDE-TAG) | |
449 | (PACKAGE-TAG . bovine-grammar-PACKAGE-TAG) | |
450 | (CODE-TAG . bovine-grammar-CODE-TAG) | |
451 | (ALIAS-TAG . bovine-grammar-ALIAS-TAG) | |
452 | ) | |
453 | "Semantic grammar macros used in bovine grammars.") | |
454 | ||
455 | (provide 'semantic/bovine/grammar) | |
456 | ||
78adbf9c CY |
457 | (defun bovine-make-parsers () |
458 | "Generate Emacs' built-in Bovine-based parser files." | |
459 | (semantic-mode 1) | |
460 | ;; Loop through each .by file in current directory, and run | |
461 | ;; `semantic-grammar-batch-build-one-package' to build the grammar. | |
509c74bd | 462 | (dolist (f (directory-files default-directory nil "\\.by\\'")) |
78adbf9c CY |
463 | (let ((packagename |
464 | (condition-case err | |
465 | (with-current-buffer (find-file-noselect f) | |
466 | (semantic-grammar-create-package)) | |
467 | (error (message "%s" (error-message-string err)) nil))) | |
468 | lang) | |
469 | (when (and packagename | |
509c74bd | 470 | (string-match "^semantic-\\(.*\\)-by\\.el\\'" packagename)) |
78adbf9c CY |
471 | (setq lang (match-string 1 packagename)) |
472 | (with-temp-buffer | |
473 | (insert-file-contents packagename) | |
474 | (setq buffer-file-name (expand-file-name packagename)) | |
475 | ;; Fix copyright header: | |
476 | (goto-char (point-min)) | |
477 | (re-search-forward "^;; Author:") | |
478 | (setq copyright-end (match-beginning 0)) | |
479 | (re-search-forward "^;;; Code:\n") | |
480 | (delete-region copyright-end (match-end 0)) | |
481 | (goto-char copyright-end) | |
482 | (insert ";; This file is part of GNU Emacs. | |
483 | ||
484 | ;; GNU Emacs is free software: you can redistribute it and/or modify | |
485 | ;; it under the terms of the GNU General Public License as published by | |
486 | ;; the Free Software Foundation, either version 3 of the License, or | |
487 | ;; (at your option) any later version. | |
488 | ||
489 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
490 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
491 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
492 | ;; GNU General Public License for more details. | |
493 | ||
494 | ;; You should have received a copy of the GNU General Public License | |
495 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |
496 | ||
497 | ;;; Commentary: | |
498 | ;; | |
499 | ;; This file was generated from admin/grammars/" | |
500 | lang ".by. | |
501 | ||
502 | ;;; Code: | |
503 | ||
504 | \(require 'semantic/lex) | |
505 | \(eval-when-compile (require 'semantic/bovine))\n") | |
506 | (goto-char (point-min)) | |
507 | (delete-region (point-min) (line-end-position)) | |
508 | (insert ";;; semantic/bovine/" lang | |
509 | "-by.el --- Generated parser support file") | |
510 | (delete-trailing-whitespace) | |
511 | ;; Fix footer: | |
512 | (goto-char (point-max)) | |
513 | (re-search-backward ".\n;;; Analyzers") | |
514 | (delete-region (point) (point-max)) | |
515 | (insert "(provide 'semantic/bovine/" lang "-by)\n\n") | |
516 | (insert ";;; semantic/bovine/" lang "-by.el ends here\n") | |
517 | (save-buffer)))))) | |
518 | ||
62f43d66 | 519 | ;;; bovine-grammar.el ends here |