1. xemacs
  2. semantic

Source

semantic / c.bnf

Diff from to

File c.bnf

-# C & C++ BNF language specification
+# C/C++ BNF language specification
 #
-# Copyright (C) 1999, 2000, 2001 Eric M. Ludlam
+# Copyright (C) 1999, 2000, 2001, 2002 Eric M. Ludlam
 #
 # Author: Eric M. Ludlam <zappo@gnu.org>
 # X-RCS: $Id$
 # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 # Boston, MA 02111-1307, USA.
 #
-# $Log$
-# Revision 1.37  2001/06/03 14:01:13  zappo
-# Multi-inheritance for classes.
-# Structs like classes for C++.
-# No ; on name spaces.
-# Throws for methods.
-# (Bugs & patches from "Jesper Nordenberg" <mayhem@home.se>
-# and Norbert Lindlbauer <Norbert_Lindlbauer@betaresearch.de>)
-#
-# Revision 1.36  2001/05/25 01:12:10  zappo
-# (expression): Added string.
-#
-# Revision 1.35  2001/05/09 03:25:17  zappo
-# Added inline method support.
-# Store protection elements
-# Change enum parts to be integer variables.
-#
-# Revision 1.34  2001/05/01 16:52:40  zappo
-# Revamped lots of summary strings.
-# Added `type' as a possible expansion in classsubparts.
-#
-# Revision 1.33  2001/04/21 14:37:55  zappo
-# Spelling error for integer.
-#
-# Revision 1.32  2001/04/13 02:24:45  zappo
-# Added built in types (void, char, etc) and summaries.
-#
-# Revision 1.31  2001/04/07 02:43:48  zappo
-# Added name spaces, and references.
-#
-# Revision 1.30  2001/03/10 16:18:15  zappo
-# Added lots of summaries to %tokens.
-# variables and functions now share declmod and typedecl start
-# match, and then get recombobulated later.  Prevents massive
-# reparsing.
-#
-# Revision 1.29  2001/02/24 15:24:24  zappo
-# Added a few optimizations for structure parts.
-# Used some %tokens in a few spots where I wasn't using them before.
-#
-# Revision 1.28  2001/02/20 20:36:19  zappo
-# Removed unused %put calls.
-#
-# Revision 1.27  2001/02/09 19:49:26  zappo
-# Added paren testing to argument lists.
-#
-# Revision 1.26  2001/02/09 11:47:32  zappo
-# Added type separation characters.
-# Added all constituents of DECLMOD into their own tokens.
-# Created a rule to create a list of declmods.
-#
-# Revision 1.25  2001/02/02 04:14:53  zappo
-# Added c++ to the list of language modes.
-# Added lots of operator symbol tokens.
-# Added DECLMOD symbol w/ complex regexp.
-# Added CLASS, OPERATOR, PUBLIC, PRIVATE, and PROTECTED token keywords.
-# Support parsing of a class.
-# Add class bit parsing for functions.
-# Add destructor bit parsing for functions.
-# Allow operator symbols for methods.
-# Added parent and destructor fields to extra-spec for functions.
-# The function rule now returns a function or prototype.
-#
-# Revision 1.24  2001/01/31 15:26:10  zappo
-# Added `codeblock' rule and `%scopestart'.
-#
-# Revision 1.23  2001/01/24 21:08:41  zappo
-# Added support for new token formats that use ASSOC.
-#
-# Revision 1.22  2001/01/06 14:35:40  zappo
-# Put `type' `t' onto some tokens.
-# Struct and enums now match the braces, and return nil.
-# Enum parts now have a token type of 'enum.
-# Added ... to fuction arg lists.
-# Match parens for arg lists.
-#
-# [...]
-#
-# Revision 1.1  1999/05/17 17:28:30  zappo
-# Initial revision
-#
 
 %start         declaration
 %scopestart    codeblock
 %(setq semantic-expand-nonterminal 'semantic-expand-c-nonterminal
        semantic-flex-extensions semantic-flex-c-extensions
        semantic-dependency-include-path semantic-default-c-path
+       semantic-orphaned-member-metaparent-type "struct"
+       semantic-symbol->name-assoc-list
+        '((type     . "Types")
+	  (variable . "Variables")
+	  (function . "Functions")
+	  (include  . "Includes"))
+       semantic-symbol->name-assoc-list-for-type-parts
+        '((type     . "Types")
+	  (variable . "Attributes")
+	  (function . "Methods")
+	  (label    . "Labels")
+	  )
        imenu-create-index-function 'semantic-create-imenu-index
        semantic-type-relation-separator-character '("." "->")
        semantic-command-separation-character ";"
        document-comment-start "/*"
        document-comment-line-prefix " *"
        document-comment-end " */"
+       ;; Semantic navigation inside 'type children
+       senator-step-at-token-ids '(function variable)
        )%
 
 %token INCLUDE "include"
 %put CONST summary "Declaration Modifier: const <type> <name> ..."
 %token VOLATILE "volatile"
 %put VOLATILE summary "Declaration Modifier: volatile <type> <name> ..."
+%token REGISTER "register"
+%put REGISTER summary "Declaration Modifier: register <type> <name> ..."
 %token SIGNED "signed"
 %put SIGNED summary "Numeric Type Modifier: signed <numeric type> <name> ..."
 %token UNSIGNED "unsigned"
 %put UNSIGNED summary "Numeric Type Modifier: unsigned <numeric type> <name> ..."
 
 %token INLINE "inline"
-%put INLINE "Function Modifier: inline <return  type> <name>(...) {...};"
+%put INLINE summary "Function Modifier: inline <return  type> <name>(...) {...};"
 %token VIRTUAL "virtual"
 %put VIRTUAL summary "Method Modifier: virtual <type> <name>(...) ..."
+%token MUTABLE "mutable"
+%put MUTABLE summary "Member Declaration Modifier: mutable <type> <name> ..."
 
 %token STRUCT "struct"
 %put STRUCT summary "Structure Type Declaration: struct [name] { ... };"
 %put CLASS summary "Class Declaration: class <name>[:parents] { ... };"
 %token NAMESPACE "namespace"
 %put NAMESPACE summary "Namespace Declaration: namespace <name> { ... };"
+%token USING "using"
+%put USING summary "using <namespace>;"
+
+# Despite this, this parser can find templates by ignoring the TEMPLATE
+# keyword, and finding the class/method being templateized.
+%token TEMPLATE "template"
+%put TEMPLATE summary "template <class TYPE ...> TYPE_OR_FUNCTION"
 
 %token THROW "throw"
 %put THROW summary "<type> <methoddef> (<method args>) throw (<exception>) ..."
+%token REENTRANT "reentrant"
+%put REENTRANT summary "<type> <methoddef> (<method args>) reentrant ..."
 
 # Leave these alone for now.
 %token OPERATOR "operator"
 %token PUBLIC "public"
 %token PRIVATE "private"
 %token PROTECTED "protected"
-
+%token FRIEND "friend"
 
 # These aren't used for parsing, but is a useful place to describe the keywords.
 %token IF "if"
 %token DOUBLE "double"
 %put DOUBLE summary "Primitive floating-point type (double-precision 64-bit IEEE 754)"
 
+%token UNDERP "_P"
+%token UNDERUNDERP "__P"
+%put UNDERP summary "Common macro to eliminate prototype compatibility on some compilers"
+%put UNDERUNDERP summary "Common macro to eliminate prototype compatibility on some compilers"
+
 declaration : macro
 	    | type
 	    | var-or-fun
 	    | define
+	    | extern-c
+	    | template
+	    | using
 	    ;
 
 codeblock : define
-	  | var-or-fun
+	  | codeblock-var-or-fun
 	  | type # type is less likely to be used here.
 	  ;
 
+extern-c-contents: open-paren
+		   ( nil )
+		 | bovine-toplevel
+		 | close-paren
+		   ( nil )
+		 ;
+
+extern-c: EXTERN string "\"C\"" semantic-list
+	# Extern C commands which contain a list need to have the
+	# entries of the list extracted, and spliced into the main
+	# list of entries.  This must be done via the function
+	# that expands singular nonterminals, such as int x,y;
+	  ( extern (EXPANDFULL $3 extern-c-contents) )
+	| EXTERN string "\"C\""
+	# A plain extern "C" call should add something to the token,
+	# but just strip it from the buffer here for now.
+	  ( nil )
+	;
+
 macro : HASH macro-or-include
 	( ,$2 )
       ;
 
-macro-or-include : DEFINE symbol opt-expression
+macro-or-include : DEFINE symbol opt-define-arglist opt-expression
 		   ( $2 variable nil $3
 			(ASSOC const t)
 			nil
 			)
-		 | INCLUDE LESS filename GREATER
-		   ( ,$3 include t nil )
+		 | INCLUDE system-include
+		   ( (substring $2 1 (1- (length $2)))  include t nil )
 		 | INCLUDE string
 		   ( (read $2) include nil nil )
 		 ;
 
+opt-define-arglist : semantic-list
+		     ( nil )
+		   | EMPTY
+		   ;
+
 # This is used in struct parts.
 define : HASH DEFINE symbol opt-expression
 	 ( $2 variable nil $3
 	      )
        ;
 
-filename : symbol PERIOD symbol
-	   ( (concat $1 $2 $3) )
-         | symbol DIVIDE filename
-	   ( (concat $1 $2 (car $3)) )
-	 ;
-
 # In C++, structures can have the same things as classes.
 # So delete this somday in the figure.
 #
 #	       # sometimes there are defines in structs.
 #	       ;
 
-classparts : semantic-list
+unionparts : semantic-list
 	     (EXPANDFULL $1 classsubparts)
-	    ;
+	   ;
+
+opt-symbol : symbol
+	   | EMPTY
+	   ;
 
 classsubparts : open-paren "{"
 		( nil )
 	      | close-paren "}"
 		( nil )
-	      | opt-class-protection COLON
+	      | class-protection opt-symbol COLON
+	      # For QT, they may put a `slot' keyword between the protection
+	      # and the COLON.
 		( ,$1 label )
 	      | var-or-fun
 	      | type
 	      | define	      
 		( ,$1 protection )
-	      # In C++, this label in a classsubpart represents
-	      # PUBLIC or PRIVATE bits.  Ignore them for now.
+	      | template
 	      | EMPTY
 	      ;
 
-opt-class-parents : COLON class-parents
+opt-class-parents : COLON class-parents opt-template-specifier
 		    ( $2 )
 		  | EMPTY
 		    ( )
 		  ;
 
-class-parents : opt-class-protection symbol COMA class-parents
-		( ,(cons $2 $4 ) )
-	      | opt-class-protection symbol
-		( $2 )
+class-parents : opt-class-protection opt-class-declmods
+		symbol COMA class-parents
+		( ,(cons $3 $5 ) )
+	      | opt-class-protection opt-class-declmods symbol
+		( $3 )
 	      ;
 
-opt-class-protection : PUBLIC
-		     | PRIVATE
-		     | PROTECTED
+opt-class-declmods : class-declmods opt-class-declmods
+		     ( nil )
+		   | EMPTY
+		   ;
+
+class-declmods : VIRTUAL
+	       ;
+
+class-protection: PUBLIC
+		| PRIVATE
+		| PROTECTED
+		;
+
+opt-class-protection : class-protection
+		       ( ,$1 )
+		     | EMPTY
 		     ;
 
 namespaceparts : semantic-list
 		  | type
                   | var-or-fun
 		  | define
-		  | opt-class-protection COLON
+		  | class-protection COLON
 		    ( $1 protection )
 		  # In C++, this label in a classsubpart represents
 		  # PUBLIC or PRIVATE bits.  Ignore them for now.
+		  | template
+		  | using
 		  | EMPTY
 		  ;
 
 	       ( nil )
 	     | close-paren "}"
 	       ( nil )
+	     | COMA
+	       ( nil )
 	     ;
 
 opt-name : symbol
 	 | EMPTY
-	   ( nil )
+	   ( "" )
          ;
 
-typesimple : struct-or-class opt-name opt-class-parents classparts
-	     ( ,$2 type ,$1 $4 ,$3 nil nil )
-	   | UNION opt-name structparts
+typesimple : struct-or-class opt-name opt-template-specifier
+	     opt-class-parents semantic-list
+	     ( ,$2 type ,$1 
+		   (let ((semantic-c-classname (cons (car ,$2) (car ,$1))))
+		       (EXPANDFULL $5 classsubparts))
+		   $4
+		   (ASSOC 'template-specifier $3)
+		   nil )
+	   | struct-or-class opt-name opt-template-specifier opt-class-parents
+	     ( ,$2 type ,$1 nil $4 
+		   (ASSOC 'template-specifier $3)
+		    nil )
+	   | UNION opt-name unionparts
 	     ( ,$2 type $1 $3 nil nil nil )
 	   | ENUM opt-name enumparts
 	     ( ,$2 type $1 $3 nil nil nil )	
-           | TYPEDEF typeform symbol
+           | TYPEDEF typeformbase typedef-symbol-list
+	   ## We put the type this typedef renames into PARENT
+	   ## but will move it in the expand function.
 	     ( $3 type $1 nil $2 nil nil )
            ;
 
+typedef-symbol-list : typedefname COMA typedef-symbol-list
+		      ( ,(cons $1 $3) )
+		    | typedefname
+		      ( $1 )
+		    ;
+
+typedefname : opt-stars symbol opt-bits opt-array
+	      ( $1 $2 )
+	    ;
+
 struct-or-class: STRUCT
 	       | CLASS
 	       ;
        ( $2 type $1 $3 nil nil nil )
      ;
 
-opt-stars : STAR opt-stars
-	    ( (1+ (car $2)) )
+# Using is vaguely like an include statement in the named portions
+# of the code.  We should probably specify a new token type for this.
+using : USING typeformbase SEMICOLON
+	( nil )
+      | USING symbol COLON COLONG typeformbase SEMICOLON;
+      ;
+
+template : TEMPLATE template-specifier opt-friend template-definition
+	   ( ,(semantic-c-reconstitute-template $4 ,$2) )
+	 ;
+
+opt-friend : FRIEND
+	   | EMPTY
+	   ;
+
+opt-template-specifier : template-specifier
+			 ( ,$1 )
+		       | EMPTY
+			 ()
+		       ;
+
+template-specifier : LESS template-specifier-types GREATER
+		     ( ,$2 )
+		   ;
+
+template-specifier-types : template-var template-specifier-type-list
+			   ( ,(cons ,$1 ,$2 ) )
+			 | EMPTY
+			 ;
+
+template-specifier-type-list : COMA template-specifier-types
+			       ( ,$2 )
+			     | EMPTY
+			       ( )
+			     ;
+
+template-var : template-type opt-stars opt-template-equal
+	       ( ,(cons (concat (car $1) (make-string (car ,$2) ?*))
+			      (cdr $1)))
+	     ;
+
+opt-template-equal : EQUAL symbol LESS template-specifier-types GREATER
+		     ( $2 )
+		   | EMPTY
+		   ;
+
+template-type : CLASS symbol
+		( $2 type "class" nil nil)
+	      | STRUCT symbol
+		( $2 type "struct" nil nil)
+	      | builtintype
+		( ,$1 type nil nil nil)
+	      | symbol
+		( $1 type nil nil nil)
+	      ;
+
+template-definition : type
+		      ( ,$1 )
+		    | var-or-fun
+		      ( ,$1 )
+		    ;
+
+opt-stars :  STAR opt-starmod opt-stars
+	    ( (1+ (car $3)) )
 	  | EMPTY
 	    ( 0 )
           ;
 
+opt-starmod : STARMOD opt-starmod
+	      ( ,(cons (,car ,$1) $2) )
+	    | EMPTY
+	      ()
+	    ;
+
+STARMOD : CONST
+	;
+
 declmods : DECLMOD declmods
 	   ( ,(cons ,(car ,$1) $2 ) )
 	 | DECLMOD
 	| VOLATILE
 	| SIGNED
 	| UNSIGNED
-	| VIRTUAL
 	| INLINE
+	| REGISTER
+	| FRIEND
+	| METADECLMOD
 	;
 
-# Don't deal with the stars or reference just yet.
-typeform : typeformbase opt-stars opt-ref
-	   ( ,$1 )
-	 ;
+metadeclmod : METADECLMOD
+	      ()
+	    | EMPTY
+	      ()
+	    ;
+
+METADECLMOD : VIRTUAL
+	    | MUTABLE
+	    ;
 
 # C++: A type can be modified into a reference by "&"
 opt-ref : AMPERSAND
+	  ( 1 )
 	| EMPTY
+	  ( 0 )
 	;
 
 typeformbase : typesimple
 	       ( $2 type $1 )
 	     | builtintype
 	       ( ,$1 )
+	     | symbol template-specifier
+	       ( $1 type "class" )
+	     | symbol COLON COLON typeformclassbase
+	       ( (concat $1 "::" (car $4) ) )
 	     | symbol
 	       ( $1 )
 	     ;
 
+typeformclassbase : symbol COLON COLON typeformclassbase
+		    ( (concat $1 "::" (car $4)) )
+		  | symbol
+		    ( $1 )
+		  ;
+
 builtintype : VOID
 	    | CHAR
 	    | SHORT
 	    | DOUBLE
 	    ;
 
-var-or-fun : declmods typeform var-or-func-decl
-	     ( ,(semantic-c-reconstitute-token ,$3 $1 $2 ) )
+codeblock-var-or-fun : declmods typeformbase metadeclmod
+		       opt-ref var-or-func-decl
+		       ( ,(semantic-c-reconstitute-token ,$5 $1 $2 ) )
+		     ;
+
+var-or-fun : codeblock-var-or-fun
+	     ( ,$1 )
 	   # it is possible for a function to not have a type, and
 	   # it is then assumed to be an int.  How annoying.
+	   # In C++, this could be a constructor or a destructor.
+	   # Even more annoying.  Only ever do this for regular
+	   # top-level items.  Ignore this problem in code blocks
+	   # so that we don't have to deal with regular code
+	   # being erroneously converted into types.
 	   | declmods var-or-func-decl
 	     ( ,(semantic-c-reconstitute-token ,$2 $1 nil ) )
 	   ;
 
-var-or-func-decl : opt-class opt-destructor functionname arg-list 
-		   opt-throw
-		   fun-or-proto-end
-		   ( ,$3 'function 
-			 ;; Extra stuff goes in here.
-			 ;; Continue with the stuff we found in
-			 ;; this definition
-			$1 $2 $4 $5)
-		 | varnamelist  SEMICOLON
-		   ( $1 'variable )
+var-or-func-decl : func-decl
+		   ( ,$1 )
+		 | var-decl
+		   ( ,$1 )
 		 ;
 
+func-decl : opt-stars opt-class opt-destructor functionname
+	    opt-template-specifier
+	    opt-under-p 
+	    arg-list
+	    opt-post-fcn-modifiers
+	    opt-throw
+	    opt-initializers
+	    fun-or-proto-end
+	    ( ,$4 'function 
+		  ;; Extra stuff goes in here.
+		  ;; Continue with the stuff we found in
+		  ;; this definition
+		  $2 $3 $7 $9 $8 ,$1 ,$11)
+	  ;
+
+var-decl :  varnamelist  SEMICOLON
+	   ( $1 'variable )
+	 ;
+
+opt-under-p : UNDERP
+	      (nil)
+	    | UNDERUNDERP
+	      (nil)
+	    | EMPTY
+	    ;
+
+opt-initializers: COLON symbol semantic-list opt-initializers
+		| COMA symbol semantic-list opt-initializers
+		| EMPTY
+		;
+
+opt-post-fcn-modifiers : post-fcn-modifiers opt-post-fcn-modifiers
+			 ( ,(cons ,$1 $2) )
+		       | EMPTY
+			 ( nil )
+		       ;
+
+post-fcn-modifiers : REENTRANT
+		   | CONST
+		   ;
+
 opt-throw : THROW semantic-list
 	     ( EXPAND $2 throw-exception-list )
 	   | EMPTY
 
 # Is this true?  I don't actually know.
 throw-exception-list : symbol COMA throw-exception-list
-			( ,(cons $1 $3) )
-		      | symbol close-paren ")"
-			( $1 )
+		       ( ,(cons $1 $3) )
+		     | symbol close-paren ")"
+		       ( $1 )
 		     | open-paren "(" throw-exception-list
-			( ,$2 )
-		      ;
+		       ( ,$2 )
+		     | close-paren ")"
+		       (  )
+		     ;
 
-opt-bits : COLON symbol
+opt-bits : COLON number
 	   ( $2 )
 	 | EMPTY
 	   ( nil )
 	;
 
 # I should store more in this def, but leave it simple for now.
-variablearg : declmods typeform varname
-	      ( (car $3) variable $2 nil
+variablearg : declmods typeformbase opt-ref variablearg-opt-name
+	      ( (list $4) variable $2 nil
 		 (ASSOC const (if (member "const" $1) t nil)
-			typemodifiers (delete "const" $1))
+			typemodifiers (delete "const" $1)
+			reference (car ,$3)
+			)
 		 nil
 		 )
 	    ;
 
+variablearg-opt-name: varname
+		      ( ,$1)
+		    | EMPTY
+		      ( ""  0 nil nil nil )
+		    ;
+
 varnamelist : varname COMA varnamelist
 	      ( ,(cons $1 $3) )
             | varname
 		 ( nil )
 	       ;
 
-arg-list : symbol "\\<__?P\\>" semantic-list
-	   (EXPAND $2 arg-list-p)
-	 | semantic-list "^(" knr-arguments
+arg-list : semantic-list "^(" knr-arguments
 	   ( ,$2 )
 	 | semantic-list "^("
 	   (EXPANDFULL $1 arg-sub-list)
+	 | semantic-list "^(void)$"
+	   ( )
 	 ;
 
 knr-arguments : variablearg SEMICOLON knr-arguments
-		( ,(cons $1 $3) )
+		( ,(cons (car (semantic-expand-c-nonterminal ,$1) ) ,$3) )
 	      | variablearg SEMICOLON
-		( $1 )
+		( (car (semantic-expand-c-nonterminal ,$1)) )
 	      ;
 
-arg-list-p : open-paren "(" semantic-list close-paren ")"
-	     (EXPANDFULL $2 arg-sub-list)
-	   ;
-
 arg-sub-list : variablearg
 	       ( ,$1 )
 	     | PERIOD PERIOD PERIOD close-paren ")"
 	       ( "..." )
+	     | COMA
+	       ( nil )
 	     | open-paren "("
 	       ( nil )
 	     | close-paren ")"
 	      ( ">=" )
 	    | BANG EQUAL
 	      ( "!=" )
+	    | MINUS GREATER
+	      ( "->" )
 	    | LESS
 	    | GREATER
 	    | STAR
 	    | MINUS
 	    | DIVIDE
 	    | EQUAL
+	    | BANG
 	    ;
 
 functionname : OPERATOR operatorsym
 		  ( t )
 		| semantic-list
 		  ( nil )
+		# Here is an anoying feature of C++ pure virtual methods
+		| EQUAL number "^0$" SEMICOLON
+		  ( 'pure-virtual )
 		;
 
 opt-expression : expression
 	       | EMPTY ( nil )
 	       ;
 
+type-cast : semantic-list
+	    ( EXPAND $1 type-cast-list )
+	  ;
+
+type-cast-list : open-paren typeformbase close-paren
+	       ;
+
+function-call: symbol semantic-list
+             ;
+
 # Use expression for parsing only.  Don't actually return anything
 # for now.  Hopefully we can fix this later.
-expression : symbol
-	     ( )
-           | punctuation "[!*&~]" symbol
-	     ( )
+expression : number
+	     ( (identity start) (identity end) )
+	   | function-call
+	     ( (identity start) (identity end) )
+	   | symbol
+	     ( (identity start) (identity end) )
 	   | string
-	     ( )
-           | semantic-list
-	     ( )
-	   # | expression "+-*/%^|&" expression
-	   # ( nil )
+	     ( (identity start) (identity end))
+           | type-cast expression  # A cast to some other type
+	     ( (identity start) (identity end) )
+	   | semantic-list
+	     ( (identity start) (identity end) )
+	   | punctuation "[-+*/%^|&]" expression
+	     ( (identity start) (identity end) )
 	   ;