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