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