Initial Commit
[packages] / xemacs-packages / semantic / c.bnf
1 # C/C++ BNF language specification
2 #
3 # Copyright (C) 1999, 2000, 2001, 2002 Eric M. Ludlam
4 #
5 # Author: Eric M. Ludlam <zappo@gnu.org>
6 # X-RCS: $Id: c.bnf,v 1.59.2.10 2003/04/04 12:19:38 berndl Exp $
7 #
8 # c.bnf is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2, or (at your option)
11 # any later version.
12 #
13 # This software is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the GNU General Public License
19 # along with GNU Emacs; see the file COPYING.  If not, write to the
20 # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 # Boston, MA 02111-1307, USA.
22 #
23
24 %start         declaration
25 %scopestart    codeblock
26 %outputfile    semantic-c.el
27 %parsetable    semantic-toplevel-c-bovine-table
28 %keywordtable  semantic-c-keyword-table
29 %languagemode  (c-mode c++-mode)
30 %setupfunction semantic-default-c-setup
31
32 %(setq semantic-expand-nonterminal 'semantic-expand-c-nonterminal
33        semantic-flex-extensions semantic-flex-c-extensions
34        semantic-dependency-include-path semantic-default-c-path
35        semantic-orphaned-member-metaparent-type "struct"
36        semantic-symbol->name-assoc-list
37         '((type     . "Types")
38           (variable . "Variables")
39           (function . "Functions")
40           (include  . "Includes"))
41        semantic-symbol->name-assoc-list-for-type-parts
42         '((type     . "Types")
43           (variable . "Attributes")
44           (function . "Methods")
45           (label    . "Labels")
46           )
47        imenu-create-index-function 'semantic-create-imenu-index
48        semantic-type-relation-separator-character '("." "->")
49        semantic-command-separation-character ";"
50        document-comment-start "/*"
51        document-comment-line-prefix " *"
52        document-comment-end " */"
53        ;; Semantic navigation inside 'type children
54        senator-step-at-token-ids '(function variable)
55        )%
56
57 %token INCLUDE "include"
58 %token DEFINE "define"
59 %token HASH punctuation "#"
60 %token PERIOD punctuation "."
61 %token COLON punctuation ":"
62 %token SEMICOLON punctuation ";"
63 %token STAR punctuation "*"
64 %token AMPERSAND punctuation "&"
65 %token DIVIDE punctuation "/"
66 %token PLUS punctuation "+"
67 %token MINUS punctuation "-"
68 %token BANG punctuation "!"
69 %token EQUAL punctuation "="
70 %token LESS punctuation "<"
71 %token GREATER punctuation ">"
72 %token COMA punctuation ","
73 %token TILDE punctuation "~"
74
75 %token EXTERN "extern"
76 %put EXTERN summary "Declaration Modifier: extern <type> <name> ..."
77 %token STATIC "static"
78 %put STATIC summary "Declaration Modifier: static <type> <name> ..."
79 %token CONST "const"
80 %put CONST summary "Declaration Modifier: const <type> <name> ..."
81 %token VOLATILE "volatile"
82 %put VOLATILE summary "Declaration Modifier: volatile <type> <name> ..."
83 %token REGISTER "register"
84 %put REGISTER summary "Declaration Modifier: register <type> <name> ..."
85 %token SIGNED "signed"
86 %put SIGNED summary "Numeric Type Modifier: signed <numeric type> <name> ..."
87 %token UNSIGNED "unsigned"
88 %put UNSIGNED summary "Numeric Type Modifier: unsigned <numeric type> <name> ..."
89
90 %token INLINE "inline"
91 %put INLINE summary "Function Modifier: inline <return  type> <name>(...) {...};"
92 %token VIRTUAL "virtual"
93 %put VIRTUAL summary "Method Modifier: virtual <type> <name>(...) ..."
94 %token MUTABLE "mutable"
95 %put MUTABLE summary "Member Declaration Modifier: mutable <type> <name> ..."
96
97 %token STRUCT "struct"
98 %put STRUCT summary "Structure Type Declaration: struct [name] { ... };"
99 %token UNION "union"
100 %put UNION summary "Union Type Declaration: union [name] { ... };"
101 %token ENUM "enum"
102 %put ENUM summary "Enumeration Type Declaration: enum [name] { ... };"
103 %token TYPEDEF "typedef"
104 %put TYPEDEF summary "Arbitrary Type Declaration: typedef <typedeclaration> <name>;"
105 %token CLASS "class"
106 %put CLASS summary "Class Declaration: class <name>[:parents] { ... };"
107 %token TYPENAME "typename"
108 %put TYPENAME summary "typename is used to handle a qualified name as a typename;"
109 %token NAMESPACE "namespace"
110 %put NAMESPACE summary "Namespace Declaration: namespace <name> { ... };"
111 %token USING "using"
112 %put USING summary "using <namespace>;"
113
114 # Despite this, this parser can find templates by ignoring the TEMPLATE
115 # keyword, and finding the class/method being templateized.
116 %token TEMPLATE "template"
117 %put TEMPLATE summary "template <class TYPE ...> TYPE_OR_FUNCTION"
118
119 %token THROW "throw"
120 %put THROW summary "<type> <methoddef> (<method args>) throw (<exception>) ..."
121 %token REENTRANT "reentrant"
122 %put REENTRANT summary "<type> <methoddef> (<method args>) reentrant ..."
123
124 # Leave these alone for now.
125 %token OPERATOR "operator"
126 %token PUBLIC "public"
127 %token PRIVATE "private"
128 %token PROTECTED "protected"
129 %token FRIEND "friend"
130
131 # These aren't used for parsing, but is a useful place to describe the keywords.
132 %token IF "if"
133 %token ELSE "else"
134 %put {IF ELSE} summary  "if (<condition>) { code } [ else { code } ]"
135
136 %token DO "do"
137 %token WHILE "while"
138 %put DO summary " do { code } while (<condition>);"
139 %put WHILE summary "do { code } while (<condition>); or while (<condition>) { code };"
140
141 %token FOR "for"
142 %put FOR summary "for(<init>; <condition>; <increment>) { code }"
143
144 %token SWITCH "switch"
145 %token CASE "case"
146 %token DEFAULT "default"
147 %put {SWITCH CASE DEFAULT} summary
148 "switch (<variable>) { case <constvalue>: code; ... default: code; }"
149
150 %token RETURN "return"
151 %put RETURN summary "return <value>;"
152
153 %token BREAK "break"
154 %put BREAK summary "Non-local exit within a loop or switch (for, do/while, switch): break;"
155 %token CONTINUE "continue"
156 %put CONTINUE summary "Non-local continue within a lool (for, do/while): continue;"
157
158 %token SIZEOF "sizeof"
159 %put SIZEOF summary "Compile time macro: sizeof(<type or variable>) // size in bytes"
160
161 # Types
162 %token VOID "void"
163 %put VOID summary "Built in typeless type: void"
164 %token CHAR "char"
165 %put CHAR summary "Integral Character Type: (0 to 256)"
166 %token WCHAR "wchar_t"
167 %put WCHAR summary "Wide Character Type"
168 %token SHORT "short"
169 %put SHORT summary "Integral Primitive Type: (-32768 to 32767)"
170 %token INT "int"
171 %put INT summary "Integral Primitive Type: (-2147483648 to 2147483647)"
172 %token LONG "long"
173 %put LONG summary "Integral primitive type (-9223372036854775808 to 9223372036854775807)"
174 %token FLOAT "float"
175 %put FLOAT summary "Primitive floating-point type (single-precision 32-bit IEEE 754)"
176 %token DOUBLE "double"
177 %put DOUBLE summary "Primitive floating-point type (double-precision 64-bit IEEE 754)"
178
179 %token UNDERP "_P"
180 %token UNDERUNDERP "__P"
181 %put UNDERP summary "Common macro to eliminate prototype compatibility on some compilers"
182 %put UNDERUNDERP summary "Common macro to eliminate prototype compatibility on some compilers"
183
184 declaration : macro
185             | type
186 # TODO: Klaus Berndl <klaus.berndl@sdm.de>: Is the define here
187 # necessary or even wrong? Is this part not already covered by macro??
188             | define
189             | var-or-fun
190             | extern-c
191             | template
192             | using
193             ;
194
195 codeblock : define
196           | codeblock-var-or-fun
197           | type # type is less likely to be used here.
198           ;
199
200 extern-c-contents: open-paren
201                    ( nil )
202                  | bovine-toplevel
203                  | close-paren
204                    ( nil )
205                  ;
206
207 extern-c: EXTERN string "\"C\"" semantic-list
208         # Extern C commands which contain a list need to have the
209         # entries of the list extracted, and spliced into the main
210         # list of entries.  This must be done via the function
211         # that expands singular nonterminals, such as int x,y;
212           ( extern (EXPANDFULL $3 extern-c-contents) )
213         | EXTERN string "\"C\""
214         # A plain extern "C" call should add something to the token,
215         # but just strip it from the buffer here for now.
216           ( nil )
217         ;
218
219 # Klaus Berndl <klaus.berndl@sdm.de>: At least one-liner should be
220 # parsed correctly! Multi-line macros (every line ends with a
221 # backslash) not being one code-block can not be parsed because
222 # \+newline is flexed as nothing and therefore we can not distinguish
223 # if the lines > 1 belong to the macro or are separated statements!
224 # Maybe we need special backslash recognizing and then better
225 # macro-parsing. For the moment it's goog enough.
226 macro-expression-list : expression macro-expression-list SEMICOLON
227                         ( nil )
228                       | expression
229                         ( nil )
230                       ;
231
232
233 macro-def : macro-expression-list
234             ( nil )
235           | expression
236             ( nil )
237           | EMPTY 
238           ;
239
240 macro : HASH macro-or-include
241         ( ,$2 )
242       ;
243
244 macro-or-include : DEFINE symbol opt-define-arglist macro-def
245                    ( $2 variable nil $3
246                         (ASSOC const t)
247                         nil
248                         )
249                  | INCLUDE system-include
250                    ( (substring $2 1 (1- (length $2)))  include t nil )
251                  | INCLUDE string
252                    ( (read $2) include nil nil )
253                  ;
254
255 opt-define-arglist : semantic-list
256                      ( nil )
257                    | EMPTY
258                    ;
259
260 # This is used in struct parts.
261 define : HASH DEFINE symbol opt-define-arglist macro-def
262          ( $3 variable nil $4
263               (ASSOC const t)
264               nil
265               )
266        ;
267
268 # In C++, structures can have the same things as classes.
269 # So delete this somday in the figure.
270 #
271 #structparts : semantic-list
272 #             (EXPANDFULL $1 structsubparts)
273 #           ;
274 #
275 #structsubparts : open-paren "{"
276 #                ( nil )
277 #              | close-paren "}"
278 #                ( nil )
279 #              | var-or-fun
280 #              | define
281 #              # sometimes there are defines in structs.
282 #              ;
283
284 unionparts : semantic-list
285              (EXPANDFULL $1 classsubparts)
286            ;
287
288 opt-symbol : symbol
289            | EMPTY
290            ;
291
292 classsubparts : open-paren "{"
293                 ( nil )
294               | close-paren "}"
295                 ( nil )
296               | class-protection opt-symbol COLON
297               # For QT, they may put a `slot' keyword between the protection
298               # and the COLON.
299                 ( ,$1 label )
300               | var-or-fun
301               | type
302               | define        
303                 ( ,$1 protection )
304               | template
305               | EMPTY
306               ;
307
308 opt-class-parents : COLON class-parents opt-template-specifier
309                     ( $2 )
310                   | EMPTY
311                     ( )
312                   ;
313
314 class-parents : opt-class-protection opt-class-declmods
315                 namespace-symbol COMA class-parents
316                 ( ,(cons $3 $5 ) )
317               | opt-class-protection opt-class-declmods namespace-symbol
318                 ( ,$3 )
319               ;
320
321 opt-class-declmods : class-declmods opt-class-declmods
322                      ( nil )
323                    | EMPTY
324                    ;
325
326 class-declmods : VIRTUAL
327                ;
328
329 class-protection: PUBLIC
330                 | PRIVATE
331                 | PROTECTED
332                 ;
333
334 opt-class-protection : class-protection
335                        ( ,$1 )
336                      | EMPTY
337                      ;
338
339 namespaceparts : semantic-list
340                  (EXPANDFULL $1 namespacesubparts)
341                ;
342
343 namespacesubparts : open-paren "{"
344                     ( nil )
345                   | close-paren "}"
346                     ( nil )
347                   | type
348                   | var-or-fun
349                   | define
350                   | class-protection COLON
351                     ( $1 protection )
352                   # In C++, this label in a classsubpart represents
353                   # PUBLIC or PRIVATE bits.  Ignore them for now.
354                   | template
355                   | using
356                   | EMPTY
357                   ;
358
359 enumparts : semantic-list
360             (EXPANDFULL $1 enumsubparts)
361           ;
362
363 enumsubparts : symbol opt-assign
364                ( $1 variable "int" ,$2 (ASSOC const t) nil)
365              | open-paren "{"
366                ( nil )
367              | close-paren "}"
368                ( nil )
369              | COMA
370                ( nil )
371              ;
372
373 opt-name : symbol
374          | EMPTY
375            ( "" )
376          ;
377
378 opt-class-declmods : symbol declespec semantic-list
379                    | symbol
380                    | EMPTY
381                    ;
382
383 typesimple : struct-or-class opt-name opt-template-specifier
384              opt-class-parents semantic-list
385              ( ,$2 type ,$1 
386                    (let ((semantic-c-classname (cons (car ,$2) (car ,$1))))
387                        (EXPANDFULL $5 classsubparts))
388                    $4
389                    (ASSOC 'template-specifier $3)
390                    nil )
391            | struct-or-class opt-name opt-template-specifier opt-class-parents
392              ( ,$2 type ,$1 nil $4 
393                    (ASSOC 'template-specifier $3)
394                     nil )
395            | UNION opt-name unionparts
396              ( ,$2 type $1 $3 nil nil nil )
397            | ENUM opt-name enumparts
398              ( ,$2 type $1 $3 nil nil nil )
399 # Klaus Berndl <klaus.berndl@sdm.de>: a typedef can be a typeformbase
400 # with all this declmods stuff.
401            | TYPEDEF declmods typeformbase cv-declmods typedef-symbol-list
402            ## We put the type this typedef renames into PARENT
403            ## but will move it in the expand function.
404              ( $5 type $1 nil $3 nil nil )
405            ;
406
407 typedef-symbol-list : typedefname COMA typedef-symbol-list
408                       ( ,(cons $1 $3) )
409                     | typedefname
410                       ( $1 )
411                     ;
412
413 # TODO: Klaus Berndl <klaus.berndl@sdm.de>: symbol -> namespace-symbol?!
414 # Answer: Probably symbol is correct here!
415 typedefname : opt-stars symbol opt-bits opt-array
416               ( $1 $2 )
417             ;
418
419 struct-or-class: STRUCT
420                | CLASS
421                ;
422
423 type : typesimple SEMICOLON
424        ( ,$1 )
425      # named namespaces like "namespace XXX {"
426      | NAMESPACE symbol namespaceparts
427        ( $2 type $1 $3 nil nil nil )
428      # unnamed namespaces like "namespace {"
429      | NAMESPACE namespaceparts
430        ( "unnamed" type $1 $2 nil nil nil )
431      ;
432
433 # Klaus Berndl <klaus.berndl@sdm.de>: 
434 # We must parse "using namespace XXX" too
435
436 # Using is vaguely like an include statement in the named portions
437 # of the code.  We should probably specify a new token type for this.
438 using : USING typeformbase SEMICOLON
439         ( nil )
440       | USING NAMESPACE typeformbase SEMICOLON
441         ( nil )
442       ;
443
444 template : TEMPLATE template-specifier opt-friend template-definition
445            ( ,(semantic-c-reconstitute-template $4 ,$2) )
446          ;
447
448 opt-friend : FRIEND
449            | EMPTY
450            ;
451
452 opt-template-specifier : template-specifier
453                          ( ,$1 )
454                        | EMPTY
455                          ()
456                        ;
457
458 template-specifier : LESS template-specifier-types GREATER
459                      ( ,$2 )
460                    ;
461
462 template-specifier-types : template-var template-specifier-type-list
463                            ( ,(cons ,$1 ,$2 ) )
464                          | EMPTY
465                          ;
466
467 template-specifier-type-list : COMA template-specifier-types
468                                ( ,$2 )
469                              | EMPTY
470                                ( )
471                              ;
472
473 #template-var : template-type opt-stars opt-template-equal
474 #              ( ,(cons (concat (car $1) (make-string (car ,$2) ?*))
475 #                             (cdr $1)))
476 ## Klaus Berndl <klaus.berndl@sdm.de>: for template-types the
477 ## template-var can also be literals or constants.
478 ## Example: map<ClassX, ClassY, 10> map_size10_var; This parses also
479 ## template<class T, 0> which is nonsense but who cares....
480 #            | string
481 #              ( $1 )
482 #            | number
483 #              ( $1 )
484 #            ;
485
486 template-var : 
487 # Klaus Berndl <klaus.berndl@sdm.de>: The following handles all
488 # template-vars of template-definitions
489                template-type opt-template-equal
490                ( ,(cons (car $1) (cdr $1)) )
491 # Klaus Berndl <klaus.berndl@sdm.de>: for template-types the
492 # template-var can also be literals or constants.
493 # Example: map<ClassX, ClassY, 10> map_size10_var; This parses also
494 # template<class T, 0> which is nonsense but who cares....
495              | string
496                ( $1 )
497              | number
498                ( $1 )
499 # Klaus Berndl <klaus.berndl@sdm.de>: In template-types arguments can
500 # be any symbols with optional adress-operator (&) and optional
501 # dereferencing operator (*)
502 # Example map<ClassX, ClassY, *size_var_ptr> sized_map_var.
503              | opt-stars opt-ref namespace-symbol
504                ( ,$3 )
505              ;
506
507 opt-template-equal : EQUAL symbol LESS template-specifier-types GREATER
508                      ( $2 )
509                    | EMPTY
510                    ;
511
512 template-type : CLASS symbol
513                 ( $2 type "class" nil nil)
514               | STRUCT symbol
515                 ( $2 type "struct" nil nil)
516 # TODO: Klaus Berndl <klaus.berndl@sdm.de>: For the moment is is ok,
517 # that we parse the C++ keyword typename as a class....
518               | TYPENAME symbol
519                 ( $2 type "class" nil nil)
520 # Klaus Berndl <klaus.berndl@sdm.de>: template-types can be all
521 # flavors of variable-args but here the argument is ignored, only the
522 # type stuff is needed.
523               | declmods typeformbase cv-declmods opt-stars
524                 opt-ref variablearg-opt-name
525                 ( (car $2) type nil nil
526                   (ASSOC const (if (member "const" (append $1 $3)) t nil)
527                          typemodifiers (delete "const" (append $1 $3))
528                          reference (car ,$5)
529                          pointer (car $4)
530                          )
531                   )
532               ;
533
534 template-definition : type
535                       ( ,$1 )
536                     | var-or-fun
537                       ( ,$1 )
538                     ;
539
540 opt-stars :  STAR opt-starmod opt-stars
541             ( (1+ (car $3)) )
542           | EMPTY
543             ( 0 )
544           ;
545
546 opt-starmod : STARMOD opt-starmod
547               ( ,(cons (,car ,$1) $2) )
548             | EMPTY
549               ()
550             ;
551
552 STARMOD : CONST
553         ;
554
555 declmods : DECLMOD declmods
556            ( ,(cons ,(car ,$1) $2 ) )
557          | DECLMOD
558            ( ,$1 )
559          | EMPTY
560            ()
561          ;
562
563 DECLMOD : EXTERN
564         | STATIC
565         | CVDECLMOD
566 # Klaus Berndl <klaus.berndl@sdm.de>: IMHO signed and unsigned are not
567 # decl-modes but these are only valid for some buildin-types like
568 # short, int etc... whereas "real" declmods are valid for all types,
569 # buildin and user-defined!
570 #       | SIGNED
571 #       | UNSIGNED
572         | INLINE
573         | REGISTER
574         | FRIEND
575 # Klaus Berndl <klaus.berndl@sdm.de>: There can be a few cases where
576 # TYPENAME is not allowed in C++-syntax but better than not
577 # recognizing the allowed situations.
578         | TYPENAME
579         | METADECLMOD
580         # This is a hack in case we are in a class.
581         | VIRTUAL
582         ;
583
584 metadeclmod : METADECLMOD
585               ()
586             | EMPTY
587               ()
588             ;
589
590 CVDECLMOD : CONST
591           | VOLATILE
592           ;
593
594 cv-declmods : CVDECLMOD cv-declmods
595               ( ,(cons ,(car ,$1) $2 ) )
596             | CVDECLMOD
597               ( ,$1 )
598             | EMPTY
599               ()
600             ;
601
602 METADECLMOD : VIRTUAL
603             | MUTABLE
604             ;
605
606 # C++: A type can be modified into a reference by "&"
607 opt-ref : AMPERSAND
608           ( 1 )
609         | EMPTY
610           ( 0 )
611         ;
612
613 typeformbase : typesimple
614                ( ,$1 )
615              | STRUCT symbol
616                ( $2 type $1 )
617              | UNION symbol
618                ( $2 type $1 )
619              | ENUM symbol
620                ( $2 type $1 )
621              | builtintype
622                ( ,$1 )
623 #            | symbol template-specifier
624 #              ( $1 type "class" )
625 #            | namespace-symbol opt-stars opt-template-specifier
626 #            | namespace-symbol opt-template-specifier
627              | namespace-symbol
628 #              ( ,$1 )
629                ( ,$1 type "class" )
630              | symbol
631                ( $1 )
632              ;
633
634 signedmod : UNSIGNED
635           | SIGNED
636           ;
637
638 # Klaus Berndl <klaus.berndl@sdm.de>: builtintype-types was builtintype
639 builtintype-types : VOID
640                   | CHAR
641 # Klaus Berndl <klaus.berndl@sdm.de>: Added WCHAR
642                   | WCHAR
643                   | SHORT
644                   | INT
645                   | LONG INT
646                     ( (concat $1 " " $2) )
647                   | FLOAT
648                   | DOUBLE
649                   | LONG DOUBLE
650                     ( (concat $1 " " $2) )
651 # TODO: Klaus Berndl <klaus.berndl@sdm.de>: Is there a long long, i
652 # think so?!
653                   | LONG LONG
654                     ( (concat $1 " " $2) )
655                   | LONG
656                   ;
657
658 builtintype : signedmod builtintype-types
659               ( (concat (car $1) " " (car $2)) )
660             | builtintype-types
661               ( ,$1 )
662 # Klaus Berndl <klaus.berndl@sdm.de>: unsigned is synonym for unsigned
663 # int and signed for signed int. To make this confusing stuff clear we
664 # add here the int.
665             | signedmod
666             ( (concat (car $1) " int") )
667             ;
668
669 # Klaus Berndl <klaus.berndl@sdm.de>: This parses also nonsense like
670 # "const volatile int const volatile const const volatile a ..." but
671 # IMHO nobody writes such code. Normaly we shoud define a rule like
672 # typeformbase-mode which exactly defines the different allowed cases
673 # and combinations of declmods (minus the CVDECLMOD) typeformbase and
674 # cv-declmods so we could recognize more invalid code but IMHO this is
675 # not worth the effort...
676 codeblock-var-or-fun : declmods typeformbase declmods
677                        opt-ref var-or-func-decl
678                        ( ,(semantic-c-reconstitute-token ,$5 $1 $2 ) )
679                      ;
680
681 var-or-fun : codeblock-var-or-fun
682              ( ,$1 )
683            # it is possible for a function to not have a type, and
684            # it is then assumed to be an int.  How annoying.
685            # In C++, this could be a constructor or a destructor.
686            # Even more annoying.  Only ever do this for regular
687            # top-level items.  Ignore this problem in code blocks
688            # so that we don't have to deal with regular code
689            # being erroneously converted into types.
690            | declmods var-or-func-decl
691              ( ,(semantic-c-reconstitute-token ,$2 $1 nil ) )
692            ;
693
694 var-or-func-decl : func-decl
695                    ( ,$1 )
696                  | var-decl
697                    ( ,$1 )
698                  ;
699
700 func-decl : opt-stars opt-class opt-destructor functionname
701             opt-template-specifier
702             opt-under-p 
703             arg-list
704             opt-post-fcn-modifiers
705             opt-throw
706             opt-initializers
707             fun-or-proto-end
708             ( ,$4 'function 
709                   ;; Extra stuff goes in here.
710                   ;; Continue with the stuff we found in
711                   ;; this definition
712                   $2 $3 $7 $9 $8 ,$1 ,$11)
713           ;
714
715 var-decl :  varnamelist  SEMICOLON
716            ( $1 'variable )
717          ;
718
719 opt-under-p : UNDERP
720               (nil)
721             | UNDERUNDERP
722               (nil)
723             | EMPTY
724             ;
725
726 # Klaus Berndl <klaus.berndl@sdm.de>: symbol -> namespace-symbol
727 opt-initializers: COLON namespace-symbol semantic-list opt-initializers
728                 | COMA namespace-symbol semantic-list opt-initializers
729                 | EMPTY
730                 ;
731
732 opt-post-fcn-modifiers : post-fcn-modifiers opt-post-fcn-modifiers
733                          ( ,(cons ,$1 $2) )
734                        | EMPTY
735                          ( nil )
736                        ;
737
738 post-fcn-modifiers : REENTRANT
739                    | CONST
740                    ;
741
742 opt-throw : THROW semantic-list
743              ( EXPAND $2 throw-exception-list )
744            | EMPTY
745            ;
746
747 # Is this true?  I don't actually know.
748 throw-exception-list : namespace-symbol COMA throw-exception-list
749                        ( ,(cons (car $1) $3) )
750                      | namespace-symbol close-paren ")"
751                        ( ,$1 )
752                      | open-paren "(" throw-exception-list
753                        ( ,$2 )
754                      | close-paren ")"
755                        (  )
756                      ;
757
758 opt-bits : COLON number
759            ( $2 )
760          | EMPTY
761            ( nil )
762          ;
763
764 opt-array : semantic-list "\\[.*\\]$" opt-array
765           # Eventually we want to replace the 1 below with a size
766           # (if available)
767             ( (cons 1 (car ,$2) ) )
768           | EMPTY
769             ( nil )
770           ;
771
772 opt-assign : EQUAL expression
773              ( $2 )
774            | EMPTY
775              ( nil )
776            ;
777
778 opt-restrict : symbol "\\<\\(__\\)?restrict\\>"
779              | EMPTY
780              ;
781
782
783 # Klaus Berndl <klaus.berndl@sdm.de>: symbol -> namespace-symbol?! I
784 # think so. Can be that then also some invalid C++-syntax is parsed
785 # but this is better than not parsing valid syntax.
786 varname : opt-stars opt-restrict namespace-symbol opt-bits opt-array opt-assign
787           ( ,$3 ,$1 ,$4 ,$5 ,$6 )
788         ;
789
790 # I should store more in this def, but leave it simple for now. Klaus
791 # Berndl <klaus.berndl@sdm.de>: const and volatile can be written
792 # after the type!
793 variablearg : declmods typeformbase cv-declmods opt-ref variablearg-opt-name
794               ( (list $5) variable $2 nil
795                 (ASSOC const (if (member "const" (append $1 $3)) t nil)
796                        typemodifiers (delete "const" (append $1 $3))
797                        reference (car ,$4)
798                        )
799                  nil
800                  )
801             ;
802
803 variablearg-opt-name: varname
804                       ( ,$1)
805 # Klaus Berndl <klaus.berndl@sdm.de>: This allows variableargs without
806 # a arg-name being parsed correct even if there several pointers (*)
807                     | opt-stars
808                       ( "" ,$1 nil nil nil )
809                     ;
810
811 varnamelist : varname COMA varnamelist
812               ( ,(cons $1 $3) )
813             | varname
814               ( $1 )
815             ;
816
817 # Klaus Berndl <klaus.berndl@sdm.de>: 
818 # Is necessary to parse stuff like 
819 #     class list_of_facts : public list<fact>, public entity
820 # and
821 #     list <shared_ptr<item> >::const_iterator l;
822 # Parses also invalid(?) and senseless(?) c++-syntax like
823 #     symbol<template-spec>::symbol1<template-spec1>::test_iterator
824 # but better parsing too much than to less
825 namespace-symbol : symbol opt-template-specifier COLON COLON namespace-symbol
826                    ( (concat $1 "::" (car $5)) )
827                  | symbol opt-template-specifier
828                    ( $1 )
829                  ;
830
831 #namespace-symbol : symbol COLON COLON namespace-symbol
832 #                  ( (concat $1 "::" (car $4)) )
833 #                | symbol
834 #                  ( $1 )
835 #                ;
836
837 namespace-opt-class : symbol COLON COLON namespace-opt-class
838                       ( (concat $1 "::" (car $4)) )
839 # Klaus Berndl <klaus.berndl@sdm.de>: We must recognize
840 # template-specifiers here so we can parse correctly the
841 # method-implementations of template-classes outside the
842 # template-class-declaration
843 # Example: TemplateClass1<T>::method_1(...)
844                     | symbol opt-template-specifier COLON COLON
845                       ( $1 )
846                     ;
847
848 # Klaus Berndl <klaus.berndl@sdm.de>: The opt-class of a func-decl
849 # must be able to recognize opt-classes with namespaces, e.g.
850 # Test1::Test2::classname::
851 opt-class : namespace-opt-class
852             ( ,$1 )
853           | EMPTY
854             ( nil )
855           ;
856
857 opt-destructor : TILDE
858                  ( t )
859                | EMPTY
860                  ( nil )
861                ;
862
863 arg-list : semantic-list "^(" knr-arguments
864            ( ,$2 )
865          | semantic-list "^("
866            (EXPANDFULL $1 arg-sub-list)
867          | semantic-list "^(void)$"
868            ( )
869          ;
870
871 knr-arguments : variablearg SEMICOLON knr-arguments
872                 ( ,(cons (car (semantic-expand-c-nonterminal ,$1) ) ,$3) )
873               | variablearg SEMICOLON
874                 ( (car (semantic-expand-c-nonterminal ,$1)) )
875               ;
876
877 arg-sub-list : variablearg
878                ( ,$1 )
879              | PERIOD PERIOD PERIOD close-paren ")"
880                ( "..." )
881              | COMA
882                ( nil )
883              | open-paren "("
884                ( nil )
885              | close-paren ")"
886                ( nil )
887              ;
888
889 operatorsym : LESS LESS
890               ( "<<" )
891             | GREATER GREATER
892               ( ">>" )
893             | EQUAL EQUAL
894               ( "==" )
895             | LESS EQUAL
896               ( "<=" )
897             | GREATER EQUAL
898               ( ">=" )
899             | BANG EQUAL
900               ( "!=" )
901             | MINUS GREATER
902               ( "->" )
903 # Klaus Berndl <klaus.berndl@sdm.de>: We have to parse also
904 # operator() and operator[]
905             | semantic-list "()"
906               ( "()" )
907             | semantic-list "\\[\\]"
908               ( "[]" )
909             | LESS
910             | GREATER
911             | STAR
912             | PLUS
913             | MINUS
914             | DIVIDE
915             | EQUAL
916             | BANG
917             ;
918
919 functionname : OPERATOR operatorsym
920                ( ,$2 )
921              | symbol
922                ( $1 )
923              ;
924
925 fun-or-proto-end: SEMICOLON
926                   ( t )
927                 | semantic-list
928                   ( nil )
929                 # Here is an anoying feature of C++ pure virtual methods
930                 | EQUAL number "^0$" SEMICOLON
931                   ( 'pure-virtual )
932                 ;
933
934 type-cast : semantic-list
935             ( EXPAND $1 type-cast-list )
936           ;
937
938 type-cast-list : open-paren typeformbase close-paren
939                ;
940
941 # Klaus Berndl <klaus.berndl@sdm.de>: symbol -> namespace-symbol!
942 function-call: namespace-symbol semantic-list
943              ;
944
945 string-seq : string string-seq
946              ( (concat $1 (car $2)) )
947            | string
948              ( $1 )
949            ;
950
951 # Use expression for parsing only.  Don't actually return anything
952 # for now.  Hopefully we can fix this later.
953 expression : number
954              ( (identity start) (identity end) ) 
955            | function-call
956              ( (identity start) (identity end) )
957 # Klaus Berndl <klaus.berndl@sdm.de>: symbol -> namespace-symbol!
958            | namespace-symbol
959              ( (identity start) (identity end) )
960 # Klaus Berndl <klaus.berndl@sdm.de>: C/C++ allows sequences of
961 # strings which are concatenated by the precompiler to one string
962            | string-seq
963              ( (identity start) (identity end))
964            | type-cast expression  # A cast to some other type
965              ( (identity start) (identity end) )
966            | semantic-list
967              ( (identity start) (identity end) )
968            | punctuation "[-+*/%^|&]" expression
969              ( (identity start) (identity end) )
970            ;