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