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