]> code.delx.au - gnu-emacs/blob - admin/grammars/c.by
f6015490939b060f39641b78bab3025c73cab964
[gnu-emacs] / admin / grammars / c.by
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.
9
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.
14
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.
19
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/>.
22
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"
39
40 %package semantic-c-by
41 %provide semantic/bovine/c-by
42
43 %{
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))
51 }
52
53 %languagemode c-mode c++-mode
54 %start declaration
55 %scopestart codeblock
56
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 "\\[\\]"
90
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> ..."
105
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>"
114
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>;"
131
132 %token NEW "new"
133 %put NEW summary "new <classname>();"
134 %token DELETE "delete"
135 %put DELETE summary "delete <object>;"
136
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"
141
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> }"
149
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>"
157
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 } ]"
162
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 };"
167
168 %token FOR "for"
169 %put FOR summary "for(<init>; <condition>; <increment>) { code }"
170
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; }"
176
177 %token RETURN "return"
178 %put RETURN summary "return <value>;"
179
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;"
184
185 %token SIZEOF "sizeof"
186 %put SIZEOF summary "Compile time macro: sizeof(<type or variable>) // size in bytes"
187
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"
207
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"
212
213 %%
214
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 ;
226
227 codeblock
228 : define
229 | codeblock-var-or-fun
230 | type ;; type is less likely to be used here.
231 | using
232 ;
233
234 extern-c-contents
235 : open-paren
236 ( nil )
237 | declaration
238 | close-paren
239 ( nil )
240 ;
241
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 ;
258
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 ;
267
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 ;
275
276 ;; In C++, structures can have the same things as classes.
277 ;; So delete this some day in the figure.
278 ;;
279 ;;structparts : semantic-list
280 ;; (EXPANDFULL $1 structsubparts)
281 ;; ;
282 ;;
283 ;;structsubparts : LBRACE
284 ;; ( nil )
285 ;; | RBRACE
286 ;; ( nil )
287 ;; | var-or-fun
288 ;; | define
289 ;; ;; sometimes there are defines in structs.
290 ;; ;
291
292 unionparts
293 : semantic-list
294 (EXPANDFULL $1 classsubparts)
295 ;
296
297 opt-symbol
298 : symbol
299 | ;;EMPTY
300 ;
301
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 ;
322
323 opt-class-parents
324 : COLON class-parents opt-template-specifier
325 ( $2 )
326 | ;;EMPTY
327 ( )
328 ;
329
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 ;
336
337 class-parents
338 : one-class-parent COMA class-parents
339 ( ,(cons ,$1 $3 ) )
340 | one-class-parent
341 ( $1 )
342 ;
343
344 opt-class-declmods
345 : class-declmods opt-class-declmods
346 ( nil )
347 | ;;EMPTY
348 ;
349
350 class-declmods
351 : VIRTUAL
352 ;
353
354 class-protection
355 : PUBLIC
356 | PRIVATE
357 | PROTECTED
358 ;
359
360 opt-class-protection
361 : class-protection
362 ( ,$1 )
363 | ;;EMPTY - Same as private
364 ( "unspecified" )
365 ;
366
367 namespaceparts
368 : semantic-list
369 (EXPANDFULL $1 namespacesubparts)
370 ;
371
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 ;
391
392 enumparts
393 : semantic-list
394 (EXPANDFULL $1 enumsubparts)
395 ;
396
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 ;
407
408 opt-name
409 : symbol
410 | ;;EMPTY
411 ( "" )
412 ;
413
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 ;
442
443 typedef-symbol-list
444 : typedefname COMA typedef-symbol-list
445 ( ,(cons $1 $3) )
446 | typedefname
447 ( $1 )
448 ;
449
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 ;
456
457 struct-or-class
458 : STRUCT
459 | CLASS
460 ;
461
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 ;
475
476 ;; Klaus Berndl: We must parse "using namespace XXX" too
477
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.
480
481 using
482 : USING usingname SEMICOLON
483 (TAG (car $2) 'using :type ,$2 )
484 ;
485
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 ;
494
495 template
496 : TEMPLATE template-specifier opt-friend template-definition
497 ( ,(semantic-c-reconstitute-template $4 ,$2) )
498 ;
499
500 opt-friend
501 : FRIEND
502 | ;;EMPTY
503 ;
504
505 opt-template-specifier
506 : template-specifier
507 ( ,$1 )
508 | ;;EMPTY
509 ( )
510 ;
511
512 template-specifier
513 : LESS template-specifier-types GREATER
514 ( ,$2 )
515 ;
516
517 template-specifier-types
518 : template-var template-specifier-type-list
519 ( ,(cons ,$1 ,$2 ) )
520 | ;;EMPTY
521 ;
522
523 template-specifier-type-list
524 : COMA template-specifier-types
525 ( ,$2 )
526 | ;;EMPTY
527 ( )
528 ;
529
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 ;; ;
543
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 ;
570
571 opt-template-equal
572 : EQUAL symbol LESS template-specifier-types GREATER
573 ( $2 )
574 | EQUAL symbol
575 ( $2 )
576 | ;;EMPTY
577 ( )
578 ;
579
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 ;
602
603 template-definition
604 : type
605 ( ,$1 )
606 | var-or-fun
607 ( ,$1 )
608 ;
609
610 opt-stars
611 : STAR opt-starmod opt-stars
612 ( (1+ (car $3)) )
613 | ;;EMPTY
614 ( 0 )
615 ;
616
617 opt-starmod
618 : STARMOD opt-starmod
619 ( ,(cons (,car ,$1) $2) )
620 | ;;EMPTY
621 ()
622 ;
623
624 STARMOD
625 : CONST
626 ;
627
628 declmods
629 : DECLMOD declmods
630 ( ,(cons ,(car ,$1) $2 ) )
631 | DECLMOD
632 ( ,$1 )
633 | ;;EMPTY
634 ()
635 ;
636
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 ;
656
657 metadeclmod
658 : METADECLMOD
659 ()
660 | ;;EMPTY
661 ()
662 ;
663
664 CVDECLMOD
665 : CONST
666 | VOLATILE
667 ;
668
669 cv-declmods
670 : CVDECLMOD cv-declmods
671 ( ,(cons ,(car ,$1) $2 ) )
672 | CVDECLMOD
673 ( ,$1 )
674 | ;;EMPTY
675 ()
676 ;
677
678 METADECLMOD
679 : VIRTUAL
680 | MUTABLE
681 ;
682
683 ;; C++: A type can be modified into a reference by "&"
684 opt-ref
685 : AMPERSAND
686 ( 1 )
687 | ;;EMPTY
688 ( 0 )
689 ;
690
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 ;
712
713 signedmod
714 : UNSIGNED
715 | SIGNED
716 ;
717
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 ;
740
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 ;
752
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 ;
765
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 ;
779
780 var-or-func-decl
781 : func-decl
782 ( ,$1 )
783 | var-decl
784 ( ,$1 )
785 ;
786
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 ;
815
816 var-decl
817 : varnamelist SEMICOLON
818 ( $1 'variable )
819 ;
820
821 opt-under-p
822 : UNDERP
823 ( nil )
824 | UNDERUNDERP
825 ( nil )
826 | ;;EMPTY
827 ;
828
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 ;
835
836 opt-post-fcn-modifiers
837 : post-fcn-modifiers opt-post-fcn-modifiers
838 ( ,(cons ,(car $1) $2) )
839 | ;;EMPTY
840 ( nil )
841 ;
842
843 post-fcn-modifiers
844 : REENTRANT
845 | CONST
846 ;
847
848 opt-throw
849 : THROW semantic-list
850 ( EXPAND $2 throw-exception-list )
851 | ;;EMPTY
852 ;
853
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 ;
867
868 opt-bits
869 : COLON number
870 ( $2 )
871 | ;;EMPTY
872 ( nil )
873 ;
874
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 ;
883
884 opt-assign
885 : EQUAL expression
886 ( $2 )
887 | ;;EMPTY
888 ( nil )
889 ;
890
891 opt-restrict
892 : RESTRICT
893 | ;;EMPTY
894 ;
895
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 ;
903
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 ;
914
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 ;
925
926 varname-opt-initializer
927 : semantic-list
928 | opt-assign
929 | ;; EMPTY
930 ;
931
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 ;
938
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 ;
952
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 ;; ;
967
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 ;
978
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 ;
988
989 opt-destructor
990 : TILDE
991 ( t )
992 | ;;EMPTY
993 ( nil )
994 ;
995
996 arg-list
997 : PAREN_BLCK knr-arguments
998 ( ,$2 )
999 | PAREN_BLCK
1000 (EXPANDFULL $1 arg-sub-list)
1001 | VOID_BLCK
1002 ( )
1003 ;
1004
1005 knr-varnamelist
1006 : varname COMA knr-varnamelist
1007 ( ,(cons $1 $3) )
1008 | varname
1009 ( $1 )
1010 ;
1011
1012
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 ;
1020
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 ;
1027
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 ;
1040
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 ;
1108
1109 functionname
1110 : OPERATOR operatorsym
1111 ( ,$2 )
1112 | semantic-list
1113 ( EXPAND $1 function-pointer )
1114 | symbol
1115 ( $1 )
1116 ;
1117
1118 function-pointer
1119 : LPAREN STAR opt-symbol RPAREN
1120 ( (concat "*" ,(car $3)) )
1121 | LPAREN symbol RPAREN
1122 ( $2 )
1123 ;
1124
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 ;
1136
1137 fun-try-end
1138 : TRY opt-initializers BRACE_BLCK fun-try-several-catches
1139 ( nil )
1140 ;
1141
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 ;
1150
1151 type-cast
1152 : semantic-list
1153 ( EXPAND $1 type-cast-list )
1154 ;
1155
1156 type-cast-list
1157 : open-paren typeformbase close-paren
1158 ;
1159
1160 opt-brackets-after-symbol
1161 : brackets-after-symbol
1162 | ;; EMPTY
1163 ;
1164
1165 brackets-after-symbol
1166 : PAREN_BLCK
1167 | BRACK_BLCK
1168 ;
1169
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 ;
1181
1182 string-seq
1183 : string string-seq
1184 ( (concat $1 (car $2)) )
1185 | string
1186 ( $1 )
1187 ;
1188
1189 expr-start
1190 : MINUS
1191 | PLUS
1192 | STAR
1193 | AMPERSAND
1194 ;
1195
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 ;
1208
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 ;
1219
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 ;
1235
1236 ;;; c.by ends here