ruby-rubocop-use-bundler: New user option
[emacs.git] / admin / grammars / grammar.wy
bloba81a2df4a6fb037050d48befcaadb228a0b72e3d
1 ;;; semantic-grammar.wy -- LALR grammar of Semantic input grammars
2 ;;
3 ;; Copyright (C) 2002-2024 Free Software Foundation, Inc.
4 ;;
5 ;; Author: David Ponce <david@dponce.com>
6 ;; Created: 26 Aug 2002
7 ;; Keywords: syntax
8 ;; X-RCS: $Id: semantic-grammar.wy,v 1.16 2005/09/30 20:20:27 zappo Exp $
10 ;; This file is part of GNU Emacs.
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.
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.
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
25 %package semantic-grammar-wy
26 %provide semantic/grammar-wy
29 (defvar semantic-grammar-lex-c-char-re)
31 ;; Current parsed nonterminal name.
32 (defvar semantic-grammar-wy--nterm nil)
33 ;; Index of rule in a nonterminal clause.
34 (defvar semantic-grammar-wy--rindx nil)
37 %languagemode wy-mode
39 ;; Main
40 %start grammar
41 ;; Reparse
42 %start prologue epilogue declaration nonterminal rule
43 ;; EXPANDFULL
44 %start put_names put_values use_names
46 ;; Keywords
47 %type    <keyword>
48 %keyword DEFAULT-PREC    "%default-prec"
49 %keyword NO-DEFAULT-PREC "%no-default-prec"
50 %keyword KEYWORD         "%keyword"
51 %keyword LANGUAGEMODE    "%languagemode"
52 %keyword LEFT            "%left"
53 %keyword NONASSOC        "%nonassoc"
54 %keyword PACKAGE         "%package"
55 %keyword EXPECTEDCONFLICTS "%expectedconflicts"
56 %keyword PROVIDE         "%provide"
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"
67 ;; Literals
68 %type  <string>
69 %token <string>      STRING
71 %type  <symbol>      syntax ":?\\(\\sw\\|\\s_\\)+"
72 %token <symbol>      SYMBOL
73 %token <symbol>      PERCENT_PERCENT "\\`%%\\'"
75 %type  <char>        syntax semantic-grammar-lex-c-char-re
76 %token <char>        CHARACTER
78 %type  <qlist>       matchdatatype sexp syntax "\\s'\\s-*("
79 %token <qlist>       PREFIXED_LIST
81 %type  <sexp>        matchdatatype sexp syntax "\\="
82 %token <sexp>        SEXP
84 ;; Don't generate these analyzers which needs special handling code.
85 %token <code>        PROLOGUE "%{...%}"
86 %token <code>        EPILOGUE "%%...EOF"
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      "}"
97 ;; Punctuation
98 %type  <punctuation>
99 %token <punctuation> COLON       ":"
100 %token <punctuation> SEMI        ";"
101 %token <punctuation> OR          "|"
102 %token <punctuation> LT          "<"
103 %token <punctuation> GT          ">"
107 grammar:
108     prologue
109   | epilogue
110   | declaration
111   | nonterminal
112   | PERCENT_PERCENT
113   ;
115 ;;; Prologue/Epilogue
117 prologue:
118     PROLOGUE
119     (CODE-TAG "prologue" nil)
120   ;
122 epilogue:
123     EPILOGUE
124     (CODE-TAG "epilogue" nil)
125   ;
127 ;;; Declarations
129 declaration:
130     decl
131     (eval $1 t)
132   ;
134 decl:
135     default_prec_decl
136   | no_default_prec_decl
137   | languagemode_decl
138   | package_decl
139   | expectedconflicts_decl
140   | provide_decl
141   | precedence_decl
142   | put_decl
143   | quotemode_decl
144   | scopestart_decl
145   | start_decl
146   | keyword_decl
147   | token_decl
148   | type_decl
149   | use_macros_decl
150   ;
152 default_prec_decl:
153     DEFAULT-PREC
154     `(TAG "default-prec" 'assoc :value '("t"))
155   ;
157 no_default_prec_decl:
158     NO-DEFAULT-PREC
159     `(TAG "default-prec" 'assoc :value '("nil"))
160   ;
162 languagemode_decl:
163     LANGUAGEMODE symbols
164     `(TAG ',(car $2) 'languagemode :rest ',(cdr $2))
165   ;
167 package_decl:
168     PACKAGE SYMBOL
169     `(PACKAGE-TAG ',$2 nil)
170   ;
172 expectedconflicts_decl:
173     EXPECTEDCONFLICTS symbols
174     `(TAG ',(car $2) 'expectedconflicts :rest ',(cdr $2))
175   ;
177 provide_decl:
178     PROVIDE SYMBOL
179     `(TAG ',$2 'provide)
180   ;
182 precedence_decl:
183     associativity token_type_opt items
184     `(TAG ',$1 'assoc :type ',$2 :value ',$3)
185   ;
187 associativity:
188     LEFT
189     (progn "left")
190   | RIGHT
191     (progn "right")
192   | NONASSOC
193     (progn "nonassoc")
194   ;
196 put_decl:
197     PUT put_name put_value
198     `(TAG ',$2 'put :value ',(list $3))
199   | PUT put_name put_value_list
200     `(TAG ',$2 'put :value ',$3)
201   | PUT put_name_list put_value
202     `(TAG ',(car $2) 'put :rest ',(cdr $2) :value ',(list $3))
203   | PUT put_name_list put_value_list
204     `(TAG ',(car $2) 'put :rest ',(cdr $2) :value ',$3)
205   ;
207 put_name_list:
208     BRACE_BLOCK
209     (mapcar #'semantic-tag-name (EXPANDFULL $1 put_names))
210   ;
212 put_names:
213     LBRACE
214     ()
215   | RBRACE
216     ()
217   | put_name
218  ;; Must return a list of Semantic tags to EXPANDFULL!
219     (TAG $1 'put-name)
220   ;
222 put_name:
223     SYMBOL
224   | token_type
225   ;
227 put_value_list:
228     BRACE_BLOCK
229     (mapcar #'semantic-tag-code-detail (EXPANDFULL $1 put_values))
230   ;
232 put_values:
233     LBRACE
234     ()
235   | RBRACE
236     ()
237   | put_value
238  ;; Must return a list of Semantic tags to EXPANDFULL!
239     (CODE-TAG "put-value" $1)
240   ;
242 put_value:
243     SYMBOL any_value
244     (cons $1 $2)
245   ;
247 scopestart_decl:
248     SCOPESTART SYMBOL
249     `(TAG ',$2 'scopestart)
250   ;
252 quotemode_decl:
253     QUOTEMODE SYMBOL
254     `(TAG ',$2 'quotemode)
255   ;
257 start_decl:
258     START symbols
259     `(TAG ',(car $2) 'start :rest ',(cdr $2))
260   ;
262 keyword_decl:
263     KEYWORD SYMBOL string_value
264     `(TAG ',$2 'keyword :value ',$3)
265   ;
267 token_decl:
268     TOKEN token_type_opt SYMBOL string_value
269     `(TAG ',$3 ',(if $2 'token 'keyword) :type ',$2 :value ',$4)
270   | TOKEN token_type_opt symbols
271     `(TAG ',(car $3) 'token :type ',$2 :rest ',(cdr $3))
272   ;
274 token_type_opt:
275  ;; EMPTY
276   | token_type
277   ;
279 token_type:
280     LT SYMBOL GT
281     (progn $2)
282   ;
284 type_decl:
285     TYPE token_type plist_opt
286     `(TAG ',$2 'type :value ',$3)
287   ;
289 plist_opt:
290  ;;EMPTY
291   | plist
292   ;
294 plist:
295     plist put_value
296     (append (list $2) $1)
297   | put_value
298     (list $1)
299   ;
301 use_name_list:
302     BRACE_BLOCK
303     (mapcar #'semantic-tag-name (EXPANDFULL $1 use_names))
304   ;
306 use_names:
307     LBRACE
308     ()
309   | RBRACE
310     ()
311   | SYMBOL
312  ;; Must return a list of Semantic tags to EXPANDFULL!
313     (TAG $1 'use-name)
314   ;
316 use_macros_decl:
317     USE-MACROS SYMBOL use_name_list
318     `(TAG "macro" 'macro :type ',$2 :value ',$3)
319   ;
321 string_value:
322     STRING
323     (read $1)
324   ;
326 ;; Return a Lisp readable form
327 any_value:
328     SYMBOL
329   | STRING
330   | PAREN_BLOCK
331   | PREFIXED_LIST
332   | SEXP
333   ;
335 symbols:
336     lifo_symbols
337     (nreverse $1)
338   ;
340 lifo_symbols:
341     lifo_symbols SYMBOL
342     (cons $2 $1)
343   | SYMBOL
344     (list $1)
345   ;
347 ;;; Grammar rules
349 nonterminal:
350     SYMBOL
351     (setq semantic-grammar-wy--nterm $1
352           semantic-grammar-wy--rindx 0)
353     COLON rules SEMI
354     (TAG $1 'nonterminal :children $4)
355   ;
357 rules:
358     lifo_rules
359     (apply #'nconc (nreverse $1))
360   ;
362 lifo_rules:
363     lifo_rules OR rule
364     (cons $3 $1)
365   | rule
366     (list $1)
367   ;
369 rule:
370     rhs
371     (let* ((nterm semantic-grammar-wy--nterm)
372            (rindx semantic-grammar-wy--rindx)
373            (rhs   $1)
374            comps prec action elt)
375       (setq semantic-grammar-wy--rindx (1+ semantic-grammar-wy--rindx))
376       (while rhs
377         (setq elt (car rhs)
378               rhs (cdr rhs))
379         (cond
380          ;; precedence level
381          ((vectorp elt)
382           (if prec
383               (error "Duplicate %%prec in `%s:%d' rule" nterm rindx))
384           (setq prec (aref elt 0)))
385          ;; action
386          ((consp elt)
387           ;; don't forget that rhs items are in reverse order, so
388           ;; the end-of-rule semantic action is the first item.
389           (if (or action comps)
390               ;; a mid-rule action
391               (setq comps (cons elt comps)
392                     ;; keep rule and action index synchronized
393                     semantic-grammar-wy--rindx
394                     (1+ semantic-grammar-wy--rindx))
395             ;; the end-of-rule action
396             (setq action (car elt))))
397          ;; item
398          (t
399           (setq comps (cons elt comps)))))
400       (EXPANDTAG
401        (TAG (format "%s:%d" nterm rindx) 'rule
402             :type (if comps "group" "empty")
403             :value comps :prec prec :expr action)))
404   ;
406 rhs:
407  ;; EMPTY
408   | rhs item
409     (cons $2 $1)
410   | rhs action
411     (cons (list $2) $1)
412   | rhs PREC item
413     (cons (vector $3) $1)
414   ;
416 action:
417     PAREN_BLOCK
418   | PREFIXED_LIST
419   | BRACE_BLOCK
420     (format "(progn\n%s)"
421             (let ((s $1))
422               (if (string-match "^{[\r\n\t ]*" s)
423                   (setq s (substring s (match-end 0))))
424               (if (string-match "[\r\n\t ]*}$" s)
425                   (setq s (substring s 0 (match-beginning 0))))
426               s))
427   ;
429 items:
430     lifo_items
431     (nreverse $1)
432   ;
434 lifo_items:
435     lifo_items item
436     (cons $2 $1)
437   | item
438     (list $1)
439   ;
441 item:
442     SYMBOL
443   | CHARACTER
444   ;
448 ;;; grammar.wy ends here