* lisp/emacs-lisp/bytecomp.el: Silence obsolete warnings more reliably.
[emacs.git] / admin / grammars / c.by
blob004f0b5f30fbf32636a430f99828689c5c5dfcf4
1 ;;; c.by -- LL grammar for C/C++ language specification
3 ;; Copyright (C) 1999-2011 Free Software Foundation, Inc.
4 ;;
5 ;; Author: Eric M. Ludlam <zappo@gnu.org>
6 ;;         David Ponce <david@dponce.com>
7 ;;         Klaus Berndl <klaus.berndl@sdm.de>
8 ;;
9 ;; This file is part of GNU Emacs.
11 ;; GNU Emacs is free software: you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation, either version 3 of the License, or
14 ;; (at your option) any later version.
16 ;; GNU Emacs is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
24 ;; TODO:  From Nate Schley
25 ;; >  * Can't parse signature element: "const char* const rmc_ClrTxt"
26 ;; >  * Can't parse signature element: "char* const dellog_ClrTxt"
27 ;; >  * Can't parse signature element: "const char* dellog_SetTxt"
28 ;; >  * Can't parse signature element: "const RmcCmdSSPADetailedStatus& status"
29 ;; >
30 ;; > And FWIW I have seen the following argument cases not handled, even
31 ;; > with no leading/trailing spaces in the split:
32 ;; >
33 ;; >  * Can't parse signature element: "const bool currentAlarmStatus"
34 ;; >  * Can't parse signature element: "unsigned char mode"
35 ;; >  * Can't parse signature element: "TskTimingTask* tsktimingtask"
36 ;; >  * Can't parse signature element: "unsigned char htrStatus"
37 ;; >  * Can't parse signature element: "char trackPower[]"
38 ;; >  * Can't parse signature element: "const RmcCmdMCDetailedStatus& status"
39 ;; >  * Can't parse signature element: "RmcBucStatus* rftBucStatus"
41 %package semantic-c-by
43 %languagemode  c-mode c++-mode
44 %start         declaration
45 %scopestart    codeblock
47 %token <punctuation>   HASH       "\\`[#]\\'"
48 %token <punctuation>   PERIOD     "\\`[.]\\'"
49 %token <punctuation>   COLON      "\\`[:]\\'"
50 %token <punctuation>   SEMICOLON  "\\`[;]\\'"
51 %token <punctuation>   STAR       "\\`[*]\\'"
52 %token <punctuation>   AMPERSAND  "\\`[&]\\'"
53 %token <punctuation>   DIVIDE     "\\`[/]\\'"
54 %token <punctuation>   PLUS       "\\`[+]\\'"
55 %token <punctuation>   MINUS      "\\`[-]\\'"
56 %token <punctuation>   BANG       "\\`[!]\\'"
57 %token <punctuation>   EQUAL      "\\`[=]\\'"
58 %token <punctuation>   LESS       "\\`[<]\\'"
59 %token <punctuation>   GREATER    "\\`[>]\\'"
60 %token <punctuation>   COMA       "\\`[,]\\'"
61 %token <punctuation>   TILDE      "\\`[~]\\'"
62 %token <punctuation>   MOD        "\\`[%]\\'"
63 %token <punctuation>   HAT        "\\`\\^\\'"
64 %token <punctuation>   OR         "\\`[|]\\'"
65 %token <string>        C          "\"C\""
66 %token <string>        CPP        "\"C\\+\\+\""
67 %token <number>        ZERO       "^0$"
68 %token <symbol>        RESTRICT   "\\<\\(__\\)?restrict\\>"
69 %token <open-paren>    LPAREN     "("
70 %token <close-paren>   RPAREN     ")"
71 %token <open-paren>    LBRACE     "{"
72 %token <close-paren>   RBRACE     "}"
73 %token <semantic-list> BRACK_BLCK "\\[.*\\]$"
74 %token <semantic-list> PAREN_BLCK "^("
75 %token <semantic-list> BRACE_BLCK "^{"
76 %token <semantic-list> VOID_BLCK  "^(void)$"
77 %token <semantic-list> PARENS     "()"
78 %token <semantic-list> BRACKETS   "\\[\\]"
80 %token EXTERN "extern"
81 %put EXTERN summary "Declaration Modifier: extern <type> <name> ..."
82 %token STATIC "static"
83 %put STATIC summary "Declaration Modifier: static <type> <name> ..."
84 %token CONST "const"
85 %put CONST summary "Declaration Modifier: const <type> <name> ..."
86 %token VOLATILE "volatile"
87 %put VOLATILE summary "Declaration Modifier: volatile <type> <name> ..."
88 %token REGISTER "register"
89 %put REGISTER summary "Declaration Modifier: register <type> <name> ..."
90 %token SIGNED "signed"
91 %put SIGNED summary "Numeric Type Modifier: signed <numeric type> <name> ..."
92 %token UNSIGNED "unsigned"
93 %put UNSIGNED summary "Numeric Type Modifier: unsigned <numeric type> <name> ..."
95 %token INLINE "inline"
96 %put INLINE summary "Function Modifier: inline <return  type> <name>(...) {...};"
97 %token VIRTUAL "virtual"
98 %put VIRTUAL summary "Method Modifier: virtual <type> <name>(...) ..."
99 %token MUTABLE "mutable"
100 %put MUTABLE summary "Member Declaration Modifier: mutable <type> <name> ..."
102 %token STRUCT "struct"
103 %put STRUCT summary "Structure Type Declaration: struct [name] { ... };"
104 %token UNION "union"
105 %put UNION summary "Union Type Declaration: union [name] { ... };"
106 %token ENUM "enum"
107 %put ENUM summary "Enumeration Type Declaration: enum [name] { ... };"
108 %token TYPEDEF "typedef"
109 %put TYPEDEF summary "Arbitrary Type Declaration: typedef <typedeclaration> <name>;"
110 %token CLASS "class"
111 %put CLASS summary "Class Declaration: class <name>[:parents] { ... };"
112 %token TYPENAME "typename"
113 %put TYPENAME summary "typename is used to handle a qualified name as a typename;"
114 %token NAMESPACE "namespace"
115 %put NAMESPACE summary "Namespace Declaration: namespace <name> { ... };"
116 %token USING "using"
117 %put USING summary "using <namespace>;"
119 %token NEW "new"
120 %put NEW summary "new <classname>();"
121 %token DELETE "delete"
122 %put DELETE summary "delete <object>;"
124 ;; Despite this, this parser can find templates by ignoring the TEMPLATE
125 ;; keyword, and finding the class/method being templateized.
126 %token TEMPLATE "template"
127 %put TEMPLATE summary "template <class TYPE ...> TYPE_OR_FUNCTION"
129 %token THROW "throw"
130 %put THROW summary "<type> <methoddef> (<method args>) throw (<exception>) ..."
131 %token REENTRANT "reentrant"
132 %put REENTRANT summary "<type> <methoddef> (<method args>) reentrant ..."
133 %token TRY "try"
134 %token CATCH "catch"
135 %put { TRY CATCH } summary "try { <body> } catch { <catch code> }"
137 ;; Leave these alone for now.
138 %token OPERATOR "operator"
139 %token PUBLIC "public"
140 %token PRIVATE "private"
141 %token PROTECTED "protected"
142 %token FRIEND "friend"
143 %put FRIEND summary "friend class <CLASSNAME>"
145 ;; These aren't used for parsing, but is a useful place to describe the keywords.
146 %token IF "if"
147 %token ELSE "else"
148 %put {IF ELSE} summary  "if (<condition>) { code } [ else { code } ]"
150 %token DO "do"
151 %token WHILE "while"
152 %put DO summary " do { code } while (<condition>);"
153 %put WHILE summary "do { code } while (<condition>); or while (<condition>) { code };"
155 %token FOR "for"
156 %put FOR summary "for(<init>; <condition>; <increment>) { code }"
158 %token SWITCH "switch"
159 %token CASE "case"
160 %token DEFAULT "default"
161 %put {SWITCH CASE DEFAULT} summary
162 "switch (<variable>) { case <constvalue>: code; ... default: code; }"
164 %token RETURN "return"
165 %put RETURN summary "return <value>;"
167 %token BREAK "break"
168 %put BREAK summary "Non-local exit within a loop or switch (for, do/while, switch): break;"
169 %token CONTINUE "continue"
170 %put CONTINUE summary "Non-local continue within a loop (for, do/while): continue;"
172 %token SIZEOF "sizeof"
173 %put SIZEOF summary "Compile time macro: sizeof(<type or variable>) // size in bytes"
175 ;; Types
176 %token VOID "void"
177 %put VOID summary "Built in typeless type: void"
178 %token CHAR "char"
179 %put CHAR summary "Integral Character Type: (0 to 256)"
180 %token WCHAR "wchar_t"
181 %put WCHAR summary "Wide Character Type"
182 %token SHORT "short"
183 %put SHORT summary "Integral Primitive Type: (-32768 to 32767)"
184 %token INT "int"
185 %put INT summary "Integral Primitive Type: (-2147483648 to 2147483647)"
186 %token LONG "long"
187 %put LONG summary "Integral primitive type (-9223372036854775808 to 9223372036854775807)"
188 %token FLOAT "float"
189 %put FLOAT summary "Primitive floating-point type (single-precision 32-bit IEEE 754)"
190 %token DOUBLE "double"
191 %put DOUBLE summary "Primitive floating-point type (double-precision 64-bit IEEE 754)"
192 %token BOOL "bool"
193 %put BOOL summary "Primitive boolean type"
195 %token UNDERP "_P"
196 %token UNDERUNDERP "__P"
197 %put UNDERP summary "Common macro to eliminate prototype compatibility on some compilers"
198 %put UNDERUNDERP summary "Common macro to eliminate prototype compatibility on some compilers"
202 declaration
203   : macro
204   | type
205  ;; TODO: Klaus Berndl: Is the define here necessary or even wrong?
206  ;; Is this part not already covered by macro??
207   | define
208   | var-or-fun
209   | extern-c
210   | template
211   | using
212   ;
214 codeblock
215   : define
216   | codeblock-var-or-fun
217   | type ;; type is less likely to be used here.
218   | using
219   ;
221 extern-c-contents
222   : open-paren
223     ( nil )
224   | declaration
225   | close-paren
226     ( nil )
227   ;
229 extern-c
230   : EXTERN C semantic-list
231  ;; Extern C commands which contain a list need to have the
232  ;; entries of the list extracted, and spliced into the main
233  ;; list of entries.  This must be done via the function
234  ;; that expands singular nonterminals, such as int x,y;
235     (TAG "C" 'extern :members (EXPANDFULL $3 extern-c-contents) )
236   | EXTERN CPP semantic-list
237     (TAG "C" 'extern :members (EXPANDFULL $3 extern-c-contents) )
238   | EXTERN C
239  ;; A plain extern "C" call should add something to the token,
240  ;; but just strip it from the buffer here for now.
241     ( nil )
242   | EXTERN CPP
243     ( nil )
244   ;
246 macro
247   : spp-macro-def
248     (VARIABLE-TAG $1 nil nil :constant-flag t )
249   | spp-system-include
250     (INCLUDE-TAG $1 t)
251   | spp-include
252     (INCLUDE-TAG $1 nil)
253   ;
255 ;; This is used in struct parts.
256 define
257   : spp-macro-def
258     (VARIABLE-TAG $1 nil nil :constant-flag t)
259   | spp-macro-undef
260     ( nil )
261   ;
263 ;; In C++, structures can have the same things as classes.
264 ;; So delete this somday in the figure.
266 ;;structparts : semantic-list
267 ;;            (EXPANDFULL $1 structsubparts)
268 ;;          ;
270 ;;structsubparts : LBRACE
271 ;;               ( nil )
272 ;;             | RBRACE
273 ;;               ( nil )
274 ;;             | var-or-fun
275 ;;             | define
276 ;;             ;; sometimes there are defines in structs.
277 ;;             ;
279 unionparts
280   : semantic-list
281     (EXPANDFULL $1 classsubparts)
282   ;
284 opt-symbol
285   : symbol
286   | ;;EMPTY
287   ;
289 ;; @todo - support 'friend' construct.
290 classsubparts
291   : LBRACE
292     ( nil )
293   | RBRACE
294     ( nil )
295   | class-protection opt-symbol COLON
296  ;; For QT, they may put a `slot' keyword between the protection
297  ;; and the COLON.  @todo - Have the QT stuff use macros.
298     (TAG (car $1) 'label)
299   | var-or-fun
300   | FRIEND func-decl
301     (TAG (car $2) 'friend)
302   | FRIEND CLASS symbol
303     (TAG $3 'friend)
304   | type
305   | define
306   | template
307   | ;;EMPTY
308   ;
310 opt-class-parents
311   : COLON class-parents opt-template-specifier
312     ( $2 )
313   | ;;EMPTY
314     ( )
315   ;
317 one-class-parent
318   : opt-class-protection opt-class-declmods namespace-symbol
319     (TYPE-TAG (car $3) "class" nil nil :protection (car $1))
320   | opt-class-declmods opt-class-protection namespace-symbol
321     (TYPE-TAG (car $3) "class" nil nil :protection (car $2))
322   ;
324 class-parents
325   : one-class-parent COMA class-parents
326     ( ,(cons ,$1 $3 ) )
327   | one-class-parent
328     ( $1 )
329   ;
331 opt-class-declmods
332   : class-declmods opt-class-declmods
333     ( nil )
334   | ;;EMPTY
335   ;
337 class-declmods
338   : VIRTUAL
339   ;
341 class-protection
342   : PUBLIC
343   | PRIVATE
344   | PROTECTED
345   ;
347 opt-class-protection
348   : class-protection
349     ( ,$1 )
350   | ;;EMPTY - Same as private
351     ( "unspecified" )
352   ;
354 namespaceparts
355   : semantic-list
356     (EXPANDFULL $1 namespacesubparts)
357   ;
359 namespacesubparts
360   : LBRACE
361     ( nil )
362   | RBRACE
363     ( nil )
364   | type
365   | var-or-fun
366   | define
367   | class-protection COLON
368     (TAG (car $1) 'label)
369  ;; In C++, this label in a classsubpart represents
370  ;; PUBLIC or PRIVATE bits.  Ignore them for now.
371   | template
372   | using
373   | ;;EMPTY
374   ;
376 enumparts
377   : semantic-list
378     (EXPANDFULL $1 enumsubparts)
379   ;
381 enumsubparts
382   : symbol opt-assign
383     (VARIABLE-TAG $1 "int" (car $2) :constant-flag t )
384   | LBRACE
385     ( nil )
386   | RBRACE
387     ( nil )
388   | COMA
389     ( nil )
390   ;
392 opt-name
393   : symbol
394   | ;;EMPTY
395     ( "" )
396   ;
398 typesimple
399   : struct-or-class opt-class opt-name opt-template-specifier
400     opt-class-parents semantic-list
401     (TYPE-TAG (car $3) (car $1)
402           (let ((semantic-c-classname (cons (car ,$3) (car ,$1))))
403             (EXPANDFULL $6 classsubparts))
404           $5
405           :template-specifier $4
406           :parent (car ,$2))
407   | struct-or-class opt-class opt-name opt-template-specifier
408     opt-class-parents
409     (TYPE-TAG (car $3) (car $1) nil $5
410               :template-specifier $4
411               :prototype t
412               :parent (car ,$2))
413   | UNION opt-class opt-name unionparts
414     (TYPE-TAG (car $3) $1 $4 nil
415               :parent (car ,$2))
416   | ENUM opt-class opt-name enumparts
417     (TYPE-TAG (car $3) $1 $4 nil
418               :parent (car ,$2))
419  ;; Klaus Berndl: a typedef can be a typeformbase with all this
420  ;; declmods stuff.
421   | TYPEDEF declmods typeformbase cv-declmods typedef-symbol-list
422  ;;;; We put the type this typedef renames into PARENT
423  ;;;; but will move it in the expand function.
424     (TYPE-TAG $5 $1 nil (list $3) )
425   ;
427 typedef-symbol-list
428   : typedefname COMA typedef-symbol-list
429     ( ,(cons $1 $3) )
430   | typedefname
431     ( $1 )
432   ;
434 ;; TODO: Klaus Berndl: symbol -> namespace-symbol?!  Answer: Probably
435 ;; symbol is correct here!
436 typedefname
437   : opt-stars symbol opt-bits opt-array
438     ( $1 $2 )
439   ;
441 struct-or-class
442   : STRUCT
443   | CLASS
444   ;
446 type
447   : typesimple SEMICOLON
448     ( ,$1 )
449  ;; named namespaces like "namespace XXX {"
450   | NAMESPACE symbol namespaceparts
451     (TYPE-TAG $2 $1 $3 nil )
452  ;; unnamed namespaces like "namespace {"
453   | NAMESPACE namespaceparts
454     (TYPE-TAG "unnamed" $1 $2 nil )
455  ;; David Engster: namespace alias like "namespace foo = bar;"
456   | NAMESPACE symbol EQUAL typeformbase SEMICOLON
457     (TYPE-TAG $2 $1 (list (TYPE-TAG (car $4) $1 nil nil)) nil :kind 'alias )
458   ;
460 ;; Klaus Berndl: We must parse "using namespace XXX" too
462 ;; Using is vaguely like an include statement in the named portions
463 ;; of the code.  We should probably specify a new token type for this.
465 using
466   : USING usingname SEMICOLON
467     (TAG (car $2) 'using :type ,$2 )
468   ;
470 ;; Jan Moringen: Differentiate between 'using' and 'using namespace'
471 ;; Adapted to creating type tags by EML.
472 usingname
473   : typeformbase
474     (TYPE-TAG (car $1) "class" nil nil :prototype t)
475   | NAMESPACE typeformbase
476     (TYPE-TAG (car $2) "namespace" nil nil :prototype t)
477   ;
479 template
480   : TEMPLATE template-specifier opt-friend template-definition
481     ( ,(semantic-c-reconstitute-template $4 ,$2) )
482   ;
484 opt-friend
485   : FRIEND
486   | ;;EMPTY
487   ;
489 opt-template-specifier
490   : template-specifier
491     ( ,$1 )
492   | ;;EMPTY
493     ( )
494   ;
496 template-specifier
497   : LESS template-specifier-types GREATER
498     ( ,$2 )
499   ;
501 template-specifier-types
502   : template-var template-specifier-type-list
503     ( ,(cons ,$1 ,$2 ) )
504   | ;;EMPTY
505   ;
507 template-specifier-type-list
508   : COMA template-specifier-types
509     ( ,$2 )
510   | ;;EMPTY
511     ( )
512   ;
514 ;; template-var
515 ;;   : template-type opt-stars opt-template-equal
516 ;;     ( ,(cons (concat (car $1) (make-string (car ,$2) ?*))
517 ;;              (cdr $1)))
518 ;;  ;; Klaus Berndl: for template-types the template-var can also be
519 ;;  ;; literals or constants.  Example: map<ClassX, ClassY, 10>
520 ;;  ;; map_size10_var; This parses also template<class T, 0> which is
521 ;;  ;; nonsense but who cares....
522 ;;   | string
523 ;;     ( $1 )
524 ;;   | number
525 ;;     ( $1 )
526 ;;   ;
528 template-var
529   :
530  ;; Klaus Berndl: The following handles all template-vars of
531  ;; template-definitions
532     template-type opt-template-equal
533     ( ,(cons (car $1) (cdr $1)) )
534  ;; Klaus Berndl: for template-types the template-var can also be
535  ;; literals or constants.
536  ;; Example: map<ClassX, ClassY, 10> map_size10_var; This parses also
537  ;; template<class T, 0> which is nonsense but who cares....
538   | string
539     ( $1 )
540   | number
541     ( $1 )
542  ;; Klaus Berndl: In template-types arguments can be any symbols with
543  ;; optional address-operator (&) and optional dereferencing operator
544  ;; (*).  Example map<ClassX, ClassY, *size_var_ptr> sized_map_var.
545   | opt-stars opt-ref namespace-symbol
546     ( ,$3 )
547  ;; Some code can compile down into a number, but starts out as an
548  ;; expression, such as "sizeof(a)", or (sizeof(a)/sizeof(b))
549   | semantic-list
550     ( $1 )
551   | SIZEOF semantic-list
552     ( $2 )
553   ;
555 opt-template-equal
556   : EQUAL symbol LESS template-specifier-types GREATER
557     ( $2 )
558   | EQUAL symbol
559     ( $2 )
560   | ;;EMPTY
561     ( )
562   ;
564 template-type
565   : CLASS symbol
566     (TYPE-TAG $2 "class" nil nil )
567   | STRUCT symbol
568     (TYPE-TAG $2 "struct" nil nil )
569  ;; TODO: Klaus Berndl: For the moment it is ok, that we parse the C++
570  ;; keyword typename as a class....
571   | TYPENAME symbol
572     (TYPE-TAG $2 "class" nil nil)
573  ;; Klaus Berndl: template-types can be all flavors of variable-args
574  ;; but here the argument is ignored, only the type stuff is needed.
575   | declmods typeformbase cv-declmods opt-stars
576     opt-ref variablearg-opt-name
577     (TYPE-TAG (car $2) nil nil nil
578               :constant-flag (if (member "const" (append $1 $3)) t nil)
579               :typemodifiers (delete "const" (append $1 $3))
580               :reference (car ,$5)
581               :pointer (car $4)
582               )
583   ;
585 template-definition
586   : type
587     ( ,$1 )
588   | var-or-fun
589     ( ,$1 )
590   ;
592 opt-stars
593   : STAR opt-starmod opt-stars
594     ( (1+ (car $3)) )
595   | ;;EMPTY
596     ( 0 )
597   ;
599 opt-starmod
600   : STARMOD opt-starmod
601     ( ,(cons (,car ,$1) $2) )
602   | ;;EMPTY
603     ()
604   ;
606 STARMOD
607   : CONST
608   ;
610 declmods
611   : DECLMOD declmods
612     ( ,(cons ,(car ,$1) $2 ) )
613   | DECLMOD
614     ( ,$1 )
615   | ;;EMPTY
616     ()
617   ;
619 DECLMOD
620   : EXTERN
621   | STATIC
622   | CVDECLMOD
623  ;; Klaus Berndl: IMHO signed and unsigned are not decl-modes but
624  ;; these are only valid for some buildin-types like short, int
625  ;; etc... whereas "real" declmods are valid for all types, buildin
626  ;; and user-defined!  SIGNED UNSIGNED
627   | INLINE
628   | REGISTER
629   | FRIEND
630  ;; Klaus Berndl: There can be a few cases where TYPENAME is not
631  ;; allowed in C++-syntax but better than not recognizing the allowed
632  ;; situations.
633   | TYPENAME
634   | METADECLMOD
635  ;; This is a hack in case we are in a class.
636   | VIRTUAL
637   ;
639 metadeclmod
640   : METADECLMOD
641     ()
642   | ;;EMPTY
643     ()
644   ;
646 CVDECLMOD
647   : CONST
648   | VOLATILE
649   ;
651 cv-declmods
652   : CVDECLMOD cv-declmods
653     ( ,(cons ,(car ,$1) $2 ) )
654   | CVDECLMOD
655     ( ,$1 )
656   | ;;EMPTY
657     ()
658   ;
660 METADECLMOD
661   : VIRTUAL
662   | MUTABLE
663   ;
665 ;; C++: A type can be modified into a reference by "&"
666 opt-ref
667   : AMPERSAND
668     ( 1 )
669   | ;;EMPTY
670     ( 0 )
671   ;
673 typeformbase
674   : typesimple
675     ( ,$1 )
676   | STRUCT symbol
677     (TYPE-TAG $2 $1 nil nil )
678   | UNION symbol
679     (TYPE-TAG $2 $1 nil nil )
680   | ENUM symbol
681     (TYPE-TAG $2 $1 nil nil )
682   | builtintype
683     ( ,$1 )
684   | symbol template-specifier
685     (TYPE-TAG $1 "class" nil nil :template-specifier $2)
686  ;;| namespace-symbol opt-stars opt-template-specifier
687  ;;| namespace-symbol opt-template-specifier
688   | namespace-symbol-for-typeformbase opt-template-specifier
689     (TYPE-TAG (car $1) "class" nil nil
690               :template-specifier $2)
691   | symbol
692     ( $1 )
693   ;
695 signedmod
696   : UNSIGNED
697   | SIGNED
698   ;
700 ;; Klaus Berndl: builtintype-types was builtintype
701 builtintype-types
702   : VOID
703   | CHAR
704  ;; Klaus Berndl: Added WCHAR
705   | WCHAR
706   | SHORT INT
707     ( (concat $1 " " $2) )
708   | SHORT
709   | INT
710   | LONG INT
711     ( (concat $1 " " $2) )
712   | FLOAT
713   | DOUBLE
714   | BOOL
715   | LONG DOUBLE
716     ( (concat $1 " " $2) )
717  ;; TODO: Klaus Berndl: Is there a long long, i think so?!
718   | LONG LONG
719     ( (concat $1 " " $2) )
720   | LONG
721   ;
723 builtintype
724   : signedmod builtintype-types
725     ( (concat (car $1) " " (car $2)) )
726   | builtintype-types
727     ( ,$1 )
728  ;; Klaus Berndl: unsigned is synonym for unsigned int and signed for
729  ;; signed int. To make this confusing stuff clear we add here the
730  ;; int.
731   | signedmod
732     ( (concat (car $1) " int") )
733   ;
735 ;; Klaus Berndl: This parses also nonsense like "const volatile int
736 ;; const volatile const const volatile a ..." but IMHO nobody writes
737 ;; such code. Normally we should define a rule like typeformbase-mode
738 ;; which exactly defines the different allowed cases and combinations
739 ;; of declmods (minus the CVDECLMOD) typeformbase and cv-declmods so
740 ;; we could recognize more invalid code but IMHO this is not worth the
741 ;; effort...
742 codeblock-var-or-fun
743   : declmods typeformbase declmods
744     opt-ref var-or-func-decl
745     ( ,(semantic-c-reconstitute-token ,$5 $1 $2 ) )
746   ;
748 var-or-fun
749   : codeblock-var-or-fun
750     ( ,$1 )
751  ;; it is possible for a function to not have a type, and
752  ;; it is then assumed to be an int.  How annoying.
753  ;; In C++, this could be a constructor or a destructor.
754  ;; Even more annoying.  Only ever do this for regular
755  ;; top-level items.  Ignore this problem in code blocks
756  ;; so that we don't have to deal with regular code
757  ;; being erroneously converted into types.
758   | declmods var-or-func-decl
759     ( ,(semantic-c-reconstitute-token ,$2 $1 nil ) )
760   ;
762 var-or-func-decl
763   : func-decl
764     ( ,$1 )
765   | var-decl
766     ( ,$1 )
767   ;
769 func-decl
770   : opt-stars opt-class opt-destructor functionname
771     opt-template-specifier
772     opt-under-p
773     arg-list
774     opt-post-fcn-modifiers
775     opt-throw
776     opt-initializers
777     fun-or-proto-end
778     ( ,$4 'function
779           ;; Extra stuff goes in here.
780           ;; Continue with the stuff we found in
781           ;; this definition
782           $2 $3 $7 $9 $8 ,$1 ,$11 $5 ,$10)
783   | opt-stars opt-class opt-destructor functionname
784     opt-template-specifier
785     opt-under-p
786  ;; arg-list   - - ini this case, a try implies a fcn.
787     opt-post-fcn-modifiers
788     opt-throw
789     opt-initializers
790     fun-try-end
791     ( ,$4 'function
792           ;; Extra stuff goes in here.
793           ;; Continue with the stuff we found in
794           ;; this definition
795           $2 $3 nil $8 $7 ,$1 ,$10 $5 ,$9)
796   ;
798 var-decl
799   : varnamelist SEMICOLON
800     ( $1 'variable )
801   ;
803 opt-under-p
804   : UNDERP
805     ( nil )
806   | UNDERUNDERP
807     ( nil )
808   | ;;EMPTY
809   ;
811 ;; Klaus Berndl: symbol -> namespace-symbol
812 opt-initializers
813   : COLON namespace-symbol semantic-list opt-initializers
814   | COMA namespace-symbol semantic-list opt-initializers
815   | ;;EMPTY
816   ;
818 opt-post-fcn-modifiers
819   : post-fcn-modifiers opt-post-fcn-modifiers
820     ( ,(cons ,$1 $2) )
821   | ;;EMPTY
822     ( nil )
823   ;
825 post-fcn-modifiers
826   : REENTRANT
827   | CONST
828   ;
830 opt-throw
831   : THROW semantic-list
832     ( EXPAND $2 throw-exception-list )
833   | ;;EMPTY
834   ;
836 ;; Is this true?  I don't actually know.
837 throw-exception-list
838   : namespace-symbol COMA throw-exception-list
839     ( ,(cons (car $1) $3) )
840   | namespace-symbol RPAREN
841     ( ,$1 )
842   | symbol RPAREN
843     ( $1 )
844   | LPAREN throw-exception-list
845     ( ,$2 )
846   | RPAREN
847     (  )
848   ;
850 opt-bits
851   : COLON number
852     ( $2 )
853   | ;;EMPTY
854     ( nil )
855   ;
857 opt-array
858   : BRACK_BLCK opt-array
859  ;; Eventually we want to replace the 1 below with a size
860  ;; (if available)
861     ( (cons 1 (car ,$2) ) )
862   | ;;EMPTY
863     ( nil )
864   ;
866 opt-assign
867   : EQUAL expression
868     ( $2 )
869   | ;;EMPTY
870     ( nil )
871   ;
873 opt-restrict
874   : RESTRICT
875   | ;;EMPTY
876   ;
878 ;; Klaus Berndl: symbol -> namespace-symbol?! I think so. Can be that
879 ;; then also some invalid C++-syntax is parsed but this is better than
880 ;; not parsing valid syntax.
881 varname
882   : opt-stars opt-restrict namespace-symbol opt-bits opt-array
883     ( ,$3 ,$1 ,$4 ,$5 )
884   ;
886 ;; I should store more in this def, but leave it simple for now.
887 ;; Klaus Berndl: const and volatile can be written after the type!
888 variablearg
889   : declmods typeformbase cv-declmods opt-ref variablearg-opt-name
890     ( VARIABLE-TAG (list $5) $2 nil
891                    :constant-flag (if (member "const" (append $1 $3)) t nil)
892                    :typemodifiers (delete "const" (append $1 $3))
893                    :reference (car ,$4)
894                    )
895   ;
897 variablearg-opt-name
898   : varname
899     ( ,$1 )
900  ;; Klaus Berndl: This allows variableargs without a arg-name being
901  ;; parsed correct even if there several pointers (*)
902   | opt-stars
903     ( "" ,$1 nil nil nil )
904   ;
906 varname-opt-initializer
907   : semantic-list
908   | opt-assign
909   | ;; EMPTY
910   ;
912 varnamelist
913   : opt-ref varname varname-opt-initializer COMA varnamelist
914     ( ,(cons $2 $5) )
915   | opt-ref varname varname-opt-initializer
916     ( $2 )
917   ;
919 ;; Klaus Berndl: Is necessary to parse stuff like
920 ;;     class list_of_facts : public list<fact>, public entity
921 ;; and
922 ;;     list <shared_ptr<item> >::const_iterator l;
923 ;; Parses also invalid(?) and senseless(?) c++-syntax like
924 ;;     symbol<template-spec>::symbol1<template-spec1>::test_iterator
925 ;; but better parsing too much than to less
926 namespace-symbol
927   : symbol opt-template-specifier COLON COLON namespace-symbol
928     ( (concat $1 "::" (car $5)) )
929   | symbol opt-template-specifier
930     ( $1 )
931   ;
933 ;; Don't pull an optional template specifier at the end of the
934 ;; namespace symbol so that it can be picked up by the type.
935 namespace-symbol-for-typeformbase
936   : symbol opt-template-specifier COLON COLON namespace-symbol-for-typeformbase
937     ( (concat $1 "::" (car $5)) )
938   | symbol
939     ( $1 )
940   ;
941 ;; namespace-symbol
942 ;;   : symbol COLON COLON namespace-symbol
943 ;;     ( (concat $1 "::" (car $4)) )
944 ;;   | symbol
945 ;;     ( $1 )
946 ;;   ;
948 namespace-opt-class
949   : symbol COLON COLON namespace-opt-class
950     ( (concat $1 "::" (car $4)) )
951  ;; Klaus Berndl: We must recognize template-specifiers here so we can
952  ;; parse correctly the method-implementations of template-classes
953  ;; outside the template-class-declaration Example:
954  ;; TemplateClass1<T>::method_1(...)
955   | symbol opt-template-specifier COLON COLON
956     ( $1 )
957   ;
959 ;; Klaus Berndl: The opt-class of a func-decl must be able to
960 ;; recognize opt-classes with namespaces, e.g.
961 ;; Test1::Test2::classname::
962 opt-class
963   : namespace-opt-class
964     ( ,$1 )
965   | ;;EMPTY
966     ( nil )
967   ;
969 opt-destructor
970   : TILDE
971     ( t )
972   | ;;EMPTY
973     ( nil )
974   ;
976 arg-list
977   : PAREN_BLCK knr-arguments
978     ( ,$2 )
979   | PAREN_BLCK
980     (EXPANDFULL $1 arg-sub-list)
981   | VOID_BLCK
982     ( )
983   ;
985 knr-varnamelist
986   : varname COMA knr-varnamelist
987     ( ,(cons $1 $3) )
988   | varname
989     ( $1 )
990   ;
993 knr-one-variable-decl
994   : declmods typeformbase cv-declmods knr-varnamelist
995     ( VARIABLE-TAG (nreverse $4) $2 nil
996                    :constant-flag (if (member "const" (append $3)) t nil)
997                    :typemodifiers (delete "const" $3)
998                    )
999   ;
1001 knr-arguments
1002   : knr-one-variable-decl SEMICOLON knr-arguments
1003     ( ,(append (semantic-expand-c-tag ,$1) ,$3) )
1004   | knr-one-variable-decl SEMICOLON
1005     ( ,(semantic-expand-c-tag ,$1) )
1006   ;
1008 arg-sub-list
1009   : variablearg
1010     ( ,$1 )
1011   | PERIOD PERIOD PERIOD RPAREN
1012     (VARIABLE-TAG "..." "vararg" nil)
1013   | COMA
1014     ( nil )
1015   | LPAREN
1016     ( nil )
1017   | RPAREN
1018     ( nil )
1019   ;
1021 operatorsym
1022   : LESS LESS EQUAL
1023     ( "<<=" )
1024   | GREATER GREATER EQUAL
1025     ( ">>=" )
1026   | LESS LESS
1027     ( "<<" )
1028   | GREATER GREATER
1029     ( ">>" )
1030   | EQUAL EQUAL
1031     ( "==" )
1032   | LESS EQUAL
1033     ( "<=" )
1034   | GREATER EQUAL
1035     ( ">=" )
1036   | BANG EQUAL
1037     ( "!=" )
1038   | PLUS EQUAL
1039     ( "+=" )
1040   | MINUS EQUAL
1041     ( "-=" )
1042   | STAR EQUAL
1043     ( "*=" )
1044   | DIVIDE EQUAL
1045     ( "/=" )
1046   | MOD EQUAL
1047     ( "%=" )
1048   | AMPERSAND EQUAL
1049     ( "&=" )
1050   | OR EQUAL
1051     ( "|=" )
1052   | MINUS GREATER STAR
1053     ( "->*" )
1054   | MINUS GREATER
1055     ( "->" )
1056   | PARENS
1057     ( "()" )
1058   | BRACKETS
1059     ( "[]" )
1060   | LESS
1061   | GREATER
1062   | STAR
1063   | PLUS PLUS
1064     ( "++" )
1065   | PLUS
1066   | MINUS MINUS
1067     ( "--" )
1068   | MINUS
1069   | AMPERSAND AMPERSAND
1070     ( "&&" )
1071   | AMPERSAND
1072   | OR OR
1073     ( "||" )
1074   | OR
1075   | DIVIDE
1076   | EQUAL
1077   | BANG
1078   | TILDE
1079   | MOD
1080   | COMA
1081  ;; HAT EQUAL seems to have a really unpleasant result and
1082  ;; breaks everything after it.  Leave it at the end, though it
1083  ;; doesn't seem to work.
1084   | HAT EQUAL
1085     ( "^=" )
1086   | HAT
1087   ;
1089 functionname
1090   : OPERATOR operatorsym
1091     ( ,$2 )
1092   | semantic-list
1093     ( EXPAND $1 function-pointer )
1094   | symbol
1095     ( $1 )
1096   ;
1098 function-pointer
1099   : LPAREN STAR symbol RPAREN
1100     ( (concat "*" $3) )
1101   ;
1103 fun-or-proto-end
1104   : SEMICOLON
1105     ( t )
1106   | semantic-list
1107     ( nil )
1108  ;; Here is an annoying feature of C++ pure virtual methods
1109   | EQUAL ZERO SEMICOLON
1110     ( :pure-virtual-flag )
1111   | fun-try-end
1112     ( nil )
1113   ;
1115 fun-try-end
1116   : TRY opt-initializers BRACE_BLCK fun-try-several-catches
1117     ( nil )
1118   ;
1120 fun-try-several-catches
1121   : CATCH PAREN_BLCK BRACE_BLCK fun-try-several-catches
1122     ( )
1123   | CATCH BRACE_BLCK fun-try-several-catches
1124     ( )
1125   | ;; EMPTY
1126     ( )
1127   ;
1129 type-cast
1130   : semantic-list
1131     ( EXPAND $1 type-cast-list )
1132   ;
1134 type-cast-list
1135   : open-paren typeformbase close-paren
1136   ;
1138 opt-stuff-after-symbol
1139   : PAREN_BLCK
1140   | BRACK_BLCK
1141   | ;; EMPTY
1142   ;
1144 multi-stage-dereference
1145   : namespace-symbol opt-stuff-after-symbol PERIOD multi-stage-dereference ;; method call
1146   | namespace-symbol opt-stuff-after-symbol MINUS GREATER multi-stage-dereference ;;method call
1147   | namespace-symbol opt-stuff-after-symbol
1148   ;
1150 string-seq
1151   : string string-seq
1152     ( (concat $1 (car $2)) )
1153   | string
1154     ( $1 )
1155   ;
1157 expr-start
1158   : MINUS
1159   | PLUS
1160   | STAR
1161   | AMPERSAND
1162   ;
1164 expr-binop
1165   : MINUS
1166   | PLUS
1167   | STAR
1168   | DIVIDE
1169   | AMPERSAND AMPERSAND
1170   | AMPERSAND
1171   | OR OR
1172   | OR
1173  ;; There are more.
1174   ;
1176 ;; Use expression for parsing only.  Don't actually return anything
1177 ;; for now.  Hopefully we can fix this later.
1178 expression
1179   : unaryexpression expr-binop unaryexpression
1180     ( (identity start) (identity end) )
1181   | unaryexpression
1182     ( (identity start) (identity end) )
1183   ;
1185 unaryexpression
1186   : number
1187   | multi-stage-dereference
1188   | NEW multi-stage-dereference
1189   | NEW builtintype-types semantic-list
1190  ;; Klaus Berndl: symbol -> namespace-symbol!
1191   | namespace-symbol
1192  ;; Klaus Berndl: C/C++ allows sequences of strings which are
1193  ;; concatenated by the precompiler to one string
1194   | string-seq
1195   | type-cast expression  ;; A cast to some other type
1196  ;; Casting the results of one expression to something else.
1197   | semantic-list expression
1198   | semantic-list
1199   | expr-start expression
1200   ;
1202 ;;; c.by ends here