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