1 ;;; c.by -- LL grammar for C/C++ language specification
3 ;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Eric M. Ludlam
4 ;; Copyright (C) 2002, 2003 David Ponce
6 ;; Author: Eric M. Ludlam <zappo@gnu.org>
7 ;; David Ponce <david@dponce.com>
8 ;; Klaus Berndl <klaus.berndl@sdm.de>
10 ;; X-RCS: $Id: c.by,v 1.1 2007-11-26 15:11:51 michaels Exp $
12 ;; c.by is free software; you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 2, or (at your option)
17 ;; This software is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ;; GNU General Public License for more details.
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs; see the file COPYING. If not, write to the
24 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25 ;; Boston, MA 02110-1301, USA.
28 %package semantic-c-by
30 %languagemode c-mode c++-mode
34 %token INCLUDE "include"
36 %token <punctuation> HASH "\\`[#]\\'"
37 %token <punctuation> PERIOD "\\`[.]\\'"
38 %token <punctuation> COLON "\\`[:]\\'"
39 %token <punctuation> SEMICOLON "\\`[;]\\'"
40 %token <punctuation> STAR "\\`[*]\\'"
41 %token <punctuation> AMPERSAND "\\`[&]\\'"
42 %token <punctuation> DIVIDE "\\`[/]\\'"
43 %token <punctuation> PLUS "\\`[+]\\'"
44 %token <punctuation> MINUS "\\`[-]\\'"
45 %token <punctuation> BANG "\\`[!]\\'"
46 %token <punctuation> EQUAL "\\`[=]\\'"
47 %token <punctuation> LESS "\\`[<]\\'"
48 %token <punctuation> GREATER "\\`[>]\\'"
49 %token <punctuation> COMA "\\`[,]\\'"
50 %token <punctuation> TILDE "\\`[~]\\'"
51 %token <punctuation> MOD "\\`[%]\\'"
52 %token <punctuation> HAT "\\`\\^\\'"
53 %token <punctuation> OR "\\`[|]\\'"
54 %token <punctuation> OPSTART "[-+*/%^|&]"
55 %token <string> C "\"C\""
56 %token <number> ZERO "^0$"
57 %token <symbol> RESTRICT "\\<\\(__\\)?restrict\\>"
58 %token <open-paren> LPAREN "("
59 %token <close-paren> RPAREN ")"
60 %token <open-paren> LBRACE "{"
61 %token <close-paren> RBRACE "}"
62 %token <semantic-list> BRACK_BLCK "\\[.*\\]$"
63 %token <semantic-list> PAREN_BLCK "^("
64 %token <semantic-list> BRACE_BLCK "^{"
65 %token <semantic-list> VOID_BLCK "^(void)$"
66 %token <semantic-list> PARENS "()"
67 %token <semantic-list> BRACKETS "\\[\\]"
69 %token EXTERN "extern"
70 %put EXTERN summary "Declaration Modifier: extern <type> <name> ..."
71 %token STATIC "static"
72 %put STATIC summary "Declaration Modifier: static <type> <name> ..."
74 %put CONST summary "Declaration Modifier: const <type> <name> ..."
75 %token VOLATILE "volatile"
76 %put VOLATILE summary "Declaration Modifier: volatile <type> <name> ..."
77 %token REGISTER "register"
78 %put REGISTER summary "Declaration Modifier: register <type> <name> ..."
79 %token SIGNED "signed"
80 %put SIGNED summary "Numeric Type Modifier: signed <numeric type> <name> ..."
81 %token UNSIGNED "unsigned"
82 %put UNSIGNED summary "Numeric Type Modifier: unsigned <numeric type> <name> ..."
84 %token INLINE "inline"
85 %put INLINE summary "Function Modifier: inline <return type> <name>(...) {...};"
86 %token VIRTUAL "virtual"
87 %put VIRTUAL summary "Method Modifier: virtual <type> <name>(...) ..."
88 %token MUTABLE "mutable"
89 %put MUTABLE summary "Member Declaration Modifier: mutable <type> <name> ..."
91 %token STRUCT "struct"
92 %put STRUCT summary "Structure Type Declaration: struct [name] { ... };"
94 %put UNION summary "Union Type Declaration: union [name] { ... };"
96 %put ENUM summary "Enumeration Type Declaration: enum [name] { ... };"
97 %token TYPEDEF "typedef"
98 %put TYPEDEF summary "Arbitrary Type Declaration: typedef <typedeclaration> <name>;"
100 %put CLASS summary "Class Declaration: class <name>[:parents] { ... };"
101 %token TYPENAME "typename"
102 %put TYPENAME summary "typename is used to handle a qualified name as a typename;"
103 %token NAMESPACE "namespace"
104 %put NAMESPACE summary "Namespace Declaration: namespace <name> { ... };"
106 %put USING summary "using <namespace>;"
108 ;; Despite this, this parser can find templates by ignoring the TEMPLATE
109 ;; keyword, and finding the class/method being templateized.
110 %token TEMPLATE "template"
111 %put TEMPLATE summary "template <class TYPE ...> TYPE_OR_FUNCTION"
114 %put THROW summary "<type> <methoddef> (<method args>) throw (<exception>) ..."
115 %token REENTRANT "reentrant"
116 %put REENTRANT summary "<type> <methoddef> (<method args>) reentrant ..."
119 %put { TRY CATCH } summary "try { <body> } catch { <catch code> }"
121 ;; Leave these alone for now.
122 %token OPERATOR "operator"
123 %token PUBLIC "public"
124 %token PRIVATE "private"
125 %token PROTECTED "protected"
126 %token FRIEND "friend"
128 ;; These aren't used for parsing, but is a useful place to describe the keywords.
131 %put {IF ELSE} summary "if (<condition>) { code } [ else { code } ]"
135 %put DO summary " do { code } while (<condition>);"
136 %put WHILE summary "do { code } while (<condition>); or while (<condition>) { code };"
139 %put FOR summary "for(<init>; <condition>; <increment>) { code }"
141 %token SWITCH "switch"
143 %token DEFAULT "default"
144 %put {SWITCH CASE DEFAULT} summary
145 "switch (<variable>) { case <constvalue>: code; ... default: code; }"
147 %token RETURN "return"
148 %put RETURN summary "return <value>;"
151 %put BREAK summary "Non-local exit within a loop or switch (for, do/while, switch): break;"
152 %token CONTINUE "continue"
153 %put CONTINUE summary "Non-local continue within a loop (for, do/while): continue;"
155 %token SIZEOF "sizeof"
156 %put SIZEOF summary "Compile time macro: sizeof(<type or variable>) // size in bytes"
160 %put VOID summary "Built in typeless type: void"
162 %put CHAR summary "Integral Character Type: (0 to 256)"
163 %token WCHAR "wchar_t"
164 %put WCHAR summary "Wide Character Type"
166 %put SHORT summary "Integral Primitive Type: (-32768 to 32767)"
168 %put INT summary "Integral Primitive Type: (-2147483648 to 2147483647)"
170 %put LONG summary "Integral primitive type (-9223372036854775808 to 9223372036854775807)"
172 %put FLOAT summary "Primitive floating-point type (single-precision 32-bit IEEE 754)"
173 %token DOUBLE "double"
174 %put DOUBLE summary "Primitive floating-point type (double-precision 64-bit IEEE 754)"
176 %put BOOL summary "Primitive boolean type"
179 %token UNDERUNDERP "__P"
180 %put UNDERP summary "Common macro to eliminate prototype compatibility on some compilers"
181 %put UNDERUNDERP summary "Common macro to eliminate prototype compatibility on some compilers"
184 %token __ATTRIBUTE__ "__attribute__"
185 %put __ATTRIBUTE__ summary "<cdecl> __attribute__ ((<attributeoption>))"
192 ;; TODO: Klaus Berndl: Is the define here necessary or even wrong?
193 ;; Is this part not already covered by macro??
203 | codeblock-var-or-fun
204 | type ;; type is less likely to be used here.
216 : EXTERN C semantic-list
217 ;; Extern C commands which contain a list need to have the
218 ;; entries of the list extracted, and spliced into the main
219 ;; list of entries. This must be done via the function
220 ;; that expands singular nonterminals, such as int x,y;
221 (TAG "C" 'extern :members (EXPANDFULL $3 extern-c-contents) )
223 ;; A plain extern "C" call should add something to the token,
224 ;; but just strip it from the buffer here for now.
228 ;; Klaus Berndl: At least one-liner should be parsed correctly!
229 ;; Multi-line macros (every line ends with a '\') not being one
230 ;; code-block can not be parsed because \+newline is flexed as nothing
231 ;; and therefore we can not distinguish if the lines > 1 belong to the
232 ;; macro or are separated statements! Maybe we need special backslash
233 ;; recognizing and then better macro-parsing. For the moment it's goog
235 macro-expression-list
236 : expression macro-expression-list SEMICOLON
243 : macro-expression-list
251 : spp-macro-def opt-define-arglist macro-def
252 (VARIABLE-TAG $1 nil $3 :constant-flag t )
253 | HASH macro-or-include
258 : INCLUDE system-include
259 (INCLUDE-TAG (substring $2 1 (1- (length $2))) t)
261 (INCLUDE-TAG (read $2) nil )
270 ;; This is used in struct parts.
272 : spp-macro-def opt-define-arglist macro-def
273 (VARIABLE-TAG $1 nil $3 :constant-flag t)
278 ;; In C++, structures can have the same things as classes.
279 ;; So delete this somday in the figure.
281 ;;structparts : semantic-list
282 ;; (EXPANDFULL $1 structsubparts)
285 ;;structsubparts : LBRACE
291 ;; ;; sometimes there are defines in structs.
296 (EXPANDFULL $1 classsubparts)
309 | class-protection opt-symbol COLON
310 ;; For QT, they may put a `slot' keyword between the protection
312 (TAG (car $1) 'label)
321 : COLON class-parents opt-template-specifier
328 : opt-class-protection opt-class-declmods
329 namespace-symbol COMA class-parents
331 | opt-class-protection opt-class-declmods namespace-symbol
336 : class-declmods opt-class-declmods
359 (EXPANDFULL $1 namespacesubparts)
370 | class-protection COLON
371 (TAG (car $1) 'label)
372 ;; In C++, this label in a classsubpart represents
373 ;; PUBLIC or PRIVATE bits. Ignore them for now.
381 (EXPANDFULL $1 enumsubparts)
386 (VARIABLE-TAG $1 "int" (car $2) :constant-flag t )
402 : symbol declespec semantic-list
408 : struct-or-class opt-class opt-name opt-template-specifier
409 opt-class-parents semantic-list
410 (TYPE-TAG (car $3) (car $1)
411 (let ((semantic-c-classname (cons (car ,$3) (car ,$1))))
412 (EXPANDFULL $6 classsubparts))
414 :template-specifier $4
416 | struct-or-class opt-class opt-name opt-template-specifier
418 (TYPE-TAG (car $3) (car $1) nil $5
419 :template-specifier $4
422 | UNION opt-class opt-name unionparts
423 (TYPE-TAG (car $3) $1 $4 nil
425 | ENUM opt-class opt-name enumparts
426 (TYPE-TAG (car $3) $1 $4 nil
428 ;; Klaus Berndl: a typedef can be a typeformbase with all this
430 | TYPEDEF declmods typeformbase cv-declmods typedef-symbol-list
431 ;;;; We put the type this typedef renames into PARENT
432 ;;;; but will move it in the expand function.
433 (TYPE-TAG $5 $1 nil (list $3) )
437 : typedefname COMA typedef-symbol-list
443 ;; TODO: Klaus Berndl: symbol -> namespace-symbol?! Answer: Probably
444 ;; symbol is correct here!
446 : opt-stars symbol opt-bits opt-array
456 : typesimple opt-attribute SEMICOLON
458 ;; named namespaces like "namespace XXX {"
459 | NAMESPACE symbol namespaceparts
460 (TYPE-TAG $2 $1 $3 nil )
461 ;; unnamed namespaces like "namespace {"
462 | NAMESPACE namespaceparts
463 (TYPE-TAG "unnamed" $1 $2 nil )
467 : __ATTRIBUTE__ semantic-list
473 ;; Klaus Berndl: We must parse "using namespace XXX" too
475 ;; Using is vaguely like an include statement in the named portions
476 ;; of the code. We should probably specify a new token type for this.
478 : USING typeformbase SEMICOLON
480 | USING NAMESPACE typeformbase SEMICOLON
485 : TEMPLATE template-specifier opt-friend template-definition
486 ( ,(semantic-c-reconstitute-template $4 ,$2) )
494 opt-template-specifier
502 : LESS template-specifier-types GREATER
506 template-specifier-types
507 : template-var template-specifier-type-list
512 template-specifier-type-list
513 : COMA template-specifier-types
520 ;; : template-type opt-stars opt-template-equal
521 ;; ( ,(cons (concat (car $1) (make-string (car ,$2) ?*))
523 ;; ;; Klaus Berndl: for template-types the template-var can also be
524 ;; ;; literals or constants. Example: map<ClassX, ClassY, 10>
525 ;; ;; map_size10_var; This parses also template<class T, 0> which is
526 ;; ;; nonsense but who cares....
535 ;; Klaus Berndl: The following handles all template-vars of
536 ;; template-definitions
537 template-type opt-template-equal
538 ( ,(cons (car $1) (cdr $1)) )
539 ;; Klaus Berndl: for template-types the template-var can also be
540 ;; literals or constants.
541 ;; Example: map<ClassX, ClassY, 10> map_size10_var; This parses also
542 ;; template<class T, 0> which is nonsense but who cares....
547 ;; Klaus Berndl: In template-types arguments can be any symbols with
548 ;; optional address-operator (&) and optional dereferencing operator
549 ;; (*). Example map<ClassX, ClassY, *size_var_ptr> sized_map_var.
550 | opt-stars opt-ref namespace-symbol
555 : EQUAL symbol LESS template-specifier-types GREATER
565 (TYPE-TAG $2 "class" nil nil )
567 (TYPE-TAG $2 "struct" nil nil )
568 ;; TODO: Klaus Berndl: For the moment is is ok, that we parse the C++
569 ;; keyword typename as a class....
571 (TYPE-TAG $2 "class" nil nil)
572 ;; Klaus Berndl: template-types can be all flavors of variable-args
573 ;; but here the argument is ignored, only the type stuff is needed.
574 | declmods typeformbase cv-declmods opt-stars
575 opt-ref variablearg-opt-name
576 (TYPE-TAG (car $2) nil nil nil
577 :constant-flag (if (member "const" (append $1 $3)) t nil)
578 :typemodifiers (delete "const" (append $1 $3))
592 : STAR opt-starmod opt-stars
599 : STARMOD opt-starmod
600 ( ,(cons (,car ,$1) $2) )
611 ( ,(cons ,(car ,$1) $2 ) )
622 ;; Klaus Berndl: IMHO signed and unsigned are not decl-modes but
623 ;; these are only valid for some buildin-types like short, int
624 ;; etc... whereas "real" declmods are valid for all types, buildin
625 ;; and user-defined! SIGNED UNSIGNED
629 ;; Klaus Berndl: There can be a few cases where TYPENAME is not
630 ;; allowed in C++-syntax but better than not recognizing the allowed
634 ;; This is a hack in case we are in a class.
651 : CVDECLMOD cv-declmods
652 ( ,(cons ,(car ,$1) $2 ) )
664 ;; C++: A type can be modified into a reference by "&"
676 (TYPE-TAG $2 $1 nil nil )
678 (TYPE-TAG $2 $1 nil nil )
680 (TYPE-TAG $2 $1 nil nil )
683 ;;| symbol template-specifier
684 ;; ( $1 type "class" )
685 ;;| namespace-symbol opt-stars opt-template-specifier
686 ;;| namespace-symbol opt-template-specifier
688 (TYPE-TAG (car $1) "class" nil nil)
698 ;; Klaus Berndl: builtintype-types was builtintype
702 ;; Klaus Berndl: Added WCHAR
705 ( (concat $1 " " $2) )
709 ( (concat $1 " " $2) )
714 ( (concat $1 " " $2) )
715 ;; TODO: Klaus Berndl: Is there a long long, i think so?!
717 ( (concat $1 " " $2) )
722 : signedmod builtintype-types
723 ( (concat (car $1) " " (car $2)) )
726 ;; Klaus Berndl: unsigned is synonym for unsigned int and signed for
727 ;; signed int. To make this confusing stuff clear we add here the
730 ( (concat (car $1) " int") )
733 ;; Klaus Berndl: This parses also nonsense like "const volatile int
734 ;; const volatile const const volatile a ..." but IMHO nobody writes
735 ;; such code. Normaly we shoud define a rule like typeformbase-mode
736 ;; which exactly defines the different allowed cases and combinations
737 ;; of declmods (minus the CVDECLMOD) typeformbase and cv-declmods so
738 ;; we could recognize more invalid code but IMHO this is not worth the
741 : declmods typeformbase declmods
742 opt-ref var-or-func-decl
743 ( ,(semantic-c-reconstitute-token ,$5 $1 $2 ) )
747 : codeblock-var-or-fun
749 ;; it is possible for a function to not have a type, and
750 ;; it is then assumed to be an int. How annoying.
751 ;; In C++, this could be a constructor or a destructor.
752 ;; Even more annoying. Only ever do this for regular
753 ;; top-level items. Ignore this problem in code blocks
754 ;; so that we don't have to deal with regular code
755 ;; being erroneously converted into types.
756 | declmods var-or-func-decl
757 ( ,(semantic-c-reconstitute-token ,$2 $1 nil ) )
768 : opt-stars opt-class opt-destructor functionname
769 opt-template-specifier
772 opt-post-fcn-modifiers
777 ;; Extra stuff goes in here.
778 ;; Continue with the stuff we found in
780 $2 $3 $7 $9 $8 ,$1 ,$11 )
781 | opt-stars opt-class opt-destructor functionname
782 opt-template-specifier
784 ;; arg-list - - ini this case, a try implies a fcn.
785 opt-post-fcn-modifiers
790 ;; Extra stuff goes in here.
791 ;; Continue with the stuff we found in
793 $2 $3 nil $8 $7 ,$1 ,$10 )
797 : varnamelist SEMICOLON
809 ;; Klaus Berndl: symbol -> namespace-symbol
811 : COLON namespace-symbol semantic-list opt-initializers
812 | COMA namespace-symbol semantic-list opt-initializers
816 opt-post-fcn-modifiers
817 : post-fcn-modifiers opt-post-fcn-modifiers
829 : THROW semantic-list
830 ( EXPAND $2 throw-exception-list )
834 ;; Is this true? I don't actually know.
836 : namespace-symbol COMA throw-exception-list
837 ( ,(cons (car $1) $3) )
838 | namespace-symbol RPAREN
842 | LPAREN throw-exception-list
856 : BRACK_BLCK opt-array
857 ;; Eventually we want to replace the 1 below with a size
859 ( (cons 1 (car ,$2) ) )
876 ;; Klaus Berndl: symbol -> namespace-symbol?! I think so. Can be that
877 ;; then also some invalid C++-syntax is parsed but this is better than
878 ;; not parsing valid syntax.
880 : opt-stars opt-restrict namespace-symbol opt-bits opt-array opt-assign
881 ( ,$3 ,$1 ,$4 ,$5 ,$6 )
884 ;; I should store more in this def, but leave it simple for now.
885 ;; Klaus Berndl: const and volatile can be written after the type!
887 : declmods typeformbase cv-declmods opt-ref variablearg-opt-name
888 ( VARIABLE-TAG (list $5) $2 nil
889 :constant-flag (if (member "const" (append $1 $3)) t nil)
890 :typemodifiers (delete "const" (append $1 $3))
898 ;; Klaus Berndl: This allows variableargs without a arg-name being
899 ;; parsed correct even if there several pointers (*)
901 ( "" ,$1 nil nil nil )
905 : varname COMA varnamelist
911 ;; Klaus Berndl: Is necessary to parse stuff like
912 ;; class list_of_facts : public list<fact>, public entity
914 ;; list <shared_ptr<item> >::const_iterator l;
915 ;; Parses also invalid(?) and senseless(?) c++-syntax like
916 ;; symbol<template-spec>::symbol1<template-spec1>::test_iterator
917 ;; but better parsing too much than to less
919 : symbol opt-template-specifier COLON COLON namespace-symbol
920 ( (concat $1 "::" (car $5)) )
921 | symbol opt-template-specifier
926 ;; : symbol COLON COLON namespace-symbol
927 ;; ( (concat $1 "::" (car $4)) )
933 : symbol COLON COLON namespace-opt-class
934 ( (concat $1 "::" (car $4)) )
935 ;; Klaus Berndl: We must recognize template-specifiers here so we can
936 ;; parse correctly the method-implementations of template-classes
937 ;; outside the template-class-declaration Example:
938 ;; TemplateClass1<T>::method_1(...)
939 | symbol opt-template-specifier COLON COLON
943 ;; Klaus Berndl: The opt-class of a func-decl must be able to
944 ;; recognize opt-classes with namespaces, e.g.
945 ;; Test1::Test2::classname::
947 : namespace-opt-class
961 : PAREN_BLCK knr-arguments
964 (EXPANDFULL $1 arg-sub-list)
970 : variablearg SEMICOLON knr-arguments
971 ( ,(cons (car (semantic-expand-c-tag ,$1) ) ,$3) )
972 | variablearg SEMICOLON
973 ( (car (semantic-expand-c-tag ,$1)) )
979 | PERIOD PERIOD PERIOD RPAREN
980 (VARIABLE-TAG "..." "vararg" nil)
992 | GREATER GREATER EQUAL
1020 | MINUS GREATER STAR
1037 | AMPERSAND AMPERSAND
1049 ;; HAT EQUAL seems to have a really unpleasant result and
1050 ;; breaks everything after it. Leave it at the end, though it
1051 ;; doesn't seem to work.
1058 : OPERATOR operatorsym
1061 ( EXPAND $1 function-pointer )
1067 : LPAREN STAR symbol RPAREN
1072 : opt-attribute SEMICOLON
1076 ;; Here is an anoying feature of C++ pure virtual methods
1077 | EQUAL ZERO SEMICOLON
1078 ( :pure-virtual-flag )
1084 : TRY opt-initializers BRACE_BLCK fun-try-several-catches
1088 fun-try-several-catches
1089 : CATCH PAREN_BLCK BRACE_BLCK fun-try-several-catches
1091 | CATCH BRACE_BLCK fun-try-several-catches
1099 ( EXPAND $1 type-cast-list )
1103 : open-paren typeformbase close-paren
1106 ;; Klaus Berndl: symbol -> namespace-symbol!
1108 : namespace-symbol PERIOD function-call ;; method call
1109 | namespace-symbol MINUS GREATER function-call ;;method call
1110 | namespace-symbol semantic-list
1115 ( (concat $1 (car $2)) )
1120 ;; Use expression for parsing only. Don't actually return anything
1121 ;; for now. Hopefully we can fix this later.
1124 ( (identity start) (identity end) )
1126 ( (identity start) (identity end) )
1127 ;; Klaus Berndl: symbol -> namespace-symbol!
1129 ( (identity start) (identity end) )
1130 ;; Klaus Berndl: C/C++ allows sequences of strings which are
1131 ;; concatenated by the precompiler to one string
1133 ( (identity start) (identity end) )
1134 | type-cast expression ;; A cast to some other type
1135 ( (identity start) (identity end) )
1137 ( (identity start) (identity end) )
1138 | OPSTART expression
1139 ( (identity start) (identity end) )