1 # C/C++ BNF language specification
3 # Copyright (C) 1999, 2000, 2001, 2002 Eric M. Ludlam
5 # Author: Eric M. Ludlam <zappo@gnu.org>
6 # X-RCS: $Id: c.bnf,v 1.59.2.10 2003/04/04 12:19:38 berndl Exp $
8 # c.bnf is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2, or (at your option)
13 # This software is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with GNU Emacs; see the file COPYING. If not, write to the
20 # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 # Boston, MA 02111-1307, USA.
26 %outputfile semantic-c.el
27 %parsetable semantic-toplevel-c-bovine-table
28 %keywordtable semantic-c-keyword-table
29 %languagemode (c-mode c++-mode)
30 %setupfunction semantic-default-c-setup
32 %(setq semantic-expand-nonterminal 'semantic-expand-c-nonterminal
33 semantic-flex-extensions semantic-flex-c-extensions
34 semantic-dependency-include-path semantic-default-c-path
35 semantic-orphaned-member-metaparent-type "struct"
36 semantic-symbol->name-assoc-list
38 (variable . "Variables")
39 (function . "Functions")
40 (include . "Includes"))
41 semantic-symbol->name-assoc-list-for-type-parts
43 (variable . "Attributes")
44 (function . "Methods")
47 imenu-create-index-function 'semantic-create-imenu-index
48 semantic-type-relation-separator-character '("." "->")
49 semantic-command-separation-character ";"
50 document-comment-start "/*"
51 document-comment-line-prefix " *"
52 document-comment-end " */"
53 ;; Semantic navigation inside 'type children
54 senator-step-at-token-ids '(function variable)
57 %token INCLUDE "include"
58 %token DEFINE "define"
59 %token HASH punctuation "#"
60 %token PERIOD punctuation "."
61 %token COLON punctuation ":"
62 %token SEMICOLON punctuation ";"
63 %token STAR punctuation "*"
64 %token AMPERSAND punctuation "&"
65 %token DIVIDE punctuation "/"
66 %token PLUS punctuation "+"
67 %token MINUS punctuation "-"
68 %token BANG punctuation "!"
69 %token EQUAL punctuation "="
70 %token LESS punctuation "<"
71 %token GREATER punctuation ">"
72 %token COMA punctuation ","
73 %token TILDE punctuation "~"
75 %token EXTERN "extern"
76 %put EXTERN summary "Declaration Modifier: extern <type> <name> ..."
77 %token STATIC "static"
78 %put STATIC summary "Declaration Modifier: static <type> <name> ..."
80 %put CONST summary "Declaration Modifier: const <type> <name> ..."
81 %token VOLATILE "volatile"
82 %put VOLATILE summary "Declaration Modifier: volatile <type> <name> ..."
83 %token REGISTER "register"
84 %put REGISTER summary "Declaration Modifier: register <type> <name> ..."
85 %token SIGNED "signed"
86 %put SIGNED summary "Numeric Type Modifier: signed <numeric type> <name> ..."
87 %token UNSIGNED "unsigned"
88 %put UNSIGNED summary "Numeric Type Modifier: unsigned <numeric type> <name> ..."
90 %token INLINE "inline"
91 %put INLINE summary "Function Modifier: inline <return type> <name>(...) {...};"
92 %token VIRTUAL "virtual"
93 %put VIRTUAL summary "Method Modifier: virtual <type> <name>(...) ..."
94 %token MUTABLE "mutable"
95 %put MUTABLE summary "Member Declaration Modifier: mutable <type> <name> ..."
97 %token STRUCT "struct"
98 %put STRUCT summary "Structure Type Declaration: struct [name] { ... };"
100 %put UNION summary "Union Type Declaration: union [name] { ... };"
102 %put ENUM summary "Enumeration Type Declaration: enum [name] { ... };"
103 %token TYPEDEF "typedef"
104 %put TYPEDEF summary "Arbitrary Type Declaration: typedef <typedeclaration> <name>;"
106 %put CLASS summary "Class Declaration: class <name>[:parents] { ... };"
107 %token TYPENAME "typename"
108 %put TYPENAME summary "typename is used to handle a qualified name as a typename;"
109 %token NAMESPACE "namespace"
110 %put NAMESPACE summary "Namespace Declaration: namespace <name> { ... };"
112 %put USING summary "using <namespace>;"
114 # Despite this, this parser can find templates by ignoring the TEMPLATE
115 # keyword, and finding the class/method being templateized.
116 %token TEMPLATE "template"
117 %put TEMPLATE summary "template <class TYPE ...> TYPE_OR_FUNCTION"
120 %put THROW summary "<type> <methoddef> (<method args>) throw (<exception>) ..."
121 %token REENTRANT "reentrant"
122 %put REENTRANT summary "<type> <methoddef> (<method args>) reentrant ..."
124 # Leave these alone for now.
125 %token OPERATOR "operator"
126 %token PUBLIC "public"
127 %token PRIVATE "private"
128 %token PROTECTED "protected"
129 %token FRIEND "friend"
131 # These aren't used for parsing, but is a useful place to describe the keywords.
134 %put {IF ELSE} summary "if (<condition>) { code } [ else { code } ]"
138 %put DO summary " do { code } while (<condition>);"
139 %put WHILE summary "do { code } while (<condition>); or while (<condition>) { code };"
142 %put FOR summary "for(<init>; <condition>; <increment>) { code }"
144 %token SWITCH "switch"
146 %token DEFAULT "default"
147 %put {SWITCH CASE DEFAULT} summary
148 "switch (<variable>) { case <constvalue>: code; ... default: code; }"
150 %token RETURN "return"
151 %put RETURN summary "return <value>;"
154 %put BREAK summary "Non-local exit within a loop or switch (for, do/while, switch): break;"
155 %token CONTINUE "continue"
156 %put CONTINUE summary "Non-local continue within a lool (for, do/while): continue;"
158 %token SIZEOF "sizeof"
159 %put SIZEOF summary "Compile time macro: sizeof(<type or variable>) // size in bytes"
163 %put VOID summary "Built in typeless type: void"
165 %put CHAR summary "Integral Character Type: (0 to 256)"
166 %token WCHAR "wchar_t"
167 %put WCHAR summary "Wide Character Type"
169 %put SHORT summary "Integral Primitive Type: (-32768 to 32767)"
171 %put INT summary "Integral Primitive Type: (-2147483648 to 2147483647)"
173 %put LONG summary "Integral primitive type (-9223372036854775808 to 9223372036854775807)"
175 %put FLOAT summary "Primitive floating-point type (single-precision 32-bit IEEE 754)"
176 %token DOUBLE "double"
177 %put DOUBLE summary "Primitive floating-point type (double-precision 64-bit IEEE 754)"
180 %token UNDERUNDERP "__P"
181 %put UNDERP summary "Common macro to eliminate prototype compatibility on some compilers"
182 %put UNDERUNDERP summary "Common macro to eliminate prototype compatibility on some compilers"
186 # TODO: Klaus Berndl <klaus.berndl@sdm.de>: Is the define here
187 # necessary or even wrong? Is this part not already covered by macro??
196 | codeblock-var-or-fun
197 | type # type is less likely to be used here.
200 extern-c-contents: open-paren
207 extern-c: EXTERN string "\"C\"" semantic-list
208 # Extern C commands which contain a list need to have the
209 # entries of the list extracted, and spliced into the main
210 # list of entries. This must be done via the function
211 # that expands singular nonterminals, such as int x,y;
212 ( extern (EXPANDFULL $3 extern-c-contents) )
213 | EXTERN string "\"C\""
214 # A plain extern "C" call should add something to the token,
215 # but just strip it from the buffer here for now.
219 # Klaus Berndl <klaus.berndl@sdm.de>: At least one-liner should be
220 # parsed correctly! Multi-line macros (every line ends with a
221 # backslash) not being one code-block can not be parsed because
222 # \+newline is flexed as nothing and therefore we can not distinguish
223 # if the lines > 1 belong to the macro or are separated statements!
224 # Maybe we need special backslash recognizing and then better
225 # macro-parsing. For the moment it's goog enough.
226 macro-expression-list : expression macro-expression-list SEMICOLON
233 macro-def : macro-expression-list
240 macro : HASH macro-or-include
244 macro-or-include : DEFINE symbol opt-define-arglist macro-def
249 | INCLUDE system-include
250 ( (substring $2 1 (1- (length $2))) include t nil )
252 ( (read $2) include nil nil )
255 opt-define-arglist : semantic-list
260 # This is used in struct parts.
261 define : HASH DEFINE symbol opt-define-arglist macro-def
268 # In C++, structures can have the same things as classes.
269 # So delete this somday in the figure.
271 #structparts : semantic-list
272 # (EXPANDFULL $1 structsubparts)
275 #structsubparts : open-paren "{"
281 # # sometimes there are defines in structs.
284 unionparts : semantic-list
285 (EXPANDFULL $1 classsubparts)
292 classsubparts : open-paren "{"
296 | class-protection opt-symbol COLON
297 # For QT, they may put a `slot' keyword between the protection
308 opt-class-parents : COLON class-parents opt-template-specifier
314 class-parents : opt-class-protection opt-class-declmods
315 namespace-symbol COMA class-parents
317 | opt-class-protection opt-class-declmods namespace-symbol
321 opt-class-declmods : class-declmods opt-class-declmods
326 class-declmods : VIRTUAL
329 class-protection: PUBLIC
334 opt-class-protection : class-protection
339 namespaceparts : semantic-list
340 (EXPANDFULL $1 namespacesubparts)
343 namespacesubparts : open-paren "{"
350 | class-protection COLON
352 # In C++, this label in a classsubpart represents
353 # PUBLIC or PRIVATE bits. Ignore them for now.
359 enumparts : semantic-list
360 (EXPANDFULL $1 enumsubparts)
363 enumsubparts : symbol opt-assign
364 ( $1 variable "int" ,$2 (ASSOC const t) nil)
378 opt-class-declmods : symbol declespec semantic-list
383 typesimple : struct-or-class opt-name opt-template-specifier
384 opt-class-parents semantic-list
386 (let ((semantic-c-classname (cons (car ,$2) (car ,$1))))
387 (EXPANDFULL $5 classsubparts))
389 (ASSOC 'template-specifier $3)
391 | struct-or-class opt-name opt-template-specifier opt-class-parents
392 ( ,$2 type ,$1 nil $4
393 (ASSOC 'template-specifier $3)
395 | UNION opt-name unionparts
396 ( ,$2 type $1 $3 nil nil nil )
397 | ENUM opt-name enumparts
398 ( ,$2 type $1 $3 nil nil nil )
399 # Klaus Berndl <klaus.berndl@sdm.de>: a typedef can be a typeformbase
400 # with all this declmods stuff.
401 | TYPEDEF declmods typeformbase cv-declmods typedef-symbol-list
402 ## We put the type this typedef renames into PARENT
403 ## but will move it in the expand function.
404 ( $5 type $1 nil $3 nil nil )
407 typedef-symbol-list : typedefname COMA typedef-symbol-list
413 # TODO: Klaus Berndl <klaus.berndl@sdm.de>: symbol -> namespace-symbol?!
414 # Answer: Probably symbol is correct here!
415 typedefname : opt-stars symbol opt-bits opt-array
419 struct-or-class: STRUCT
423 type : typesimple SEMICOLON
425 # named namespaces like "namespace XXX {"
426 | NAMESPACE symbol namespaceparts
427 ( $2 type $1 $3 nil nil nil )
428 # unnamed namespaces like "namespace {"
429 | NAMESPACE namespaceparts
430 ( "unnamed" type $1 $2 nil nil nil )
433 # Klaus Berndl <klaus.berndl@sdm.de>:
434 # We must parse "using namespace XXX" too
436 # Using is vaguely like an include statement in the named portions
437 # of the code. We should probably specify a new token type for this.
438 using : USING typeformbase SEMICOLON
440 | USING NAMESPACE typeformbase SEMICOLON
444 template : TEMPLATE template-specifier opt-friend template-definition
445 ( ,(semantic-c-reconstitute-template $4 ,$2) )
452 opt-template-specifier : template-specifier
458 template-specifier : LESS template-specifier-types GREATER
462 template-specifier-types : template-var template-specifier-type-list
467 template-specifier-type-list : COMA template-specifier-types
473 #template-var : template-type opt-stars opt-template-equal
474 # ( ,(cons (concat (car $1) (make-string (car ,$2) ?*))
476 ## Klaus Berndl <klaus.berndl@sdm.de>: for template-types the
477 ## template-var can also be literals or constants.
478 ## Example: map<ClassX, ClassY, 10> map_size10_var; This parses also
479 ## template<class T, 0> which is nonsense but who cares....
487 # Klaus Berndl <klaus.berndl@sdm.de>: The following handles all
488 # template-vars of template-definitions
489 template-type opt-template-equal
490 ( ,(cons (car $1) (cdr $1)) )
491 # Klaus Berndl <klaus.berndl@sdm.de>: for template-types the
492 # template-var can also be literals or constants.
493 # Example: map<ClassX, ClassY, 10> map_size10_var; This parses also
494 # template<class T, 0> which is nonsense but who cares....
499 # Klaus Berndl <klaus.berndl@sdm.de>: In template-types arguments can
500 # be any symbols with optional adress-operator (&) and optional
501 # dereferencing operator (*)
502 # Example map<ClassX, ClassY, *size_var_ptr> sized_map_var.
503 | opt-stars opt-ref namespace-symbol
507 opt-template-equal : EQUAL symbol LESS template-specifier-types GREATER
512 template-type : CLASS symbol
513 ( $2 type "class" nil nil)
515 ( $2 type "struct" nil nil)
516 # TODO: Klaus Berndl <klaus.berndl@sdm.de>: For the moment is is ok,
517 # that we parse the C++ keyword typename as a class....
519 ( $2 type "class" nil nil)
520 # Klaus Berndl <klaus.berndl@sdm.de>: template-types can be all
521 # flavors of variable-args but here the argument is ignored, only the
522 # type stuff is needed.
523 | declmods typeformbase cv-declmods opt-stars
524 opt-ref variablearg-opt-name
525 ( (car $2) type nil nil
526 (ASSOC const (if (member "const" (append $1 $3)) t nil)
527 typemodifiers (delete "const" (append $1 $3))
534 template-definition : type
540 opt-stars : STAR opt-starmod opt-stars
546 opt-starmod : STARMOD opt-starmod
547 ( ,(cons (,car ,$1) $2) )
555 declmods : DECLMOD declmods
556 ( ,(cons ,(car ,$1) $2 ) )
566 # Klaus Berndl <klaus.berndl@sdm.de>: IMHO signed and unsigned are not
567 # decl-modes but these are only valid for some buildin-types like
568 # short, int etc... whereas "real" declmods are valid for all types,
569 # buildin and user-defined!
575 # Klaus Berndl <klaus.berndl@sdm.de>: There can be a few cases where
576 # TYPENAME is not allowed in C++-syntax but better than not
577 # recognizing the allowed situations.
580 # This is a hack in case we are in a class.
584 metadeclmod : METADECLMOD
594 cv-declmods : CVDECLMOD cv-declmods
595 ( ,(cons ,(car ,$1) $2 ) )
602 METADECLMOD : VIRTUAL
606 # C++: A type can be modified into a reference by "&"
613 typeformbase : typesimple
623 # | symbol template-specifier
624 # ( $1 type "class" )
625 # | namespace-symbol opt-stars opt-template-specifier
626 # | namespace-symbol opt-template-specifier
638 # Klaus Berndl <klaus.berndl@sdm.de>: builtintype-types was builtintype
639 builtintype-types : VOID
641 # Klaus Berndl <klaus.berndl@sdm.de>: Added WCHAR
646 ( (concat $1 " " $2) )
650 ( (concat $1 " " $2) )
651 # TODO: Klaus Berndl <klaus.berndl@sdm.de>: Is there a long long, i
654 ( (concat $1 " " $2) )
658 builtintype : signedmod builtintype-types
659 ( (concat (car $1) " " (car $2)) )
662 # Klaus Berndl <klaus.berndl@sdm.de>: unsigned is synonym for unsigned
663 # int and signed for signed int. To make this confusing stuff clear we
666 ( (concat (car $1) " int") )
669 # Klaus Berndl <klaus.berndl@sdm.de>: This parses also nonsense like
670 # "const volatile int const volatile const const volatile a ..." but
671 # IMHO nobody writes such code. Normaly we shoud define a rule like
672 # typeformbase-mode which exactly defines the different allowed cases
673 # and combinations of declmods (minus the CVDECLMOD) typeformbase and
674 # cv-declmods so we could recognize more invalid code but IMHO this is
675 # not worth the effort...
676 codeblock-var-or-fun : declmods typeformbase declmods
677 opt-ref var-or-func-decl
678 ( ,(semantic-c-reconstitute-token ,$5 $1 $2 ) )
681 var-or-fun : codeblock-var-or-fun
683 # it is possible for a function to not have a type, and
684 # it is then assumed to be an int. How annoying.
685 # In C++, this could be a constructor or a destructor.
686 # Even more annoying. Only ever do this for regular
687 # top-level items. Ignore this problem in code blocks
688 # so that we don't have to deal with regular code
689 # being erroneously converted into types.
690 | declmods var-or-func-decl
691 ( ,(semantic-c-reconstitute-token ,$2 $1 nil ) )
694 var-or-func-decl : func-decl
700 func-decl : opt-stars opt-class opt-destructor functionname
701 opt-template-specifier
704 opt-post-fcn-modifiers
709 ;; Extra stuff goes in here.
710 ;; Continue with the stuff we found in
712 $2 $3 $7 $9 $8 ,$1 ,$11)
715 var-decl : varnamelist SEMICOLON
726 # Klaus Berndl <klaus.berndl@sdm.de>: symbol -> namespace-symbol
727 opt-initializers: COLON namespace-symbol semantic-list opt-initializers
728 | COMA namespace-symbol semantic-list opt-initializers
732 opt-post-fcn-modifiers : post-fcn-modifiers opt-post-fcn-modifiers
738 post-fcn-modifiers : REENTRANT
742 opt-throw : THROW semantic-list
743 ( EXPAND $2 throw-exception-list )
747 # Is this true? I don't actually know.
748 throw-exception-list : namespace-symbol COMA throw-exception-list
749 ( ,(cons (car $1) $3) )
750 | namespace-symbol close-paren ")"
752 | open-paren "(" throw-exception-list
758 opt-bits : COLON number
764 opt-array : semantic-list "\\[.*\\]$" opt-array
765 # Eventually we want to replace the 1 below with a size
767 ( (cons 1 (car ,$2) ) )
772 opt-assign : EQUAL expression
778 opt-restrict : symbol "\\<\\(__\\)?restrict\\>"
783 # Klaus Berndl <klaus.berndl@sdm.de>: symbol -> namespace-symbol?! I
784 # think so. Can be that then also some invalid C++-syntax is parsed
785 # but this is better than not parsing valid syntax.
786 varname : opt-stars opt-restrict namespace-symbol opt-bits opt-array opt-assign
787 ( ,$3 ,$1 ,$4 ,$5 ,$6 )
790 # I should store more in this def, but leave it simple for now. Klaus
791 # Berndl <klaus.berndl@sdm.de>: const and volatile can be written
793 variablearg : declmods typeformbase cv-declmods opt-ref variablearg-opt-name
794 ( (list $5) variable $2 nil
795 (ASSOC const (if (member "const" (append $1 $3)) t nil)
796 typemodifiers (delete "const" (append $1 $3))
803 variablearg-opt-name: varname
805 # Klaus Berndl <klaus.berndl@sdm.de>: This allows variableargs without
806 # a arg-name being parsed correct even if there several pointers (*)
808 ( "" ,$1 nil nil nil )
811 varnamelist : varname COMA varnamelist
817 # Klaus Berndl <klaus.berndl@sdm.de>:
818 # Is necessary to parse stuff like
819 # class list_of_facts : public list<fact>, public entity
821 # list <shared_ptr<item> >::const_iterator l;
822 # Parses also invalid(?) and senseless(?) c++-syntax like
823 # symbol<template-spec>::symbol1<template-spec1>::test_iterator
824 # but better parsing too much than to less
825 namespace-symbol : symbol opt-template-specifier COLON COLON namespace-symbol
826 ( (concat $1 "::" (car $5)) )
827 | symbol opt-template-specifier
831 #namespace-symbol : symbol COLON COLON namespace-symbol
832 # ( (concat $1 "::" (car $4)) )
837 namespace-opt-class : symbol COLON COLON namespace-opt-class
838 ( (concat $1 "::" (car $4)) )
839 # Klaus Berndl <klaus.berndl@sdm.de>: We must recognize
840 # template-specifiers here so we can parse correctly the
841 # method-implementations of template-classes outside the
842 # template-class-declaration
843 # Example: TemplateClass1<T>::method_1(...)
844 | symbol opt-template-specifier COLON COLON
848 # Klaus Berndl <klaus.berndl@sdm.de>: The opt-class of a func-decl
849 # must be able to recognize opt-classes with namespaces, e.g.
850 # Test1::Test2::classname::
851 opt-class : namespace-opt-class
857 opt-destructor : TILDE
863 arg-list : semantic-list "^(" knr-arguments
866 (EXPANDFULL $1 arg-sub-list)
867 | semantic-list "^(void)$"
871 knr-arguments : variablearg SEMICOLON knr-arguments
872 ( ,(cons (car (semantic-expand-c-nonterminal ,$1) ) ,$3) )
873 | variablearg SEMICOLON
874 ( (car (semantic-expand-c-nonterminal ,$1)) )
877 arg-sub-list : variablearg
879 | PERIOD PERIOD PERIOD close-paren ")"
889 operatorsym : LESS LESS
903 # Klaus Berndl <klaus.berndl@sdm.de>: We have to parse also
904 # operator() and operator[]
907 | semantic-list "\\[\\]"
919 functionname : OPERATOR operatorsym
925 fun-or-proto-end: SEMICOLON
929 # Here is an anoying feature of C++ pure virtual methods
930 | EQUAL number "^0$" SEMICOLON
934 type-cast : semantic-list
935 ( EXPAND $1 type-cast-list )
938 type-cast-list : open-paren typeformbase close-paren
941 # Klaus Berndl <klaus.berndl@sdm.de>: symbol -> namespace-symbol!
942 function-call: namespace-symbol semantic-list
945 string-seq : string string-seq
946 ( (concat $1 (car $2)) )
951 # Use expression for parsing only. Don't actually return anything
952 # for now. Hopefully we can fix this later.
954 ( (identity start) (identity end) )
956 ( (identity start) (identity end) )
957 # Klaus Berndl <klaus.berndl@sdm.de>: symbol -> namespace-symbol!
959 ( (identity start) (identity end) )
960 # Klaus Berndl <klaus.berndl@sdm.de>: C/C++ allows sequences of
961 # strings which are concatenated by the precompiler to one string
963 ( (identity start) (identity end))
964 | type-cast expression # A cast to some other type
965 ( (identity start) (identity end) )
967 ( (identity start) (identity end) )
968 | punctuation "[-+*/%^|&]" expression
969 ( (identity start) (identity end) )