Mercurial > emacs
annotate lisp/progmodes/ebnf-yac.el @ 95003:3a511cbd02ec
Fix previous.
author | Glenn Morris <rgm@gnu.org> |
---|---|
date | Thu, 15 May 2008 06:52:20 +0000 |
parents | 52b7a8c22af5 |
children | a9dc0e7c3f2b |
rev | line source |
---|---|
38436
b174db545cfd
Some fixes to follow coding conventions.
Pavel Janík <Pavel@Janik.cz>
parents:
34807
diff
changeset
|
1 ;;; ebnf-yac.el --- parser for Yacc/Bison |
27451 | 2 |
79717 | 3 ;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 |
75347 | 4 ;; Free Software Foundation, Inc. |
27451 | 5 |
54140
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
6 ;; Author: Vinicius Jose Latorre <viniciusjl@ig.com.br> |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
7 ;; Maintainer: Vinicius Jose Latorre <viniciusjl@ig.com.br> |
39344 | 8 ;; Keywords: wp, ebnf, PostScript |
82143
81c81019e0c6
New: Header/Footer comment & Log messages
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
78234
diff
changeset
|
9 ;; Version: 1.4 |
27451 | 10 |
27539 | 11 ;; This file is part of GNU Emacs. |
27451 | 12 |
94673
52b7a8c22af5
Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents:
93975
diff
changeset
|
13 ;; GNU Emacs is free software: you can redistribute it and/or modify |
27451 | 14 ;; it under the terms of the GNU General Public License as published by |
94673
52b7a8c22af5
Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents:
93975
diff
changeset
|
15 ;; the Free Software Foundation, either version 3 of the License, or |
52b7a8c22af5
Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents:
93975
diff
changeset
|
16 ;; (at your option) any later version. |
27451 | 17 |
27539 | 18 ;; GNU Emacs is distributed in the hope that it will be useful, |
27451 | 19 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21 ;; GNU General Public License for more details. | |
22 | |
23 ;; You should have received a copy of the GNU General Public License | |
94673
52b7a8c22af5
Switch to recommended form of GPLv3 permissions notice.
Glenn Morris <rgm@gnu.org>
parents:
93975
diff
changeset
|
24 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. |
27451 | 25 |
26 ;;; Commentary: | |
27 | |
28 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
29 ;; | |
30 ;; | |
31 ;; This is part of ebnf2ps package. | |
32 ;; | |
33 ;; This package defines a parser for Yacc/Bison. | |
34 ;; | |
35 ;; See ebnf2ps.el for documentation. | |
36 ;; | |
37 ;; | |
38 ;; Yacc/Bison Syntax | |
39 ;; ----------------- | |
40 ;; | |
41 ;; YACC = { YACC-Definitions }* "%%" { YACC-Rule }* [ "%%" [ YACC-Code ] ]. | |
42 ;; | |
54140
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
43 ;; YACC-Definitions = ( "%token" | "%left" | "%right" | "%nonassoc" ) |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
44 ;; [ "<" Name ">" ] Name-List |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
45 ;; | "%prec" Name |
27451 | 46 ;; | "any other Yacc definition" |
47 ;; . | |
48 ;; | |
49 ;; YACC-Code = "any C definition". | |
50 ;; | |
51 ;; YACC-Rule = Name ":" Alternative ";". | |
52 ;; | |
53 ;; Alternative = { Sequence || "|" }*. | |
54 ;; | |
55 ;; Sequence = { Factor }*. | |
56 ;; | |
57 ;; Factor = Name | |
58 ;; | "'" "character" "'" | |
59 ;; | "error" | |
60 ;; | "{" "C like commands" "}" | |
61 ;; . | |
62 ;; | |
63 ;; Name-List = { Name || "," }*. | |
64 ;; | |
65 ;; Name = "[A-Za-z][A-Za-z0-9_.]*". | |
66 ;; | |
67 ;; Comment = "/*" "any character, but the sequence \"*/\"" "*/" | |
54208 | 68 ;; | "//" "any character, but the newline \"\\n\"" "\\n". |
27451 | 69 ;; |
70 ;; | |
54140
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
71 ;; In other words, a valid Name begins with a letter (upper or lower case) |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
72 ;; followed by letters, decimal digits, underscore (_) or point (.). For |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
73 ;; example: this_is_a_valid.name, Another_EXAMPLE, mIxEd.CaSe. |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
74 ;; |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
75 ;; |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
76 ;; Acknowledgements |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
77 ;; ---------------- |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
78 ;; |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
79 ;; Thanks to Matthew K. Junker <junker@alum.mit.edu> for the suggestion to deal |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
80 ;; with %right, %left and %prec pragmas. His suggestion was extended to deal |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
81 ;; with %nonassoc pragma too. |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
82 ;; |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
83 ;; |
27451 | 84 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
85 | |
38436
b174db545cfd
Some fixes to follow coding conventions.
Pavel Janík <Pavel@Janik.cz>
parents:
34807
diff
changeset
|
86 ;;; Code: |
27451 | 87 |
88 | |
89 (require 'ebnf-otz) | |
90 | |
91 | |
92 (defvar ebnf-yac-lex nil | |
93 "Value returned by `ebnf-yac-lex' function.") | |
94 | |
95 | |
96 (defvar ebnf-yac-token-list nil | |
97 "List of `%TOKEN' names.") | |
98 | |
99 | |
100 (defvar ebnf-yac-skip-char nil | |
101 "Non-nil means skip printable characters with no grammatical meaning.") | |
102 | |
103 | |
104 (defvar ebnf-yac-error nil | |
46275
0d5f7cc6ce91
(ebnf-yac-error): Fix typo.
Juanma Barranquero <lekktu@gmail.com>
parents:
39424
diff
changeset
|
105 "Non-nil means \"error\" occurred.") |
27451 | 106 |
107 | |
108 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
49670
cc820064216c
Fix typo in comment.
Juanma Barranquero <lekktu@gmail.com>
parents:
46275
diff
changeset
|
109 ;; Syntactic analyzer |
27451 | 110 |
111 | |
112 ;;; YACC = { YACC-Definitions }* "%%" { YACC-Rule }* [ "%%" [ YACC-Code ] ]. | |
113 ;;; | |
114 ;;; YACC-Code = "any C definition". | |
115 | |
116 (defun ebnf-yac-parser (start) | |
117 "yacc/Bison parser." | |
118 (let ((total (+ (- ebnf-limit start) 1)) | |
119 (bias (1- start)) | |
120 (origin (point)) | |
121 syntax-list token rule) | |
122 (goto-char start) | |
123 (setq token (ebnf-yac-lex)) | |
124 (and (eq token 'end-of-input) | |
38436
b174db545cfd
Some fixes to follow coding conventions.
Pavel Janík <Pavel@Janik.cz>
parents:
34807
diff
changeset
|
125 (error "Invalid Yacc/Bison file format")) |
27451 | 126 (or (eq (ebnf-yac-definitions token) 'yac-separator) |
38436
b174db545cfd
Some fixes to follow coding conventions.
Pavel Janík <Pavel@Janik.cz>
parents:
34807
diff
changeset
|
127 (error "Missing `%%%%'")) |
27451 | 128 (setq token (ebnf-yac-lex)) |
129 (while (not (memq token '(end-of-input yac-separator))) | |
130 (ebnf-message-float | |
131 "Parsing...%s%%" | |
132 (/ (* (- (point) bias) 100.0) total)) | |
133 (setq token (ebnf-yac-rule token) | |
134 rule (cdr token) | |
135 token (car token)) | |
136 (or (ebnf-add-empty-rule-list rule) | |
137 (setq syntax-list (cons rule syntax-list)))) | |
138 (goto-char origin) | |
139 syntax-list)) | |
140 | |
141 | |
54140
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
142 ;;; YACC-Definitions = ( "%token" | "%left" | "%right" | "%nonassoc" ) |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
143 ;;; [ "<" Name ">" ] Name-List |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
144 ;;; | "%prec" Name |
27451 | 145 ;;; | "any other Yacc definition" |
146 ;;; . | |
147 | |
148 (defun ebnf-yac-definitions (token) | |
149 (let ((ebnf-yac-skip-char t)) | |
150 (while (not (memq token '(yac-separator end-of-input))) | |
151 (setq token | |
152 (cond | |
54140
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
153 ;; ( "%token" | "%left" | "%right" | "%nonassoc" ) |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
154 ;; [ "<" Name ">" ] Name-List |
27451 | 155 ((eq token 'yac-token) |
156 (setq token (ebnf-yac-lex)) | |
157 (when (eq token 'open-angle) | |
158 (or (eq (ebnf-yac-lex) 'non-terminal) | |
38436
b174db545cfd
Some fixes to follow coding conventions.
Pavel Janík <Pavel@Janik.cz>
parents:
34807
diff
changeset
|
159 (error "Missing type name")) |
27451 | 160 (or (eq (ebnf-yac-lex) 'close-angle) |
38436
b174db545cfd
Some fixes to follow coding conventions.
Pavel Janík <Pavel@Janik.cz>
parents:
34807
diff
changeset
|
161 (error "Missing `>'")) |
27451 | 162 (setq token (ebnf-yac-lex))) |
163 (setq token (ebnf-yac-name-list token) | |
164 ebnf-yac-token-list (nconc (cdr token) | |
165 ebnf-yac-token-list)) | |
166 (car token)) | |
54140
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
167 ;; "%prec" Name |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
168 ((eq token 'yac-prec) |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
169 (or (eq (ebnf-yac-lex) 'non-terminal) |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
170 (error "Missing prec name")) |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
171 (ebnf-yac-lex)) |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
172 ;; "any other Yacc definition" |
27451 | 173 (t |
174 (ebnf-yac-lex)) | |
175 ))) | |
176 token)) | |
177 | |
178 | |
179 ;;; YACC-Rule = Name ":" Alternative ";". | |
180 | |
181 (defun ebnf-yac-rule (token) | |
182 (let ((header ebnf-yac-lex) | |
183 (action ebnf-action) | |
184 body) | |
185 (setq ebnf-action nil) | |
186 (or (eq token 'non-terminal) | |
38436
b174db545cfd
Some fixes to follow coding conventions.
Pavel Janík <Pavel@Janik.cz>
parents:
34807
diff
changeset
|
187 (error "Invalid rule name")) |
27451 | 188 (or (eq (ebnf-yac-lex) 'colon) |
38436
b174db545cfd
Some fixes to follow coding conventions.
Pavel Janík <Pavel@Janik.cz>
parents:
34807
diff
changeset
|
189 (error "Invalid rule: missing `:'")) |
27451 | 190 (setq body (ebnf-yac-alternative)) |
191 (or (eq (car body) 'period) | |
38436
b174db545cfd
Some fixes to follow coding conventions.
Pavel Janík <Pavel@Janik.cz>
parents:
34807
diff
changeset
|
192 (error "Invalid rule: missing `;'")) |
27451 | 193 (setq body (cdr body)) |
194 (ebnf-eps-add-production header) | |
195 (cons (ebnf-yac-lex) | |
196 (ebnf-make-production header body action)))) | |
197 | |
198 | |
199 ;;; Alternative = { Sequence || "|" }*. | |
200 | |
201 (defun ebnf-yac-alternative () | |
202 (let (body sequence) | |
203 (while (eq (car (setq sequence (ebnf-yac-sequence))) | |
204 'alternative) | |
205 (and (setq sequence (cdr sequence)) | |
206 (setq body (cons sequence body)))) | |
207 (ebnf-token-alternative body sequence))) | |
208 | |
209 | |
210 ;;; Sequence = { Factor }*. | |
211 | |
212 (defun ebnf-yac-sequence () | |
213 (let (ebnf-yac-error token seq factor) | |
214 (while (setq token (ebnf-yac-lex) | |
215 factor (ebnf-yac-factor token)) | |
216 (setq seq (cons factor seq))) | |
217 (cons token | |
54714 | 218 (if (and ebnf-yac-ignore-error-recovery ebnf-yac-error) |
219 ;; ignore error recovery | |
220 nil | |
221 (ebnf-token-sequence seq))))) | |
27451 | 222 |
223 | |
224 ;;; Factor = Name | |
225 ;;; | "'" "character" "'" | |
226 ;;; | "error" | |
227 ;;; | "{" "C like commands" "}" | |
228 ;;; . | |
229 | |
230 (defun ebnf-yac-factor (token) | |
231 (cond | |
232 ;; 'character' | |
233 ((eq token 'terminal) | |
234 (ebnf-make-terminal ebnf-yac-lex)) | |
235 ;; Name | |
236 ((eq token 'non-terminal) | |
237 (ebnf-make-non-terminal ebnf-yac-lex)) | |
238 ;; "error" | |
239 ((eq token 'yac-error) | |
240 (ebnf-make-special ebnf-yac-lex)) | |
241 ;; not a factor | |
242 (t | |
243 nil) | |
244 )) | |
245 | |
246 | |
247 ;;; Name-List = { Name || "," }*. | |
248 | |
249 (defun ebnf-yac-name-list (token) | |
250 (let (names) | |
251 (when (eq token 'non-terminal) | |
252 (while (progn | |
253 (setq names (cons ebnf-yac-lex names) | |
254 token (ebnf-yac-lex)) | |
255 (eq token 'comma)) | |
256 (or (eq (ebnf-yac-lex) 'non-terminal) | |
38436
b174db545cfd
Some fixes to follow coding conventions.
Pavel Janík <Pavel@Janik.cz>
parents:
34807
diff
changeset
|
257 (error "Missing token name")))) |
27451 | 258 (cons token names))) |
259 | |
260 | |
261 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
262 ;; Lexical analyzer | |
263 | |
264 | |
265 ;;; Name = "[A-Za-z][A-Za-z0-9_.]*". | |
266 ;;; | |
267 ;;; Comment = "/*" "any character, but the sequence \"*/\"" "*/" | |
268 ;;; | "//" "any character" "\\n". | |
269 | |
270 (defconst ebnf-yac-token-table | |
271 ;; control character & 8-bit character are set to `error' | |
272 (let ((table (make-vector 256 'error))) | |
273 ;; upper & lower case letters: | |
85222
12b40810304b
(ebnf-yac-token-table): Use mapc rather than mapcar.
Glenn Morris <rgm@gnu.org>
parents:
82143
diff
changeset
|
274 (mapc |
27451 | 275 #'(lambda (char) |
276 (aset table char 'non-terminal)) | |
277 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz") | |
278 ;; printable characters: | |
85222
12b40810304b
(ebnf-yac-token-table): Use mapc rather than mapcar.
Glenn Morris <rgm@gnu.org>
parents:
82143
diff
changeset
|
279 (mapc |
27451 | 280 #'(lambda (char) |
281 (aset table char 'character)) | |
282 "!#$&()*+-.0123456789=?@[\\]^_`~") | |
283 ;; Override space characters: | |
284 (aset table ?\n 'space) ; [NL] linefeed | |
285 (aset table ?\r 'space) ; [CR] carriage return | |
286 (aset table ?\t 'space) ; [HT] horizontal tab | |
287 (aset table ?\ 'space) ; [SP] space | |
288 ;; Override form feed character: | |
289 (aset table ?\f 'form-feed) ; [FF] form feed | |
290 ;; Override other lexical characters: | |
291 (aset table ?< 'open-angle) | |
292 (aset table ?> 'close-angle) | |
293 (aset table ?, 'comma) | |
294 (aset table ?% 'yac-pragma) | |
295 (aset table ?/ 'slash) | |
296 (aset table ?\{ 'yac-code) | |
297 (aset table ?\" 'string) | |
298 (aset table ?\' 'terminal) | |
299 (aset table ?: 'colon) | |
300 (aset table ?| 'alternative) | |
301 (aset table ?\; 'period) | |
302 table) | |
303 "Vector used to map characters to a lexical token.") | |
304 | |
305 | |
306 (defun ebnf-yac-initialize () | |
307 "Initializations for Yacc/Bison parser." | |
308 (setq ebnf-yac-token-list nil)) | |
309 | |
310 | |
311 (defun ebnf-yac-lex () | |
63632
174466935578
(ebnf-yac-lex): Fix spellings.
Juanma Barranquero <lekktu@gmail.com>
parents:
60917
diff
changeset
|
312 "Lexical analyzer for Yacc/Bison. |
27451 | 313 |
314 Return a lexical token. | |
315 | |
316 See documentation for variable `ebnf-yac-lex'." | |
317 (if (>= (point) ebnf-limit) | |
318 'end-of-input | |
319 (let (token) | |
320 ;; skip spaces, code blocks and comments | |
321 (while (if (> (following-char) 255) | |
322 (progn | |
323 (setq token 'error) | |
324 nil) | |
325 (setq token (aref ebnf-yac-token-table (following-char))) | |
326 (cond | |
327 ((or (eq token 'space) | |
328 (and ebnf-yac-skip-char | |
329 (eq token 'character))) | |
330 (ebnf-yac-skip-spaces)) | |
331 ((eq token 'yac-code) | |
332 (ebnf-yac-skip-code)) | |
333 ((eq token 'slash) | |
334 (ebnf-yac-handle-comment)) | |
335 ((eq token 'form-feed) | |
336 (forward-char) | |
337 (setq ebnf-action 'form-feed)) | |
338 (t nil) | |
339 ))) | |
340 (cond | |
341 ;; end of input | |
342 ((>= (point) ebnf-limit) | |
343 'end-of-input) | |
344 ;; error | |
345 ((eq token 'error) | |
60917
87f9bb9d3718
* progmodes/ebnf-abn.el, progmodes/ebnf-bnf.el,
Werner LEMBERG <wl@gnu.org>
parents:
54714
diff
changeset
|
346 (error "Invalid character")) |
27451 | 347 ;; "string" |
348 ((eq token 'string) | |
349 (setq ebnf-yac-lex (ebnf-get-string)) | |
350 'string) | |
351 ;; terminal: 'char' | |
352 ((eq token 'terminal) | |
353 (setq ebnf-yac-lex (ebnf-string " -&(-~" ?\' "terminal")) | |
354 'terminal) | |
355 ;; non-terminal, terminal or "error" | |
356 ((eq token 'non-terminal) | |
357 (setq ebnf-yac-lex (ebnf-buffer-substring "0-9A-Za-z_.")) | |
358 (cond ((member ebnf-yac-lex ebnf-yac-token-list) | |
359 'terminal) | |
360 ((string= ebnf-yac-lex "error") | |
361 (setq ebnf-yac-error t) | |
362 'yac-error) | |
363 (t | |
364 'non-terminal) | |
365 )) | |
366 ;; %% and Yacc pragmas (%TOKEN, %START, etc). | |
367 ((eq token 'yac-pragma) | |
368 (forward-char) | |
369 (cond | |
370 ;; Yacc separator | |
371 ((eq (following-char) ?%) | |
372 (forward-char) | |
373 'yac-separator) | |
54140
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
374 ;; %TOKEN, %RIGHT, %LEFT, %PREC, %NONASSOC |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
375 ((cdr (assoc (upcase (ebnf-buffer-substring "0-9A-Za-z_")) |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
376 '(("TOKEN" . yac-token) |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
377 ("RIGHT" . yac-token) |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
378 ("LEFT" . yac-token) |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
379 ("NONASSOC" . yac-token) |
766aaa5bded5
ABNF parser. Fix bug on productions like test = {"test"}* | ("tt" ["test"]). Reported by Markus Dreyer.
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
52401
diff
changeset
|
380 ("PREC" . yac-prec))))) |
27451 | 381 ;; other Yacc pragmas |
382 (t | |
383 'yac-pragma) | |
384 )) | |
385 ;; miscellaneous | |
386 (t | |
387 (forward-char) | |
388 token) | |
389 )))) | |
390 | |
391 | |
392 (defun ebnf-yac-skip-spaces () | |
393 (skip-chars-forward | |
394 (if ebnf-yac-skip-char | |
395 "\n\r\t !#$&()*+-.0123456789=?@[\\\\]^_`~" | |
396 "\n\r\t ") | |
397 ebnf-limit) | |
398 (< (point) ebnf-limit)) | |
399 | |
400 | |
39424
b7142e063fee
Fix character range regexp. Doc fix.
Gerd Moellmann <gerd@gnu.org>
parents:
39344
diff
changeset
|
401 ;; replace the range "\177-\377" (see `ebnf-range-regexp'). |
b7142e063fee
Fix character range regexp. Doc fix.
Gerd Moellmann <gerd@gnu.org>
parents:
39344
diff
changeset
|
402 (defconst ebnf-yac-skip-chars |
b7142e063fee
Fix character range regexp. Doc fix.
Gerd Moellmann <gerd@gnu.org>
parents:
39344
diff
changeset
|
403 (ebnf-range-regexp "^{}/'\"\000-\010\013\016-\037" ?\177 ?\377)) |
b7142e063fee
Fix character range regexp. Doc fix.
Gerd Moellmann <gerd@gnu.org>
parents:
39344
diff
changeset
|
404 |
b7142e063fee
Fix character range regexp. Doc fix.
Gerd Moellmann <gerd@gnu.org>
parents:
39344
diff
changeset
|
405 |
27451 | 406 (defun ebnf-yac-skip-code () |
407 (forward-char) | |
408 (let ((pair 1)) | |
409 (while (> pair 0) | |
39424
b7142e063fee
Fix character range regexp. Doc fix.
Gerd Moellmann <gerd@gnu.org>
parents:
39344
diff
changeset
|
410 (skip-chars-forward ebnf-yac-skip-chars ebnf-limit) |
27451 | 411 (cond |
412 ((= (following-char) ?{) | |
413 (forward-char) | |
414 (setq pair (1+ pair))) | |
415 ((= (following-char) ?}) | |
416 (forward-char) | |
417 (setq pair (1- pair))) | |
418 ((= (following-char) ?/) | |
419 (ebnf-yac-handle-comment)) | |
420 ((= (following-char) ?\") | |
421 (ebnf-get-string)) | |
422 ((= (following-char) ?\') | |
423 (ebnf-string " -&(-~" ?\' "character")) | |
424 (t | |
60917
87f9bb9d3718
* progmodes/ebnf-abn.el, progmodes/ebnf-bnf.el,
Werner LEMBERG <wl@gnu.org>
parents:
54714
diff
changeset
|
425 (error "Invalid character")) |
27451 | 426 ))) |
427 (ebnf-yac-skip-spaces)) | |
428 | |
429 | |
430 (defun ebnf-yac-handle-comment () | |
431 (forward-char) | |
432 (cond | |
433 ;; begin comment | |
434 ((= (following-char) ?*) | |
435 (ebnf-yac-skip-comment) | |
436 (ebnf-yac-skip-spaces)) | |
437 ;; line comment | |
438 ((= (following-char) ?/) | |
439 (end-of-line) | |
440 (ebnf-yac-skip-spaces)) | |
441 ;; no comment | |
442 (t nil) | |
443 )) | |
444 | |
445 | |
34807
05c7152c7aeb
Fix the same problem as described on ebnf2ps.el log
Gerd Moellmann <gerd@gnu.org>
parents:
27539
diff
changeset
|
446 ;; replace the range "\177-\237" (see `ebnf-range-regexp'). |
05c7152c7aeb
Fix the same problem as described on ebnf2ps.el log
Gerd Moellmann <gerd@gnu.org>
parents:
27539
diff
changeset
|
447 (defconst ebnf-yac-comment-chars |
05c7152c7aeb
Fix the same problem as described on ebnf2ps.el log
Gerd Moellmann <gerd@gnu.org>
parents:
27539
diff
changeset
|
448 (ebnf-range-regexp "^*\000-\010\013\016-\037" ?\177 ?\237)) |
27451 | 449 |
450 | |
451 (defun ebnf-yac-skip-comment () | |
452 (forward-char) | |
453 (cond | |
454 ;; open EPS file | |
455 ((and ebnf-eps-executing (= (following-char) ?\[)) | |
456 (ebnf-eps-add-context (ebnf-yac-eps-filename))) | |
457 ;; close EPS file | |
458 ((and ebnf-eps-executing (= (following-char) ?\])) | |
459 (ebnf-eps-remove-context (ebnf-yac-eps-filename))) | |
82143
81c81019e0c6
New: Header/Footer comment & Log messages
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
78234
diff
changeset
|
460 ;; EPS header |
81c81019e0c6
New: Header/Footer comment & Log messages
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
78234
diff
changeset
|
461 ((and ebnf-eps-executing (= (following-char) ?H)) |
81c81019e0c6
New: Header/Footer comment & Log messages
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
78234
diff
changeset
|
462 (ebnf-eps-header-comment (ebnf-yac-eps-filename))) |
81c81019e0c6
New: Header/Footer comment & Log messages
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
78234
diff
changeset
|
463 ;; EPS footer |
81c81019e0c6
New: Header/Footer comment & Log messages
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
78234
diff
changeset
|
464 ((and ebnf-eps-executing (= (following-char) ?F)) |
81c81019e0c6
New: Header/Footer comment & Log messages
Vinicius Jose Latorre <viniciusjl@ig.com.br>
parents:
78234
diff
changeset
|
465 (ebnf-eps-footer-comment (ebnf-yac-eps-filename))) |
27451 | 466 ;; any other action in comment |
467 (t | |
468 (setq ebnf-action (aref ebnf-comment-table (following-char)))) | |
469 ) | |
470 (let ((not-end t)) | |
471 (while not-end | |
472 (skip-chars-forward ebnf-yac-comment-chars ebnf-limit) | |
473 (cond ((>= (point) ebnf-limit) | |
38436
b174db545cfd
Some fixes to follow coding conventions.
Pavel Janík <Pavel@Janik.cz>
parents:
34807
diff
changeset
|
474 (error "Missing end of comment: `*/'")) |
27451 | 475 ((= (following-char) ?*) |
476 (skip-chars-forward "*" ebnf-limit) | |
477 (when (= (following-char) ?/) | |
478 ;; end of comment | |
479 (forward-char) | |
480 (setq not-end nil))) | |
481 (t | |
60917
87f9bb9d3718
* progmodes/ebnf-abn.el, progmodes/ebnf-bnf.el,
Werner LEMBERG <wl@gnu.org>
parents:
54714
diff
changeset
|
482 (error "Invalid character")) |
27451 | 483 )))) |
484 | |
485 | |
486 (defun ebnf-yac-eps-filename () | |
487 (forward-char) | |
488 (buffer-substring-no-properties | |
489 (point) | |
490 (let ((chars (concat ebnf-yac-comment-chars "\n")) | |
491 found) | |
492 (while (not found) | |
493 (skip-chars-forward chars ebnf-limit) | |
494 (setq found | |
495 (cond ((>= (point) ebnf-limit) | |
496 (point)) | |
497 ((= (following-char) ?*) | |
498 (skip-chars-forward "*" ebnf-limit) | |
499 (if (/= (following-char) ?\/) | |
500 nil | |
501 (backward-char) | |
502 (point))) | |
503 (t | |
504 (point)) | |
505 ))) | |
506 found))) | |
507 | |
508 | |
509 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
510 | |
511 | |
512 (provide 'ebnf-yac) | |
513 | |
514 | |
93975
1e3a407766b9
Fix up comment convention on the arch-tag lines.
Stefan Monnier <monnier@iro.umontreal.ca>
parents:
87649
diff
changeset
|
515 ;; arch-tag: 8a96989c-0b1d-42ba-a020-b2901f9a2a4d |
27451 | 516 ;;; ebnf-yac.el ends here |