Fix putenv race conditions with undefined behavior.
[emacs.git] / admin / grammars / grammar.wy
blob4605e3c4f70e63503a694aa054189533f982d51a
1 ;;; semantic-grammar.wy -- LALR grammar of Semantic input grammars
2 ;;
3 ;; Copyright (C) 2002-2014 Free Software Foundation, Inc.
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 $
11 ;; This file is part of GNU Emacs.
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.
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.
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/>.
26 %package semantic-grammar-wy
27 %provide semantic/grammar-wy
30 (defvar semantic-grammar-lex-c-char-re)
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)
38 %languagemode wy-mode
40 ;; Main
41 %start grammar
42 ;; Reparse
43 %start prologue epilogue declaration nonterminal rule
44 ;; EXPANDFULL
45 %start put_names put_values use_names
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"
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)
132   ;
134 decl:
135     default_prec_decl
136   | no_default_prec_decl
137   | languagemode_decl
138   | package_decl
139   | provide_decl
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   ;
151 default_prec_decl:
152     DEFAULT-PREC
153     `(TAG "default-prec" 'assoc :value '("t"))
154   ;
156 no_default_prec_decl:
157     NO-DEFAULT-PREC
158     `(TAG "default-prec" 'assoc :value '("nil"))
159   ;
161 languagemode_decl:
162     LANGUAGEMODE symbols
163     `(TAG ',(car $2) 'languagemode :rest ',(cdr $2))
164   ;
166 package_decl:
167     PACKAGE SYMBOL
168     `(PACKAGE-TAG ',$2 nil)
169   ;
171 provide_decl:
172     PROVIDE SYMBOL
173     `(TAG ',$2 'provide)
174   ;
176 precedence_decl:
177     associativity token_type_opt items
178     `(TAG ',$1 'assoc :type ',$2 :value ',$3)
179   ;
181 associativity:
182     LEFT
183     (progn "left")
184   | RIGHT
185     (progn "right")
186   | NONASSOC
187     (progn "nonassoc")
188   ;
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   ;
201 put_name_list:
202     BRACE_BLOCK
203     (mapcar 'semantic-tag-name (EXPANDFULL $1 put_names))
204   ;
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   ;
216 put_name:
217     SYMBOL
218   | token_type
219   ;
221 put_value_list:
222     BRACE_BLOCK
223     (mapcar 'semantic-tag-code-detail (EXPANDFULL $1 put_values))
224   ;
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   ;
236 put_value:
237     SYMBOL any_value
238     (cons $1 $2)
239   ;
241 scopestart_decl:
242     SCOPESTART SYMBOL
243     `(TAG ',$2 'scopestart)
244   ;
246 quotemode_decl:
247     QUOTEMODE SYMBOL
248     `(TAG ',$2 'quotemode)
249   ;
251 start_decl:
252     START symbols
253     `(TAG ',(car $2) 'start :rest ',(cdr $2))
254   ;
256 keyword_decl:
257     KEYWORD SYMBOL string_value
258     `(TAG ',$2 'keyword :value ',$3)
259   ;
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   ;
268 token_type_opt:
269  ;; EMPTY
270   | token_type
271   ;
273 token_type:
274     LT SYMBOL GT
275     (progn $2)
276   ;
278 type_decl:
279     TYPE token_type plist_opt
280     `(TAG ',$2 'type :value ',$3)
281   ;
283 plist_opt:
284  ;;EMPTY
285   | plist
286   ;
288 plist:
289     plist put_value
290     (append (list $2) $1)
291   | put_value
292     (list $1)
293   ;
295 use_name_list:
296     BRACE_BLOCK
297     (mapcar 'semantic-tag-name (EXPANDFULL $1 use_names))
298   ;
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   ;
310 use_macros_decl:
311     USE-MACROS SYMBOL use_name_list
312     `(TAG "macro" 'macro :type ',$2 :value ',$3)
313   ;
315 string_value:
316     STRING
317     (read $1)
318   ;
320 ;; Return a Lisp readable form
321 any_value:
322     SYMBOL
323   | STRING
324   | PAREN_BLOCK
325   | PREFIXED_LIST
326   | SEXP
327   ;
329 symbols:
330     lifo_symbols
331     (nreverse $1)
332   ;
334 lifo_symbols:
335     lifo_symbols SYMBOL
336     (cons $2 $1)
337   | SYMBOL
338     (list $1)
339   ;
341 ;;; Grammar rules
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   ;
351 rules:
352     lifo_rules
353     (apply 'nconc (nreverse $1))
354   ;
356 lifo_rules:
357     lifo_rules OR rule
358     (cons $3 $1)
359   | rule
360     (list $1)
361   ;
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   ;
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   ;
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   ;
423 items:
424     lifo_items
425     (nreverse $1)
426   ;
428 lifo_items:
429     lifo_items item
430     (cons $2 $1)
431   | item
432     (list $1)
433   ;
435 item:
436     SYMBOL
437   | CHARACTER
438   ;
442 ;;; grammar.wy ends here