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