Commit | Line | Data |
---|---|---|
78adbf9c CY |
1 | ;;; semantic-grammar.wy -- LALR grammar of Semantic input grammars |
2 | ;; | |
ab422c4d | 3 | ;; Copyright (C) 2002-2013 Free Software Foundation, Inc. |
78adbf9c 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 | ;; X-RCS: $Id: semantic-grammar.wy,v 1.16 2005/09/30 20:20:27 zappo Exp $ | |
10 | ||
11 | ;; This file is part of GNU Emacs. | |
12 | ||
13 | ;; GNU Emacs is free software: you can redistribute it and/or modify | |
14 | ;; it under the terms of the GNU General Public License as published by | |
15 | ;; the Free Software Foundation, either version 3 of the License, or | |
16 | ;; (at your option) any later version. | |
17 | ||
18 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
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 | |
24 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |
25 | ||
62a81506 CY |
26 | %package semantic-grammar-wy |
27 | %provide semantic/grammar-wy | |
28 | ||
78adbf9c CY |
29 | %{ |
30 | (defvar semantic-grammar-lex-c-char-re) | |
31 | ||
32 | ;; Current parsed nonterminal name. | |
33 | (defvar semantic-grammar-wy--nterm nil) | |
34 | ;; Index of rule in a nonterminal clause. | |
35 | (defvar semantic-grammar-wy--rindx nil) | |
36 | } | |
37 | ||
78adbf9c CY |
38 | %languagemode wy-mode |
39 | ||
40 | ;; Main | |
41 | %start grammar | |
42 | ;; Reparse | |
43 | %start prologue epilogue declaration nonterminal rule | |
44 | ;; EXPANDFULL | |
45 | %start put_names put_values use_names | |
46 | ||
47 | ;; Keywords | |
48 | %type <keyword> | |
49 | %keyword DEFAULT-PREC "%default-prec" | |
50 | %keyword NO-DEFAULT-PREC "%no-default-prec" | |
51 | %keyword KEYWORD "%keyword" | |
52 | %keyword LANGUAGEMODE "%languagemode" | |
53 | %keyword LEFT "%left" | |
54 | %keyword NONASSOC "%nonassoc" | |
55 | %keyword PACKAGE "%package" | |
62a81506 | 56 | %keyword PROVIDE "%provide" |
78adbf9c CY |
57 | %keyword PREC "%prec" |
58 | %keyword PUT "%put" | |
59 | %keyword QUOTEMODE "%quotemode" | |
60 | %keyword RIGHT "%right" | |
61 | %keyword SCOPESTART "%scopestart" | |
62 | %keyword START "%start" | |
63 | %keyword TOKEN "%token" | |
64 | %keyword TYPE "%type" | |
65 | %keyword USE-MACROS "%use-macros" | |
66 | ||
67 | ;; Literals | |
68 | %type <string> | |
69 | %token <string> STRING | |
70 | ||
71 | %type <symbol> syntax ":?\\(\\sw\\|\\s_\\)+" | |
72 | %token <symbol> SYMBOL | |
73 | %token <symbol> PERCENT_PERCENT "\\`%%\\'" | |
74 | ||
75 | %type <char> syntax semantic-grammar-lex-c-char-re | |
76 | %token <char> CHARACTER | |
77 | ||
78 | %type <qlist> matchdatatype sexp syntax "\\s'\\s-*(" | |
79 | %token <qlist> PREFIXED_LIST | |
80 | ||
81 | %type <sexp> matchdatatype sexp syntax "\\=" | |
82 | %token <sexp> SEXP | |
83 | ||
84 | ;; Don't generate these analyzers which needs special handling code. | |
85 | %token <code> PROLOGUE "%{...%}" | |
86 | %token <code> EPILOGUE "%%...EOF" | |
87 | ||
88 | ;; Blocks & Parenthesis | |
89 | %type <block> | |
90 | %token <block> PAREN_BLOCK "(LPAREN RPAREN)" | |
91 | %token <block> BRACE_BLOCK "(LBRACE RBRACE)" | |
92 | %token <open-paren> LPAREN "(" | |
93 | %token <close-paren> RPAREN ")" | |
94 | %token <open-paren> LBRACE "{" | |
95 | %token <close-paren> RBRACE "}" | |
96 | ||
97 | ;; Punctuations | |
98 | %type <punctuation> | |
99 | %token <punctuation> COLON ":" | |
100 | %token <punctuation> SEMI ";" | |
101 | %token <punctuation> OR "|" | |
102 | %token <punctuation> LT "<" | |
103 | %token <punctuation> GT ">" | |
104 | ||
105 | %% | |
106 | ||
107 | grammar: | |
108 | prologue | |
109 | | epilogue | |
110 | | declaration | |
111 | | nonterminal | |
112 | | PERCENT_PERCENT | |
113 | ; | |
114 | ||
115 | ;;; Prologue/Epilogue | |
116 | ;; | |
117 | prologue: | |
118 | PROLOGUE | |
119 | (CODE-TAG "prologue" nil) | |
120 | ; | |
121 | ||
122 | epilogue: | |
123 | EPILOGUE | |
124 | (CODE-TAG "epilogue" nil) | |
125 | ; | |
126 | ||
127 | ;;; Declarations | |
128 | ;; | |
129 | declaration: | |
130 | decl | |
131 | (eval $1) | |
132 | ; | |
133 | ||
134 | decl: | |
135 | default_prec_decl | |
136 | | no_default_prec_decl | |
137 | | languagemode_decl | |
138 | | package_decl | |
62a81506 | 139 | | provide_decl |
78adbf9c CY |
140 | | precedence_decl |
141 | | put_decl | |
142 | | quotemode_decl | |
143 | | scopestart_decl | |
144 | | start_decl | |
145 | | keyword_decl | |
146 | | token_decl | |
147 | | type_decl | |
148 | | use_macros_decl | |
149 | ; | |
150 | ||
151 | default_prec_decl: | |
152 | DEFAULT-PREC | |
153 | `(TAG "default-prec" 'assoc :value '("t")) | |
154 | ; | |
155 | ||
156 | no_default_prec_decl: | |
157 | NO-DEFAULT-PREC | |
158 | `(TAG "default-prec" 'assoc :value '("nil")) | |
159 | ; | |
160 | ||
161 | languagemode_decl: | |
162 | LANGUAGEMODE symbols | |
163 | `(TAG ',(car $2) 'languagemode :rest ',(cdr $2)) | |
164 | ; | |
165 | ||
166 | package_decl: | |
167 | PACKAGE SYMBOL | |
168 | `(PACKAGE-TAG ',$2 nil) | |
169 | ; | |
170 | ||
62a81506 CY |
171 | provide_decl: |
172 | PROVIDE SYMBOL | |
173 | `(TAG ',$2 'provide) | |
174 | ; | |
175 | ||
78adbf9c CY |
176 | precedence_decl: |
177 | associativity token_type_opt items | |
178 | `(TAG ',$1 'assoc :type ',$2 :value ',$3) | |
179 | ; | |
180 | ||
181 | associativity: | |
182 | LEFT | |
183 | (progn "left") | |
184 | | RIGHT | |
185 | (progn "right") | |
186 | | NONASSOC | |
187 | (progn "nonassoc") | |
188 | ; | |
189 | ||
190 | put_decl: | |
191 | PUT put_name put_value | |
192 | `(TAG ',$2 'put :value ',(list $3)) | |
193 | | PUT put_name put_value_list | |
194 | `(TAG ',$2 'put :value ',$3) | |
195 | | PUT put_name_list put_value | |
196 | `(TAG ',(car $2) 'put :rest ',(cdr $2) :value ',(list $3)) | |
197 | | PUT put_name_list put_value_list | |
198 | `(TAG ',(car $2) 'put :rest ',(cdr $2) :value ',$3) | |
199 | ; | |
200 | ||
201 | put_name_list: | |
202 | BRACE_BLOCK | |
203 | (mapcar 'semantic-tag-name (EXPANDFULL $1 put_names)) | |
204 | ; | |
205 | ||
206 | put_names: | |
207 | LBRACE | |
208 | () | |
209 | | RBRACE | |
210 | () | |
211 | | put_name | |
212 | ;; Must return a list of Semantic tags to EXPANDFULL! | |
213 | (TAG $1 'put-name) | |
214 | ; | |
215 | ||
216 | put_name: | |
217 | SYMBOL | |
218 | | token_type | |
219 | ; | |
220 | ||
221 | put_value_list: | |
222 | BRACE_BLOCK | |
223 | (mapcar 'semantic-tag-code-detail (EXPANDFULL $1 put_values)) | |
224 | ; | |
225 | ||
226 | put_values: | |
227 | LBRACE | |
228 | () | |
229 | | RBRACE | |
230 | () | |
231 | | put_value | |
232 | ;; Must return a list of Semantic tags to EXPANDFULL! | |
233 | (CODE-TAG "put-value" $1) | |
234 | ; | |
235 | ||
236 | put_value: | |
237 | SYMBOL any_value | |
238 | (cons $1 $2) | |
239 | ; | |
240 | ||
241 | scopestart_decl: | |
242 | SCOPESTART SYMBOL | |
243 | `(TAG ',$2 'scopestart) | |
244 | ; | |
245 | ||
246 | quotemode_decl: | |
247 | QUOTEMODE SYMBOL | |
248 | `(TAG ',$2 'quotemode) | |
249 | ; | |
250 | ||
251 | start_decl: | |
252 | START symbols | |
253 | `(TAG ',(car $2) 'start :rest ',(cdr $2)) | |
254 | ; | |
255 | ||
256 | keyword_decl: | |
257 | KEYWORD SYMBOL string_value | |
258 | `(TAG ',$2 'keyword :value ',$3) | |
259 | ; | |
260 | ||
261 | token_decl: | |
262 | TOKEN token_type_opt SYMBOL string_value | |
263 | `(TAG ',$3 ',(if $2 'token 'keyword) :type ',$2 :value ',$4) | |
264 | | TOKEN token_type_opt symbols | |
265 | `(TAG ',(car $3) 'token :type ',$2 :rest ',(cdr $3)) | |
266 | ; | |
267 | ||
268 | token_type_opt: | |
269 | ;; EMPTY | |
270 | | token_type | |
271 | ; | |
272 | ||
273 | token_type: | |
274 | LT SYMBOL GT | |
275 | (progn $2) | |
276 | ; | |
277 | ||
278 | type_decl: | |
279 | TYPE token_type plist_opt | |
280 | `(TAG ',$2 'type :value ',$3) | |
281 | ; | |
282 | ||
283 | plist_opt: | |
284 | ;;EMPTY | |
285 | | plist | |
286 | ; | |
287 | ||
288 | plist: | |
289 | plist put_value | |
290 | (append (list $2) $1) | |
291 | | put_value | |
292 | (list $1) | |
293 | ; | |
294 | ||
295 | use_name_list: | |
296 | BRACE_BLOCK | |
297 | (mapcar 'semantic-tag-name (EXPANDFULL $1 use_names)) | |
298 | ; | |
299 | ||
300 | use_names: | |
301 | LBRACE | |
302 | () | |
303 | | RBRACE | |
304 | () | |
305 | | SYMBOL | |
306 | ;; Must return a list of Semantic tags to EXPANDFULL! | |
307 | (TAG $1 'use-name) | |
308 | ; | |
309 | ||
310 | use_macros_decl: | |
311 | USE-MACROS SYMBOL use_name_list | |
312 | `(TAG "macro" 'macro :type ',$2 :value ',$3) | |
313 | ; | |
314 | ||
315 | string_value: | |
316 | STRING | |
317 | (read $1) | |
318 | ; | |
319 | ||
320 | ;; Return a Lisp readable form | |
321 | any_value: | |
322 | SYMBOL | |
323 | | STRING | |
324 | | PAREN_BLOCK | |
325 | | PREFIXED_LIST | |
326 | | SEXP | |
327 | ; | |
328 | ||
329 | symbols: | |
330 | lifo_symbols | |
331 | (nreverse $1) | |
332 | ; | |
333 | ||
334 | lifo_symbols: | |
335 | lifo_symbols SYMBOL | |
336 | (cons $2 $1) | |
337 | | SYMBOL | |
338 | (list $1) | |
339 | ; | |
340 | ||
341 | ;;; Grammar rules | |
342 | ;; | |
343 | nonterminal: | |
344 | SYMBOL | |
345 | (setq semantic-grammar-wy--nterm $1 | |
346 | semantic-grammar-wy--rindx 0) | |
347 | COLON rules SEMI | |
348 | (TAG $1 'nonterminal :children $4) | |
349 | ; | |
350 | ||
351 | rules: | |
352 | lifo_rules | |
353 | (apply 'nconc (nreverse $1)) | |
354 | ; | |
355 | ||
356 | lifo_rules: | |
357 | lifo_rules OR rule | |
358 | (cons $3 $1) | |
359 | | rule | |
360 | (list $1) | |
361 | ; | |
362 | ||
363 | rule: | |
364 | rhs | |
365 | (let* ((nterm semantic-grammar-wy--nterm) | |
366 | (rindx semantic-grammar-wy--rindx) | |
367 | (rhs $1) | |
368 | comps prec action elt) | |
369 | (setq semantic-grammar-wy--rindx (1+ semantic-grammar-wy--rindx)) | |
370 | (while rhs | |
371 | (setq elt (car rhs) | |
372 | rhs (cdr rhs)) | |
373 | (cond | |
374 | ;; precedence level | |
375 | ((vectorp elt) | |
376 | (if prec | |
377 | (error "Duplicate %%prec in `%s:%d' rule" nterm rindx)) | |
378 | (setq prec (aref elt 0))) | |
379 | ;; action | |
380 | ((consp elt) | |
381 | ;; don't forget that rhs items are in reverse order, so | |
382 | ;; the end-of-rule semantic action is the first item. | |
383 | (if (or action comps) | |
384 | ;; a mid-rule action | |
385 | (setq comps (cons elt comps) | |
386 | ;; keep rule and action index synchronized | |
387 | semantic-grammar-wy--rindx | |
388 | (1+ semantic-grammar-wy--rindx)) | |
389 | ;; the end-of-rule action | |
390 | (setq action (car elt)))) | |
391 | ;; item | |
392 | (t | |
393 | (setq comps (cons elt comps))))) | |
394 | (EXPANDTAG | |
395 | (TAG (format "%s:%d" nterm rindx) 'rule | |
396 | :type (if comps "group" "empty") | |
397 | :value comps :prec prec :expr action))) | |
398 | ; | |
399 | ||
400 | rhs: | |
401 | ;; EMPTY | |
402 | | rhs item | |
403 | (cons $2 $1) | |
404 | | rhs action | |
405 | (cons (list $2) $1) | |
406 | | rhs PREC item | |
407 | (cons (vector $3) $1) | |
408 | ; | |
409 | ||
410 | action: | |
411 | PAREN_BLOCK | |
412 | | PREFIXED_LIST | |
413 | | BRACE_BLOCK | |
414 | (format "(progn\n%s)" | |
415 | (let ((s $1)) | |
416 | (if (string-match "^{[\r\n\t ]*" s) | |
417 | (setq s (substring s (match-end 0)))) | |
418 | (if (string-match "[\r\n\t ]*}$" s) | |
419 | (setq s (substring s 0 (match-beginning 0)))) | |
420 | s)) | |
421 | ; | |
422 | ||
423 | items: | |
424 | lifo_items | |
425 | (nreverse $1) | |
426 | ; | |
427 | ||
428 | lifo_items: | |
429 | lifo_items item | |
430 | (cons $2 $1) | |
431 | | item | |
432 | (list $1) | |
433 | ; | |
434 | ||
435 | item: | |
436 | SYMBOL | |
437 | | CHARACTER | |
438 | ; | |
439 | ||
440 | %% | |
441 | ||
442 | ;;; grammar.wy ends here |