Anonymous avatar Anonymous committed a663240

Brought in semantic 1.2.1

Comments (0)

Files changed (39)

+_pkg.el
+auto-autoloads.el
+custom-load.el
+package-info
+*.info
+2000-07-16  Mike Sperber <mike@xemacs.org>
+
+	* Makefile: brought in semantic 1.2.1.
+
+2000-07-16  Michael Sperber [Mr. Preprocessor]  <sperber@informatik.uni-tuebingen.de>
+
+	* Makefile: brought in semantic 1.2.1.
+
+# Makefile for semantic lisp code
+
+# This file is part of XEmacs.
+
+# XEmacs is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2, or (at your option) any
+# later version.
+
+# XEmacs is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with XEmacs; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+VERSION = 1.0
+AUTHOR_VERSION = 1.2.1
+MAINTAINER = XEmacs Development Team <xemacs-beta@xemacs.org>
+PACKAGE = semantic
+PKG_TYPE = regular
+REQUIRES = xemacs-base speedbar
+CATEGORY = prog
+
+ELCS = semantic-bnf.elc semantic-c.elc semantic-el.elc \
+	semantic-imenu.elc semantic-make.elc semantic-sb.elc \
+	semantic.elc \
+	sformat.elc working.elc
+EXTRA_SOURCES = semantic-util.el
+
+INFO_FILES = $(PACKAGE).info*
+TEXI_FILES = $(PACKAGE).texi
+MANUAL = $(PACKAGE)
+
+include ../../XEmacs.rules
+
+GENERATED += custom-load.elc
+
+all:: $(ELCS) auto-autoloads.elc custom-load.elc $(PACKAGE).info
+
+srckit: srckit-std
+
+binkit: binkit-common
+# Makefile for semantic lisp code
+
+# This file is part of XEmacs.
+
+# XEmacs is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2, or (at your option) any
+# later version.
+
+# XEmacs is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with XEmacs; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+VERSION = 1.0
+AUTHOR_VERSION = 1.2.1
+MAINTAINER = XEmacs Development Team <xemacs-beta@xemacs.org>
+PACKAGE = semantic
+PKG_TYPE = regular
+REQUIRES = xemacs-base speedbar
+CATEGORY = prog
+
+ELCS = semantic-bnf.elc semantic-c.elc semantic-el.elc \
+	semantic-imenu.elc semantic-make.elc semantic-sb.elc \
+	semantic-util.elc semantic.elc \
+	sformat.elc working.elc
+
+INFO_FILES = $(PACKAGE).info*
+TEXI_FILES = $(PACKAGE).texi
+MANUAL = $(PACKAGE)
+
+include ../../XEmacs.rules
+
+GENERATED += custom-load.elc
+
+all:: $(ELCS) auto-autoloads.elc custom-load.elc $(PACKAGE).info
+
+srckit: srckit-std
+
+binkit: binkit-common
+;; Object ede-proj-project
+;; EDE project file.
+(ede-proj-project "ede-proj-project"
+  :name "semantic"
+  :version "1.2.1"
+  :file "Project.ede"
+  :targets (list   (ede-proj-target-elisp "tools"
+    :name "tools"
+    :path ""
+    :source '("document.el" "document-vars.el" "sformat.el" "semantic-make.el" "semantic-c.el" "semantic-imenu.el" "semantic-el.el" "semantic-sb.el" "working.el")
+    )
+   (ede-proj-target-makefile-info "info"
+    :name "info"
+    :path ""
+    :source '("semantic.texi")
+    )
+   (ede-proj-target-aux "aux"
+    :name "aux"
+    :path ""
+    :source '("c.bnf" "make.bnf")
+    )
+   (ede-proj-target-elisp "semantic"
+    :name "semantic"
+    :path ""
+    :source '("semantic-bnf.el" "semantic.el" "semantic-util.el")
+    )
+   )
+  :configuration-variables 'nil
+  )
+;;;###autoload
+(package-provide 'semantic
+		 :version 1.0
+		 :type 'regular)

auto-autoloads.el

+;;; DO NOT MODIFY THIS FILE
+(if (featurep 'semantic-autoloads) (error "Already loaded"))
+
+;;;### (autoloads nil "_pkg" "semantic/_pkg.el")
+
+(package-provide 'semantic :version 1.0 :type 'regular)
+
+;;;***
+
+;;;### (autoloads (semantic-bovinate-toplevel) "semantic" "semantic/semantic.el")
+
+(autoload 'semantic-bovinate-toplevel "semantic" "\
+Bovinate the entire current buffer to a list depth of DEPTH.
+DEPTH is optional, and defaults to 0.
+Optional argument TRASHCOMMENTS indicates that comments should be
+stripped from the main list of synthesized tokens.
+If third argument CHECKCACHE is non-nil, then flush the cache iff
+there has been a size change." nil nil)
+
+;;;***
+
+(provide 'semantic-autoloads)

Binary file added.

+# Simple BNF notation for top-level C elements.
+#
+# Copyright (C) 1999, 2000 Eric M. Ludlam
+#
+# Author: Eric M. Ludlam <zappo@gnu.org>
+# X-RCS: $Id$
+#
+# c.bnf is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This software is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Emacs; see the file COPYING.  If not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+# $Log$
+# Revision 1.14  2000/07/05 14:41:31  zappo
+# Support multiple continuous decl modifiers.
+# Added modifiers into variables.
+#
+# Revision 1.13  2000/07/01 18:15:31  zappo
+# Updated for new elements in the tokens.
+#
+# Revision 1.12  2000/06/13 14:37:48  zappo
+# The table has moved.
+#
+# Revision 1.11  2000/05/06 01:32:57  zappo
+# Use EXPANDFULL for enums, and for argument lists to functions.
+#
+# Revision 1.10  2000/04/29 12:54:15  zappo
+# Added support for Linux __P items.
+# Added support for "..." fn prototypes.
+#
+# Revision 1.9  2000/04/28 18:57:49  zappo
+# Added system flag to include files.
+#
+# Revision 1.8  2000/04/25 14:46:42  zappo
+# structparts now uses EXPANDFULL to get positional information for it's
+# sub parts.  This simplified STRUCTSUBPARTS nonterminal
+#
+# Revision 1.7  2000/04/23 15:34:28  zappo
+# Added copyright information.
+#
+# Revision 1.6  2000/04/20 23:55:03  zappo
+# Macros split from 'variable' nt.
+# Added knr-argument parsing.
+#
+# Revision 1.5  2000/04/16 22:34:07  zappo
+# Added `filename' for include rules.
+#
+# Revision 1.4  1999/12/17 20:53:16  zappo
+# Added a splice , for varnamelist.
+#
+# Revision 1.3  1999/06/06 14:20:24  zappo
+# Fixed up some language definitions.
+#
+# Revision 1.2  1999/05/18 14:08:56  zappo
+# Fixed up the returns of some nonterminals.
+#
+# Revision 1.1  1999/05/17 17:28:30  zappo
+# Initial revision
+#
+
+# TABLE: semantic-c.el:semantic-toplevel-c-bovine-table
+# MODE: c-mode
+
+bovine-toplevel : include
+		| macro
+		| comment
+                | function
+		| variable
+                | prototype
+                | type
+                | define
+                ;
+		
+include : punctuation "#" symbol "include" punctuation "<"
+	  filename punctuation ">"
+	  ( ,$4 include t nil )
+        | punctuation "#" symbol "include" string
+	  ( (read $3) include nil nil )
+        ;
+
+filename : symbol punctuation "\\." symbol
+	   ( (concat $1 $2 $3) )
+         | symbol punctuation "/" filename
+	   ( (concat $1 $2 (car $3)) )
+	 ;
+	  
+structparts : semantic-list
+	      (EXPANDFULL $1 structsubparts)
+	    ;
+
+structsubparts : variable
+	       | define
+	       # sometimes there are defines in structs.
+	       ;
+
+
+enumparts : semantic-list
+	    (EXPANDFULL $1 enumsubparts)
+	  ;
+
+enumsubparts : symbol opt-assign
+	       ( $1 )
+	     ;
+
+opt-name : symbol
+	 | EMPTY
+	   ( nil )
+         ;
+
+typesimple : symbol "struct\\|union" opt-name structparts
+	     ( ,$2 type $1 $3 nil nil nil )
+	   | symbol "enum" opt-name enumparts
+	     ( ,$2 type $1 $3 nil nil nil )	
+           | symbol "typedef" typeform symbol
+	     ( $3 type $1 nil $2 nil nil )
+           ;
+
+type : typesimple punctuation ";"
+       ( ,$1 )
+     ;
+
+opt-stars : punctuation "*" opt-stars
+	    ( (1+ (car $2)) )
+	  | EMPTY
+	    ( 0 )
+          ;
+
+declmods : symbol "\\(_+\\)?\\(extern\\|static\\|const\\|volitile\\|signed\\|unsigned\\)" declmods
+	   ( ,(cons $1 $2 ) )
+	 | symbol "\\(_+\\)?\\(extern\\|static\\|const\\|volitile\\|signed\\|unsigned\\)"
+	   ( $1 )
+	 | EMPTY
+	   ()
+	 ;
+
+# dont deal with the stars just yet.
+typeform : typeformbase opt-stars
+	   ( ,$1 )
+	 ;
+
+typeformbase : typesimple
+	       ( ,$1 )
+	     | symbol "struct\\|union\\|enum" symbol
+	       ( $2 type $1 )
+	     | symbol
+	       ( $1 )
+	     ;
+  
+opt-bits : punctuation ":" symbol
+	   ( $2 )
+	 | EMPTY
+	   ( nil )
+	 ;
+
+opt-array : semantic-list "^\\[.*\\]$" opt-array
+	  # Eventually we want to replace the 1 below with a size
+	  # (if available)
+	    ( (cons 1 (car ,$2) ) )
+	  | EMPTY
+	    ( nil )
+          ;
+
+opt-assign : punctuation "=" expression
+	     ( $2 )
+	   | EMPTY
+	     ( nil )
+	   ;
+
+macro : punctuation "#" symbol "define" symbol opt-expression
+	( $3 variable nil t $4 nil nil )
+      ;
+
+variable : variabledef punctuation ";"
+	   ( ,$1 )
+	 ;
+
+variabledef : declmods typeform varnamelist
+	      ( $3 variable $2 (if $1 (string-match "const" (car $1))) nil 
+	      (if (and $1 (string-match "const" (car $1))) (cdr $1) $1) nil )
+	    ;
+
+opt-restrict : symbol "\\(__\\)?restrict"
+	     | EMPTY
+	     ;
+
+varname : opt-stars opt-restrict symbol opt-bits opt-array opt-assign
+	  ( $3 ,$1 ,$4 ,$5 ,$6 )
+	;
+
+# I should store more in this def, but leave it simple for now.
+variablearg : declmods typeform varname
+	      ( (car $3) variable $2 (if $1 (string-match "const" (car $1)))
+	      nil (if (and $1 (string-match "const" (car $1))) (cdr $1) $1)
+	      nil )
+	    ;
+
+varnamelist : varname  punctuation "," varnamelist
+	      ( ,(cons $1 $3) )
+            | varname
+	      ( $1 )
+	    ;
+
+arg-list : symbol "__P" semantic-list
+	   (EXPAND $2 arg-list-p)
+	 | semantic-list knr-arguments
+	   ( ,$2 )
+	 | semantic-list
+	   (EXPANDFULL $1 arg-sub-list)
+	 ;
+
+knr-arguments : variablearg punctuation ";" knr-arguments
+		( ,(cons $1 $3) )
+	      | variablearg punctuation ";"
+		( $1 )
+	      ;
+
+arg-list-p : open-paren "(" semantic-list close-paren ")"
+	     (EXPANDFULL $2 arg-sub-list)
+	   ;
+
+arg-sub-list : variablearg
+	       ( ,$1 )
+	     | punctuation "\\." punctuation "\\." punctuation "\\."
+	       close-paren ")"
+	       ( "..." )
+	     ;
+
+functiondef : declmods typeform symbol arg-list
+	      ( $3 function $2 $4 $1 nil )
+            ;
+
+prototype : functiondef punctuation ";"
+	    ( ,$1 )
+	  ;
+
+function : functiondef semantic-list
+	   ( ,$1 )
+         ;
+
+opt-expression : expression
+	       | EMPTY ( nil )
+	       ;
+
+# Use expressiosn for parsing only.  Don't actually return anything
+# for now.  Hopefully we can't fix this later.
+expression : symbol
+	     ( nil )
+           | punctuation "[!*&~]" symbol
+	     ( nil )
+           | semantic-list
+	     ( nil )
+	   # | expression "+-*/%^|&" expression
+	   # ( nil )
+	   ;
+;;; custom-load.el --- automatically extracted custom dependencies
+
+;;; Code:
+
+(custom-add-loads 'texinfo '("document"))
+(custom-add-loads 'speedbar '("semantic-sb"))
+(custom-add-loads 'document '("document-vars" "document"))
+(custom-add-loads 'lisp '("working"))
+(custom-add-loads 'semantic '("document" "semantic"))
+(custom-add-loads 'working '("working"))
+(custom-add-loads 'imenu '("semantic-imenu"))
+(custom-add-loads 'c '("semantic-c"))
+
+;;; custom-load.el ends here

Binary file added.

+;;; document-vars.el --- Default settings for the document package.
+
+;;; Copyright (C) 2000 Eric M. Ludlam
+
+;; Author: Eric M. Ludlam <zappo@gnu.org>
+;; Keywords: doc
+;; X-RCS: $Id$
+
+;; This file is not part of GNU Emacs.
+
+;; Semantic is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This software is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+;;
+;; Default settings for the document comment generation package.
+
+
+;;; Code:
+(provide 'document-vars)
+
+(defcustom document-copyright-notice-file nil
+  "*A file name containing a copyright notice.
+It will be reformatted in the header to have the correct prefix character.
+See the %N token in document-file-comment"
+  :group 'document
+  :type 'file)
+
+(defcustom document-change-number nil
+  "*The current change number being worked on.
+Large projects may use change numbers, bug numbers, or other tag."
+  :group 'document
+  :type 'string)
+
+(defcustom document-extra-line-after-short-parameters t
+  "*Non-nil to add an extra line when there is < 1 arguments."
+  :group 'document
+  :type 'string)
+
+(defvar document-comment-left-edge-character nil
+  "*Language/preference specific characters to use in comments.")
+
+(defcustom document-file-comment "%s %B
+%m
+%m Copyright (C) %Y %O
+%m
+%m %N
+%m
+%m Description:
+%m
+%m   %D
+%m
+%m History:
+%m %H
+%m
+%m Tokens: %T
+%e
+"
+  "Comment block for the beginning of a new file.
+The format tokens available are:
+ %B - Brief description of the file (Auto-comment by file name)
+ %D - Made up documentation
+ %N - Copyright notice for your organization
+ %O - Owner (full name of copyright holder held in `document-copyright-holder'
+ %H - History elements
+ %T - cproto header id token.  Always is form 'token file.h' where
+      token is defined in cpr-header-token, and file.h is the
+      relational file name of the header.  If you wish to use cproto's
+      features, you must have this somewhere in the header.
+ %Y - Year
+Commenting elements:
+ %b - Comment start string
+ %m - Comment line prefix (not the start)
+ %e - Comment end string"
+  :group 'document
+  :type 'string)
+
+(defcustom document-header-comment "%b
+%m Copyright (c) %Y %O
+%m
+%m %N
+%m
+%m History:
+%m %H
+%e
+"
+  "Comment block for the beginning of a new header/dependency file.
+The format tokens available are the same as for `document-file-comment'"
+  :group 'document
+  :type 'string)
+
+(defcustom document-file-brief-comment "%F - %C"
+  "Format of the brief comment with tokens.
+Available tokens are:
+ %F - file name short
+ %C - Comment field"
+  :group 'document
+  :type 'string)
+
+(defcustom document-function-comment "
+%b
+%m Function: %F
+%m
+%m %f  %D%p
+%m
+%m Returns:     %R
+%m Parameters:  %P
+%m History:
+%m %H
+%e
+"
+  "Comment block for the beginning of a new function/variable definition.
+There are several format tokens represent the following:
+  %F - function name
+  %D - Made up documentation
+  %f - Place, where everything before the point is the distance to set
+       in the fill prefix.  Allows a first line in paragraph indent
+  %p - Where to place point after insertion of a new header
+  %R - Returns
+  %P - Parameter list
+  %H - History insertion point
+
+  The parts %f and %p can be confusing, so here is an example:
+
+ * Moose: %f%D%p
+
+ Will set fill prefix to ` *         `, and put the point AFTER the
+description.  The `Moose:` will not be in the prefix.  The default
+value shows the equivalent of a hanging indent.
+
+Commenting elements:
+ %b - Comment start string
+ %m - Comment line prefix (not the start)
+ %e - Comment end string"
+  :group 'document
+  :type 'string)
+
+(defcustom document-param-element "%P - %D"
+  "The format of a parameter element in the list of parameters.
+The parts are:
+ %P - Parameter name spaced to length of max param
+ %p - Parameter name with no padding
+ %R - Type of element
+ %D - Description of parameter as known by document."
+  :group 'document
+  :type 'string)
+
+(defcustom document-history-element "%-7U %-10D %C"
+  "Format for history element.
+Valid % codes are:
+  %U - Username, initials, what have you.
+  %D - The current date formatted as in `document-date-element'
+  %S - System Change id, SCCS vers, major change comment, etc
+  %C - Auto comment area, cursor goes here for new elts."
+  :group 'document
+  :type 'string)
+
+(defcustom document-date-element "%M/%D/%y"
+  "Format for date elements.
+Valid format chars are:
+  %H - Hours
+  %h - Hours 24 hr format
+  %a - AM/PM flag
+  %I - mInutes
+  %S - Seconds
+  %D - Day
+  %w - Weekday string
+  %M - Month as number
+  %m - Month as string
+  %Y - Year
+  %y - Year as 2 numbers 1994 -> 94"
+  :group 'document
+  :type 'string)
+
+(defcustom document-autocomment-function-alist
+  '(
+    ("abort" . "Aborts the")
+    ;; trick to get re-alloc and alloc to pair into one sentence.
+    ("realloc" . "moves or ")
+    ("alloc\\(ate\\)?" . "Allocates and initializes a new ")
+    ("clean" . "Cleans up the")
+    ("clobber" . "Removes")
+    ("close" . "Cleanly closes")
+    ("check" . "Checks the")
+    ("comp\\(are\\)?" . "Compares the")
+    ("create" . "Creates a new ")
+    ("find" . "Finds ")
+    ("free" . "Frees up space")
+    ("gen\\(erate\\)?" . "Generates a new ")
+    ("get\\|find" . "Looks for the given ")
+    ("gobble" . "Removes")
+    ("he?lp" . "Provides help for")
+    ("li?ste?n" . "Listens for ")
+    ("connect" . "Connects to ")
+    ("acc?e?pt" . "Accepts a ")
+    ("load" . "Loads in ")
+    ("match" . "Check that parameters match")
+    ("name" . "Provides a name which ")
+    ("parse" . "Parses the parameters and returns ")
+    ("print\\|display" . "Prints out")
+    ("read" . "Reads from")
+    ("reset" . "Resets the parameters and returns")
+    ("scan" . "Scans the ")
+    ("setup\\|init\\(iallize\\)?" . "Initializes the ")
+    ("select" . "Chooses the ")
+    ("send" . "Sends a")
+    ("re?c\\(v\\|ieves?\\)" . "Receives a ")
+    ("wait" . "Waits for ")
+    ("write" . "Writes to")
+    )
+  "List of names to string match against the function name.
+This is an alist with each element of the form:
+ (MATCH . RESULT)
+MATCH is a regexp to match in the type field.
+RESULT is a string.
+
+Certain prefixes may always mean the same thing, and the same comment
+can be used as a beginning for the description.  Regexp should be
+lower case since the string they are compared to is downcased.
+A string may end in a space, in which case, last-alist is searched to
+see how best to describe what can be returned.
+Doesn't always work correctly, but that is just because English
+doesn't always work correctly."
+  :group 'document
+  :type '(repeat (cons (string :tag "Regexp")
+		       (string :tag "Doc Text"))))
+
+(defcustom document-autocomment-common-nouns-abbrevs
+  '(
+    ("sock\\(et\\)?" . "socket")
+    ("addr\\(ess\\)?" . "address")
+    ("buf\\(f\\(er\\)?\\)?" . "buffer")
+    ("cur\\(r\\(ent\\)?\\)?" . "current")
+    ("dev\\(ice\\)?" . "device")
+    ("file" . "file")
+    ("line" . "line")
+    ("msg\\|message" . "message")
+    ("name" . "name")
+    ("next\\|nxt" . "next")
+    ("port" . "port")
+    ("host" . "host")
+    ("obj\\|object" . "object")
+    ("previous\\|prev" . "previous")
+    ("str\\(ing\\)?" . "string")
+    ("use?r" . "user")
+    ("num\\(ber\\)?" . "number")
+    ("\\(^\\|\\s-\\)id\\($\\|\\s-\\)" . "Identifier") ;complex cause ;commen sylable
+    )
+  "List of common English abbreviations or full words.
+These are nouns (as opposed to verbs) for use in creating expanded
+versions of names.This is an alist with each element of the form:
+ (MATCH . RESULT)
+MATCH is a regexp to match in the type field.
+RESULT is a string."
+  :group 'document
+  :type '(repeat (cons (string :tag "Regexp")
+		       (string :tag "Doc Text"))))
+
+(defcustom document-autocomment-return-first-alist
+  '(
+    ;; Static must be first in the list to provide the intro to the sentence
+    ("static" . "Locally defined function which ")
+    ("Bool\\|BOOL" . "Status of ")
+    )
+  "List of regexp matches for types.
+They provide a little bit of text when typing information is
+described.
+This is an alist with each element of the form:
+ (MATCH . RESULT)
+MATCH is a regexp to match in the type field.
+RESULT is a string."
+  :group 'document
+  :type '(repeat (cons (string :tag "Regexp")
+		       (string :tag "Doc Text"))))
+
+(defcustom document-autocomment-return-last-alist
+  '(
+    ("static[ \t\n]+struct \\([a-zA-Z0-9_]+\\)" . "%s")
+    ("struct \\([a-zA-Z0-9_]+\\)" . "%s")
+    ("static[ \t\n]+union \\([a-zA-Z0-9_]+\\)" . "%s")
+    ("union \\([a-zA-Z0-9_]+\\)" . "%s")
+    ("static[ \t\n]+enum \\([a-zA-Z0-9_]+\\)" . "%s")
+    ("enum \\([a-zA-Z0-9_]+\\)" . "%s")
+    ("static[ \t\n]+\\([a-zA-Z0-9_]+\\)" . "%s")
+    ("\\([a-zA-Z0-9_]+\\)" . "of type %s")
+    )
+  "List of regexps which provide the type of the return value.
+This is an alist with each element of the form:
+ (MATCH . RESULT)
+MATCH is a regexp to match in the type field.
+RESULT is a string, which can contain %s, whih is replaced with
+`match-string' 1."
+  :group 'document
+  :type '(repeat (cons (string :tag "Regexp")
+		       (string :tag "Doc Text"))))
+
+(defcustom document-autocomment-param-alist
+  '( ("[Cc]txt" . "Context")
+     ("[Ii]d" . "Identifier of")
+     ("[Tt]ype" . "Type of")
+     ("[Nn]ame" . "Name of")
+     ("argc" . "Number of arguments")
+     ("argv" . "Argument vector")
+     ("envp" . "Environment variable vector")
+     )
+  "Alist of common variable names appearing as function parameters.
+This is an alist with each element of the form:
+ (MATCH . RESULT)
+MATCH is a regexp to match in the type field.
+RESULT is a string of text to use to describe MATCH.
+When one is encountered, document-insert-parameters will automatically
+place this comment after the parameter name."
+  :group 'document
+  :type '(repeat (cons (string :tag "Regexp")
+		       (string :tag "Doc Text"))))
+
+(defcustom document-autocomment-param-type-alist
+  '(("const" . "Constant")
+    ("void" . "Empty")
+    ("char[ ]*\\*" . "String ")
+    ("\\*\\*" . "Pointer to ")
+    ("\\*" . "Pointer ")
+    ("char[ ]*\\([^ \t*]\\|$\\)" . "Character")
+    ("int\\|long" . "Number of")
+    ("FILE" . "File of")
+    ("float\\|double" . "Value of")
+    ;; How about some X things?
+    ("Bool\\|BOOL" . "Flag")
+    ("Window" . "Window")
+    ("GC" . "Graphic Context")
+    ("Widget" . "Widget")
+    )
+  "Alist of input parameter types and strings desribing them.
+This is an alist with each element of the form:
+ (MATCH . RESULT)
+MATCH is a regexp to match in the type field.
+RESULT is a string."
+  :group 'document
+  :type '(repeat (cons (string :tag "Regexp")
+		       (string :tag "Doc Text"))))
+
+(defcustom document-new-hist-comment "Created"
+  "Comment used in the history when something is created."
+  :group 'document
+  :type 'string)
+
+(defvar document-autocomment-modify-alist
+  '((document-newparam . "%s")
+    )
+  "Alist of history change calculations.
+This is an alist with each element of the form:
+ (FUNCTION . RESULT)
+FUNCTION is a function to run to check for chnges.
+RESULT is a string with %s being filled with change text.")
+
+;;; A few fns to access some variables.
+(defun document-comment-start ()
+  "Derive a string to start a comment in this mode."
+  (or document-comment-start
+      block-comment-start
+      comment-start))
+
+(defun document-comment-line-prefix ()
+  "Derive a string to end a comment in this mode."
+  (or document-comment-line-prefix
+      ""))
+
+(defun document-comment-end ()
+  "Derive a string to end a comment in this mode."
+  (or document-comment-end
+      block-comment-end
+      "\n"))
+
+;;; document-vars.el ends here
+;;; document.el --- Use the bovinator to aid in generating documentation.
+
+;;; Copyright (C) 2000 Eric M. Ludlam
+
+;; Author: Eric M. Ludlam <zappo@gnu.org>
+;; Keywords: doc
+;; X-RCS: $Id$
+
+;; This file is not part of GNU Emacs.
+
+;; Semantic is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This software is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+;;
+;; Document provides the ability to create a documentation framework
+;; for functions and variables.  It uses `semantic' to find the
+;; current function, and to provide additional context information for
+;; generating the documentation.
+;;
+;;   Document then provides some rules for creating English Text based
+;; on the name of a given function, it's return type, or variable
+;; type.  It also has output rules for texinfo, or comments.
+
+(require 'sformat)
+(require 'document-vars)
+
+;;; Code:
+
+;;; User customizations
+;;
+(defgroup document nil
+  "File and tag browser frame."
+  :group 'semantic
+  :group 'texinfo
+  )
+
+(defcustom document-my-initials (user-login-name)
+  "*The initials to use when commenting something."
+  :group 'document
+  :type 'string)
+
+(defcustom document-copyright-holder (user-full-name)
+  "*The string to use as the copyright holder in the file comment."
+  :group 'document
+  :type 'string)
+
+(defvar document-comment-start nil
+  "Comment start string.")
+
+(defvar document-comment-line-prefix nil
+  "Comment prefix string.  Used at the beginning of each line.")
+
+(defvar document-comment-end nil
+  "Comment end string.")
+
+(defvar document-runflags nil
+  "Flags collected while updating a comment.
+This is used to create a history element.")
+
+;; This contains most variable settings for auto-comment generation.
+(require 'document-vars)
+
+;;; Status tracking
+;;
+(defvar document-current-output-file nil
+  "A marker for the current output file used for documentation.")
+
+;;; User Functions
+;;
+(defun document (&optional resetfile)
+  "Document the function or variable the cursor is in.
+Optional argument RESETFILE is provided w/ universal argument.
+When non-nil, query for a new documentation file."
+  (interactive (if current-prefix-arg
+		   (save-excursion
+		     (list (document-locate-file
+			    (current-buffer) t)))))
+  ;; First, garner some information from Semantic.
+  (semantic-bovinate-toplevel nil t t)
+  (let ((cdi (semantic-find-nonterminal-by-position (point) (current-buffer)))
+	(cdib (current-buffer)))
+    ;; Make sure we have a file.
+    (document-locate-file (current-buffer))
+    ;; Now go and create the documentation
+    (if (not document-current-output-file)
+	(error "No file found for your documentation"))
+    (set-buffer (marker-buffer document-current-output-file))
+    (goto-char document-current-output-file)
+    (document-insert-texinfo cdi cdib)
+    (setq document-current-output-file (point-marker))
+    ))
+
+(defun document-inline ()
+  "Document the current function with an inline comment."
+  (interactive)
+  (semantic-bovinate-toplevel nil t t)
+  (let ((cf (semantic-find-nonterminal-by-position (point) (current-buffer))))
+    (document-insert-defun-comment cf (current-buffer))))
+
+;;; Documentation insertion functions
+;;
+(defun document-insert-texinfo (nonterm buffer)
+  "Insert texinfo documentation about NONTERM from BUFFER."
+  (insert "\n")
+  (let ((tt (semantic-token-token nonterm)))
+    (insert "@"
+	    (cond ((eq tt 'variable)
+		   "defvar")
+		  ((eq tt 'function)
+		   "defun")
+		  ((eq tt 'type)
+		   "deftype")
+		  (t (error "Don't know how to document that")))
+	    " "
+	    (semantic-token-name nonterm))
+    (if (eq tt 'function)
+	(let ((args (semantic-token-function-args nonterm)))
+	  (while args
+	    (insert " ")
+	    (if (stringp (car args))
+		(insert (car args))
+	      (insert (semantic-token-name (car args))))
+	    (setq args (cdr args)))))
+    (insert "\n")
+    (insert (document-massage-to-texinfo
+	     nonterm
+	     buffer
+	     (document-generate-documentation nonterm buffer)))
+    (insert "\n@end "
+	    (cond ((eq tt 'variable)
+		   "defvar")
+		  ((eq tt 'function)
+		   "defun")
+		  ((eq tt 'type)
+		   "deftype"))
+	    "\n")))
+
+(defun document-insert-defun-comment (nonterm buffer)
+  "Insert mode-comment documentation about NONTERM from BUFFER."
+  (interactive)
+  (let ((document-runflags nil)
+	(tt (semantic-token-token nonterm)))
+    (cond
+     ((eq tt 'function)
+      (if (semantic-find-documentation buffer nonterm t)
+	  (document-update-comment nonterm)
+	(document-insert-function-comment-new nonterm))
+      (message "Done..."))
+     (t
+      (error "Type %s is not yet managed by document `document-inline'" tt)))))
+
+(defun document-update-comment (nonterm)
+  "Update an existing comment for NONTERM."
+  (let ((comment (semantic-find-documentation (current-buffer)
+					      nonterm 'flex)))
+    (save-excursion
+      (document-update-paramlist nonterm comment))
+    (semantic-bovinate-toplevel nil t t)
+    (let ((ct (semantic-find-nonterminal-by-position
+	       (point) (current-buffer))))
+      (setq comment (semantic-find-documentation (current-buffer)
+						 nonterm 'flex))
+      (document-update-history comment (document-get-history-elt "")))))
+
+(defun document-insert-new-file-header (header)
+  "Insert a new header file into this buffer.  Add reference to HEADER.
+Used by `prototype' if this file doesn't have an introductory comment."
+  (interactive)
+  (goto-char 0)
+  (let ((pnt nil))
+    (insert (document-new-file-header header))
+    (if pnt
+	(goto-char pnt))))
+
+;;; Top level comment things.
+;;
+(defun document-new-file-header (&optional header)
+  "Return a comment string customized for the current buffer.
+Optional HEADER is the header file to use under Token."
+  (Sformat (list (list ?B '(lambda () (document-file-brief-comment)))
+		 (list ?D
+		       (if (boundp 'pnt)
+			   '(lambda () (setq pnt (Sformat-point)) "")
+			 ""))
+		 (list ?N '(lambda ()
+			     (document-copyright-notice)))
+		 (list ?O document-copyright-holder)
+		 (list ?Y (document-get-date-time-string "%Y"))
+		 (list ?T '(lambda ()
+			     (concat
+			      cpr-header-token
+			      " "
+			      (if header header
+				(semantic-prototype-file (current-buffer))))))
+		 (list ?H (document-get-history-elt "Created"))
+		 (list ?b (document-comment-start))
+		 (list ?m (document-comment-line-prefix))
+		 (list ?e (document-comment-end)))
+	   ;; This is lame!  Fix it sometime soon.
+	   (if (string-match "\\.c$" (buffer-file-name))
+	       document-file-comment
+	     document-header-comment)))
+
+(defun document-set-copyright-file (f)
+  "Interactively find the file name with the copyright blurb.
+Argument F is the file to use."
+  (interactive "FCopyright Notice File (RET for none): ")
+  (if (string= f (buffer-file-name))
+      (setq document-copyright-notice-file "")
+    (setq document-copyright-notice-file f)))
+
+(defun document-copyright-notice ()
+  "Create, or find a copyright notice.
+Adds the comment line PREFIX to each line."
+  (if (not document-copyright-notice-file)
+      (call-interactively 'document-set-copyright-file))
+  (if (= (length document-copyright-notice-file) 0)
+      "??Public Domain Software??"
+    (let* ((b (get-buffer-create "DOCUMENT TEMP"))
+	   (s nil)
+	   (plen (Sformat-column))
+	   (pstr (substring (concat (document-comment-line-prefix)
+				    "         ")
+			    0 plen)))
+      (setq s
+	    (save-excursion
+	      (set-buffer b)
+	      (insert-file-contents document-copyright-notice-file)
+	      ;; Now put comment marks all over.
+	      (goto-char 0)
+	      (forward-line 1)
+	      (end-of-line)
+	      (while (not (eobp))
+		(beginning-of-line)
+		(insert pstr)
+		(end-of-line)
+		(forward-char 1)
+		(end-of-line))
+	      (forward-char -1)
+	      (if (equal (following-char) ?\n)
+		  (delete-char 1))
+	      (set-buffer-modified-p nil)
+	      (buffer-string)))
+      (kill-buffer b)
+      s)))
+
+(defun document-file-brief-comment ()
+  "Make a brief comment about the file we are currently editing."
+  (Sformat (list (list ?F (file-name-nondirectory (buffer-file-name)))
+		 (list ?C '(lambda ()
+			    (read-string "Brief Description of file: "))))
+	   document-file-brief-comment))
+
+;;; Documentatation generation functions
+;;
+(defun document-generate-documentation (nonterm buffer)
+  "Return a plain string documenting NONTERM from BUFFER."
+  (let ((doc ;; Second, does this thing have docs in the source buffer which
+	 ;; an override method might be able to find?
+	 (semantic-find-documentation buffer nonterm)
+	 ))
+    (if (not doc)
+	(document-generate-new-documentation nonterm buffer)
+      ;; Ok, now lets see what sort of formatting there might be,
+      ;; and see about removing some of it.. (Tables of arguments,
+      ;; and that sort of thing.)
+      nil
+      ;; Return the string.
+      doc)))
+
+(defun document-generate-new-documentation (nonterm buffer)
+  "Look at elements of NONTERM in BUFFER to make documentation.
+This will create a new documentation string from scratch."
+  ;; We probably want more than this, but for now it's close.
+  (document-function-name-comment nonterm))
+
+;;; Inline comment mangling.
+;;
+(defun document-insert-function-comment-new (nonterm)
+  "Insert a new comment which explains the function found in NONTERM."
+  (let ((hist (document-get-history-elt ""))
+	(pnt 0)
+	(upnt 0)
+	(st 0)
+	(zpnt 0)
+	(fname (semantic-token-name nonterm))
+	(returns (semantic-token-type nonterm))
+	(params (semantic-token-function-args nonterm))
+	)
+    (if (listp returns)
+	;; convert a type list into a long string to analyze.
+	(setq returns (car returns)))
+    ;; nonterm should always be correct.
+    (goto-char (semantic-token-start nonterm))
+    (setq st (point))
+    (insert (Sformat (list (list ?F fname)
+			   (list ?f '(lambda () (setq zpnt (Sformat-point)) ""))
+			   (list ?p '(lambda () (setq pnt (Sformat-point)) ""))
+			   (list ?D (document-function-name-comment nonterm))
+			   (list ?R (document-insert-return returns))
+			   (list ?P '(lambda ()
+				       (document-insert-parameters params)))
+			   (list ?H (concat hist document-new-hist-comment))
+			   (list ?b (document-comment-start))
+			   (list ?m (document-comment-line-prefix))
+			   (list ?e (document-comment-end)))
+		     document-function-comment))
+    (goto-char (+ zpnt st))
+    (message "Setting fill prefix to: \"%s\""
+	     (setq fill-prefix
+		   (concat (document-comment-line-prefix)
+			   (make-string
+			    (- (current-column)
+			       (length (document-comment-line-prefix)))
+			    ? ))))
+    (goto-char (+ pnt st))
+    (auto-fill-mode 1)
+    )
+  )
+
+(defun document-function-name-comment (nonterm)
+  "Create documentation for the function defined in NONTERM.
+If we can identify a verb in the list followed by some
+name part then check the return value to see if we can use that to
+finish off the sentence.  ie.  Any function with 'alloc' in it will be
+allocating something based on it's type."
+  (let ((al document-autocomment-return-first-alist)
+	(dropit nil)
+	(tailit nil)
+	(news "")
+	(fname (semantic-token-name nonterm))
+	(retval (or (semantic-token-type nonterm) "")))
+    (if (listp retval)
+	;; convert a type list into a long string to analyze.
+	(setq retval (car retval)))
+    ;; check for modifiers like static
+    (while al
+      (if (string-match (car (car al)) (downcase retval))
+	  (progn
+	    (setq news (concat news (cdr (car al))))
+	    (setq dropit t)
+	    (setq al nil)))
+      (setq al (cdr al)))
+    ;; check for verb parts!
+    (setq al document-autocomment-function-alist)
+    (while al
+      (if (string-match (car (car al)) (downcase fname))
+	  (progn
+	    (setq news
+		  (concat news (if dropit (downcase (cdr (car al)))
+				 (cdr (car al)))))
+	    ;; if we end in a space, then we are expecting a potential
+	    ;; return value.
+	    (if (= ?  (aref news (1- (length news))))
+		(setq tailit t))
+	    (setq al nil)))
+      (setq al (cdr al)))
+    ;; check for noun parts!
+    (setq al document-autocomment-common-nouns-abbrevs)
+    (while al
+      (if (string-match (car (car al)) (downcase fname))
+	  (progn
+	    (setq news
+		  (concat news (if dropit (downcase (cdr (car al)))
+				 (cdr (car al)))))
+	    (setq al nil)))
+      (setq al (cdr al)))
+    ;; add tailers to names which are obviously returning something.
+    (if tailit
+	(progn
+	  (setq al document-autocomment-return-last-alist)
+	  (while al
+	    (if (string-match (car (car al)) (downcase retval))
+		(progn
+		  (setq news
+			(concat news " "
+				;; this one may use parts of the return value.
+				(format (cdr (car al))
+					(document-programmer->english
+					 (substring retval (match-beginning 1)
+						    (match-end 1))))))
+		  (setq al nil)))
+	    (setq al (cdr al)))))
+    news))
+
+(defun document-insert-return (returnval)
+  "Take the return value, and return a string which is ready to be commented.
+Argument RETURNVAL is the string representing the type to be returned."
+  (if (not returnval)
+      ""
+    (if (string-match "^\\(static +\\|STATIC +\\)?\\(void\\|VOID\\)" returnval)
+	"Nothing"
+      (if (= (length returnval) 0)
+	  "int - "
+	(concat returnval " - ")))))
+  
+(defun document-insert-parameters (params &optional commentlist)
+  "Convert a parameter list PARAMS into a vertical list separated by -es.
+Optional COMMENTLIST is a list of previously know parts with comments."
+
+  (let* ((col (if Sformat-formatting (Sformat-column) (current-column)))
+	 (newl params)
+	 ;; returns is local to the caller
+	 (longest (document-longest-name newl))
+	 (numdfs 0)
+	 (newp ""))
+    (while newl
+      (let* ((n (car newl))
+	     (nn (if (stringp n) n (semantic-token-name n)))
+	     (al (if (stringp n) nil (semantic-token-variable-modifiers n)))
+	     (nt (if (stringp n) "" (semantic-token-type n))))
+	(if (listp nt)
+	    ;; make sure this is a string.
+	    (setq nt (car nt)))
+	(setq numdfs (1+ numdfs))
+	(let ((nextp (Sformat
+		      (list (list ?P
+				  (substring (concat
+					      nn
+					      "                   ")
+					     0 longest))
+			    (list ?p n)
+			    (list ?R nt)
+			    (list ?D (document-parameter-comment
+				      n
+				      commentlist)))
+		      document-param-element)))
+	  (setq newp
+		(concat
+		 newp nextp
+		 ;; the following always assumes that there is
+		 ;; always a comment starting with SPC * on
+		 ;; every line.  Mabee fix, but this is what I
+		 ;; use, so tough noogies as of right now.
+		 (concat "\n" (document-comment-line-prefix)
+			 (make-string
+			  (- col (length (document-comment-line-prefix)))
+			  ? ))))))
+      (setq newl (cdr newl)))
+    (if (= (length newp) 0) (setq newp "None"))
+    (if (and document-extra-line-after-short-parameters (<= numdfs 1))
+	(setq newp (concat newp "\n *")))
+    newp)
+  )
+
+(defun document-parameter-comment (param &optional commentlist)
+  "Convert nonterminal or string PARAM into a name,comment pair.
+Optional COMMENTLIST is list of previously existing comments to
+use instead in alist form.  If the name doesn't appear in the list of
+standard names, then englishafy it.  instead."
+  (let ((cmt "")
+	(aso document-autocomment-param-alist)
+	(fnd nil)
+	(name (if (stringp param) param (semantic-token-name param)))
+	(tt (if (stringp param) nil (semantic-token-type param))))
+    ;; Make sure the type is a string.
+    (if (listp tt)
+	(setq tt (semantic-token-name tt)))
+    ;; Find name description parts.
+    (while aso
+      (if (string-match (car (car aso)) name)
+	  (progn
+	    (setq fnd t)
+	    (setq cmt (concat cmt (cdr (car aso))))))
+      (setq aso (cdr aso)))
+    (if (/= (length cmt) 0)
+	nil
+      ;; finally check for array parts
+      (if (and (not (stringp param)) (semantic-token-variable-modifiers param))
+	  (setq cmt (concat cmt "array of ")))
+      (setq aso document-autocomment-param-type-alist)
+      (while (and aso tt)
+	(if (string-match (car (car aso)) tt)
+	    (setq cmt (concat cmt (cdr (car aso)))))
+	(setq aso (cdr aso))))
+    ;; Convert from programmer to english.
+    (if (not fnd)
+	(setq cmt (concat cmt " "
+			  (document-programmer->english name))))
+    cmt))
+
+
+(defun document-get-history-elt (changes)
+  "Return the history element with the change elt set to CHANGES."
+  (Sformat (list '(?U document-my-initials)
+		 (list ?D (document-get-date))
+		 '(?S document-change-number)
+		 '(?C changes))
+	   document-history-element))
+
+(defun document-get-date-time-string (form)
+  "Return a string matching the format of `document-date-element'.
+Argument FORM is the format string to use."
+  (let* ((date (current-time-string))
+         (garbage
+          (string-match
+           (concat "^\\([A-Z][a-z]*\\) *\\([A-Z][a-z]*\\) *\\([0-9]*\\)"
+	   " \\([0-9]*\\):\\([0-9]*\\):\\([0-9]*\\)"
+	   " \\([0-9]*\\)$")
+           date))
+	 (wkdy (substring date (match-beginning 1) (match-end 1)))
+	 (hour (string-to-int
+		(substring date (match-beginning 4) (match-end 4))))
+	 (min (substring date (match-beginning 5) (match-end 5)))
+	 (sec (substring date (match-beginning 6) (match-end 6)))
+         (month
+	  (cdr (assoc (substring date (match-beginning 2) (match-end 2))
+		      '(("Jan" . 1) ("Feb" . 2) ("Mar" . 3) ("Apr" . 4)
+			("May" . 5) ("Jun" . 6) ("Jul" . 7) ("Aug" . 8)
+			("Sep" . 9) ("Oct" . 10) ("Nov" . 11) ("Dec" . 12)))))
+	 (ms (substring date (match-beginning 2) (match-end 2)))
+	 (day (substring date (match-beginning 3) (match-end 3)))
+         (year (substring date (match-beginning 7) (match-end 7))))
+    (Sformat (list (list ?H (% hour 12))
+		   (list ?h hour)
+		   (list ?a (if (> hour 12) "pm" "am"))
+		   (list ?I min)
+		   (list ?S sec)
+		   (list ?D day)
+		   (list ?M month)
+		   (list ?m ms)
+		   (list ?Y year)
+		   (list ?y (substring year 2))
+		   (list ?w wkdy))
+	     form)))
+
+(defun document-get-date ()
+  "Return a string which is the current date."
+  (document-get-date-time-string document-date-element))
+
+;;; Updating utilities
+;;
+(defun document-update-history (comment history)
+  "Update COMMENT with the text HISTORY.
+COMMENT is a flex token."
+  (let ((endpos 0))
+    (save-excursion
+      (goto-char (semantic-flex-end comment))
+      (if (not (re-search-backward (regexp-quote (document-comment-start))
+				   (semantic-flex-start comment) t))
+	  (error "Comment confuses me"))
+      (let ((s (document-just-after-token-regexp ?H document-function-comment)))
+	(if (not s) (error "Can't find where to enter new history element"))
+	(if (re-search-forward (concat "\\(" s "\\)")
+			       (1+ (semantic-flex-end comment)) t)
+	    (progn
+	      (goto-char (match-beginning 1))
+	      (insert (concat "\n" (document-comment-line-prefix) " "))
+	      (insert history)))
+	(setq endpos (point))))
+    (goto-char endpos)
+    (while document-runflags
+      (let ((p (assoc (car (car document-runflags))
+		      document-autocomment-modify-alist)))
+	(if p (insert (format (cdr p) (cdr (car document-runflags))))))
+      (setq document-runflags (cdr document-runflags)))))
+
+(defun document-update-paramlist (nonterm comment)
+  "Update NONTERM's comment found in the flex token COMMENT."
+  (let ((endpos 0) st en (il nil)
+	(case-fold-search nil)
+	(l (semantic-token-function-args nonterm)))
+    (save-excursion
+      (goto-char (semantic-flex-start comment))
+      (let ((s (document-just-after-token-regexp ?P document-function-comment))
+	    (s2 (document-just-before-token-regexp ?P document-function-comment)))
+	(if (or (not s) (not s2))
+	    (error "Cannot break format string into findable begin and end tokens"))
+	(if (not (re-search-forward (concat "\\(" s "\\)")
+				    (1+ (semantic-flex-end comment)) t))
+	    (error "Comment is not formatted correctly for param check"))
+	(goto-char (match-beginning 1))
+	(setq en (point))
+	(goto-char (semantic-flex-start comment))
+	(if (not (re-search-forward s2 (semantic-flex-end comment) t))
+	    (error "Comment is not formatted correctly for param check"))
+	(setq st (point))
+	;; At this point we have the beginning and end of the
+	;; parameter list in the comment.  Now lets search through
+	;; it and generate a list (name . commentpart) so we can
+	;; re-build it if it doesn't match L
+	(while (re-search-forward
+		(concat "\\(\\(\\sw\\|\\s_+\\)+\\)\\s-*-[ \t]*")
+		en t)
+	  (let ((n (buffer-substring (match-beginning 1) (match-end 1)))
+		(c nil))
+	    (setq c (point))
+	    (re-search-forward "$" (semantic-flex-end comment) t)
+	    (setq c (buffer-substring c (point)))
+	    (setq il (cons (cons n c) il))))
+	;; run verify on two lists of parameters to make sure they
+	;; are the same.
+	(let ((tl l) (stop nil))
+	  (while (and tl (not stop))
+	    (if (not (assoc (semantic-token-name (car tl)) il))
+		(setq stop t))
+	    (setq tl (cdr tl)))
+	  (if (not stop)
+	      (setq il nil)))
+	;; check if we want to modify the parameter list.
+	(if (not (and il (y-or-n-p "Parameter list changed.  Fix? ")))
+	    (message "Not fixing.")
+	  ;; delete what was there, and insert the new stuff.
+	  (let ((ntl l)
+		(cs1 nil)
+		(num 0))
+	    (while ntl
+	      (if (not (assoc (semantic-token-name (car ntl)) il))
+		  (progn
+		    (setq num (1+ num))
+		    (setq cs1 (concat cs1 (if cs1 ", ")
+				      (semantic-token-name (car ntl))))))
+	      (setq ntl (cdr ntl)))
+	    (if cs1
+		(if (= num 1)
+		    (setq cs1 (concat "Added parameter " cs1))
+		  (setq cs1 (concat "Added parameters " cs1)))
+	      (setq cs1 "Removed parameters."))
+	    (setq document-runflags (cons (cons 'document-newparam cs1)
+					  document-runflags)))
+	  (let ((dif (- en st))
+		(newc nil))
+	    (delete-region st en)
+	    (setq newc (document-insert-parameters l il))
+	    (setq dif (- (length newc) dif))
+	    (insert newc)))))
+    (goto-char endpos)))
+
+;;; Conversion utilities
+;;
+(defun document-longest-name (list)
+  "Go through LIST, and return the length of the longest name."
+  (let ((longest 1)
+	(nn nil))
+    (while list
+      (setq nn (if (stringp (car list)) (car list)
+		 (semantic-token-name (car list))))
+      (if (< longest (length nn))
+	  (setq longest (length nn)))
+      (setq list (cdr list)))
+    longest))
+
+(defun document-programmer->english (programmer)
+  "Takes PROGRAMMER and converts it into English.
+Works with the following rules:
+  1) convert all _ into spaces.
+  2) inserts spaces in front of all lowerUpper case combos
+  3) expands noun names based on common programmer nouns.
+  
+  This function is designed for Variables, not functions.  This does
+not account for verb parts."
+  (let ((ind 0)				;index in string
+	(llow nil)			;lower/upper case flag
+	(wlist nil)			;list of words after breaking
+	(newstr nil)			;new string being generated
+	(al nil))			;autocomment list
+    ;;
+    ;; 1) Convert underscores
+    ;;
+    (while (< ind (length programmer))
+      (setq newstr (concat newstr
+			   (if (= (aref programmer ind) ?_)
+			       " " (char-to-string (aref programmer ind)))))
+      (setq ind (1+ ind)))
+    (setq programmer newstr
+	  newstr nil
+	  ind 0)
+    ;;
+    ;; 2) Find word brakes between case changes
+    ;;
+    (while (< ind (length programmer))
+      (setq newstr
+	    (concat newstr
+		    (let ((tc (aref programmer ind)))
+		      (if (and (>= tc ?a) (<= tc ?z))
+			  (progn
+			    (setq llow t)
+			    (char-to-string tc))
+			(if llow
+			    (progn
+			      (setq llow nil)
+			      (concat " " (char-to-string tc)))
+			  (char-to-string tc))))))
+      (setq ind (1+ ind)))
+    ;;
+    ;; 3) Expand the words if possible
+    ;;
+    (setq llow nil
+	  ind 0
+	  programmer newstr
+	  newstr nil)
+    (while (string-match (concat "^\\s-*\\([^ \t\n]+\\)") programmer)
+      (let ((ts (substring programmer (match-beginning 1) (match-end 1)))
+	    (end (match-end 1)))
+	(setq al document-autocomment-common-nouns-abbrevs)
+	(setq llow nil)
+	(while al
+	  (if (string-match (car (car al)) (downcase ts))
+	      (progn
+		(setq newstr (concat newstr (cdr (car al))))
+		;; don't terminate because we may actuall have 2 words
+		;; next to eachother we didn't identify before
+		(setq llow t)))
+	  (setq al (cdr al)))
+	(if (not llow) (setq newstr (concat newstr ts)))
+	(setq newstr (concat newstr " "))
+	(setq programmer (substring programmer end))))
+    newstr))
+
+
+;;; Sformat string managers
+;;
+;; These two routines find the string between different % tokens, and
+;; returns them as regular expressions vie regexp-quote.  The result
+;; will allow a program to find text surrounding major parts within a
+;; comment, thus, the parts in a comment that need to be changed.
+
+(defun document-just-before-token-regexp (token format)
+  "Return a search expression for text before TOKEN in FORMAT.
+This search string can be used to find the text residing in TOKEN
+if it were inserted with FORMAT in the past."
+  (setq format (document-format-for-native-comments format))
+  (sformat-just-before-token-regexp token format))
+
+(defun document-just-after-token-regexp (token format)
+  "Return a search expression for text after TOKEN in FORMAT.
+This search string can be used to find the text residing in TOKEN
+if it were inserted with FORMAT in the past."
+  (setq format (document-format-for-native-comments format))
+  (sformat-just-after-token-regexp token format))
+
+;; This function adds in the comment thingies so that the above
+;; functions can work some magic.
+(defun document-format-for-native-comments (formatstr)
+  "Return FORMATSTR with the comment formatters filled in.
+Leaves other formatting elements the way they are."
+  (Sformat (list (list ?b (document-comment-start))
+		 (list ?m (document-comment-line-prefix))
+		 (list ?e (document-comment-end)))
+	   formatstr))
+
+
+;;; Texinfo mangling.
+;;
+(defun document-massage-to-texinfo (nonterm buffer string)
+  "Massage NONTERM's documentation from BUFFER as STRING.
+This is to take advantage of TeXinfo's markup symbols."
+  (if (save-excursion (set-buffer buffer)
+		      (eq major-mode 'emacs-lisp-mode))
+      ;; Elisp has a few advantages.  Hack it in.
+      (setq string (document-texify-elisp-docstring string)))
+  ;; Else, other languages are simpler.  Also, might as well
+  ;; run the elisp version through also.
+  (let ((case-fold-search nil))
+    (while (string-match
+	    "\\(^\\|[^{]\\)\\<\\([A-Z0-9_]+\\)\\>\\($\\|[^}]\\)"
+	    string)
+      (setq string (concat (substring string 0 (match-beginning 2))
+			   "@var{"
+			   (match-string 2 string)
+			   "}"
+			   (substring string (match-end 2)))))
+    )
+  string)
+
+;; This FN was taken from EIEIO and modified.  Maybe convert later.
+(defun document-texify-elisp-docstring (string)
+  "Take STRING, (a normal doc string), and convert it into a texinfo string.
+For instances where CLASS is the class being referenced, do not Xref
+that class.
+
+ `function' => @dfn{function}
+ `variable' => @code{variable}
+ `class'    => @code{class} @xref{class}
+ `unknown'  => @code{unknonwn}
+ 'quoteme   => @code{quoteme}
+ non-nil    => non-@code{nil}
+ t          => @code{t}
+ :tag       => @code{:tag}
+ [ stuff ]  => @code{[ stuff ]}
+ Key        => @kbd{Key}     (key is C\\-h, M\\-h, SPC, RET, TAB and the like)"
+  (while (string-match "`\\([-a-zA-Z0-9]+\\)'" string)
+    (let* ((vs (substring string (match-beginning 1) (match-end 1)))
+	   (v (intern-soft vs)))
+      (setq string
+	    (concat
+	     (replace-match (concat
+			     (if (fboundp v)
+				 "@dfn{" "@code{")
+			     vs "}")
+		    nil t string)))))
+  (while (string-match "\\( \\|^\\)\\(nil\\|t\\|'[-a-zA-Z0-9]+\\|:[-a-zA-Z0-9]+\\)\\([ ,]\\|$\\)" string)
+    (setq string (replace-match "@code{\\2}" t nil string 2)))
+  (while (string-match "\\( \\|^\\)\\(\\(non-\\)\\(nil\\)\\)\\([ ,]\\|$\\)" string)
+    (setq string (replace-match "\\3@code{\\4}" t nil string 2)))
+  (while (string-match "\\( \\|^\\)\\(\\[[^]]+\\]\\)\\( \\|$\\)" string)
+    (setq string (replace-match "@code{\\2}" t nil string 2)))
+  (while (string-match "\\( \\|^\\)\\(\\(\\(C-\\|M-\\|S-\\)+\\([^ \t\n]\\|RET\\|SPC\\|TAB\\)\\)\\|\\(RET\\|SPC\\|TAB\\)\\)\\( \\|$\\)" string)
+    (setq string (replace-match "@kbd{\\2}" t nil string 2)))
+  string)
+
+;;; Buffer finding and managing
+;;
+(defun document-find-file (file)
+  "Load up the document file FILE.
+Make it current, and return a marker for the location of newly inserted
+documentation."
+  (set-buffer (find-file-noselect file))
+  ;; Theoretically, we should add some smarts here for positioning
+  ;; the cursor.  For now, do some simple stuff.
+  (if (eq (point) (point-min))
+      (progn
+	(switch-to-buffer (current-buffer))
+	(error "Position cursor in %s, and try inserting documentation again"))
+    (point-marker)))
+
+(defun document-locate-file (buffer &optional override)
+  "Return a file in which documentation belonging to BUFFER should be placed.
+Optional argument OVERRIDE indicates to override the last used location."
+  (if (and document-current-output-file (not override))
+      document-current-output-file
+    ;; Else, perform some default behaviors
+    (let ((files (if (and (fboundp 'ede-documentation-files) ede-minor-mode)
+		     (save-excursion
+		       (set-buffer buffer)
+		       (ede-documentation-files))
+		   ))
+	  (choice nil))
+      (while files
+	(setq choice (cons (list (car files)) choice)
+	      files (cdr files)))
+      (setq choice
+	    (if choice
+		(completing-read "Documentation File: "
+				 choice
+				 nil t (car choice))
+	      (read-file-name "Documentation File: "
+			      default-directory)))
+      (setq document-current-output-file (document-find-file choice)))))
+      
+
+(provide 'document)
+
+;;; document.el ends here
+# Simple BNF notation for top-level C elements.
+#
+# Copyright (C) 1999, 2000 Eric M. Ludlam
+#
+# Author: Eric M. Ludlam <zappo@gnu.org>
+# X-RCS: $Id$
+#
+# make.bnf is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This software is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Emacs; see the file COPYING.  If not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+# $Log$
+# Revision 1.3  2000/07/01 18:19:01  zappo
+# Updated for new elements in the tokens.
+#
+# Revision 1.2  2000/06/13 14:38:26  zappo
+# Added special equals and colon NTs
+#
+# Revision 1.1  2000/06/11 02:18:47  zappo
+# Initial revision
+#
+
+# TABLE: semantic-make.el:semantic-toplevel-make-bovine-table
+# MODE: make-mode
+
+bovine-toplevel : variable
+		| rule
+		| conditional
+		;
+
+variable: symbol equals elements
+	  ($1 variable nil nil $3 nil nil)
+	;
+
+rule: symbol colons elements commands
+      ($1 function nil $3 nil nil)
+    ;
+
+conditional: symbol "if" symbol newline
+	     ( nil )
+	   | symbol "else" newline
+	     ( nil )
+	   | symbol "endif" newline
+	     ( nil )
+	   ;
+
+equals: punctuation ":" punctuation "="	()
+      | punctuation "+" punctuation "="	()
+      | punctuation "="	()
+      ;
+
+colons: punctuation ":" punctuation ":" ()
+      | punctuation ":" ()
+      ;
+
+elements: symbol elements
+	  ( $1 ,$2 )
+	| symbol newline
+	  ( $1 )
+	| newline
+	  (  )
+	;
+  
+commands: shell-command newline commands
+	  ( $1 ,$2 )
+	| EMPTY
+	  ( )
+	;
+
+# End
+(pcl-cvs
+  (standards-version 1.1
+   version "1.0"
+   author-version "1.2.1"
+   date "2000-07-16"
+   build-date "2000-07-16"
+   maintainer "XEmacs Development Team <xemacs-beta@xemacs.org>"
+   distribution xemacs
+   priority low
+   category "prog"
+   dump nil
+   description "Semantic bovinator."
+   filename "semantic-1.0-pkg.tar.gz"
+   md5sum "01bc09b2434d963aefd366b216e47246"
+   size 69666
+   provides (semantic)
+   requires (xemacs-base speedbar)
+   type regular
+))
+(pcl-cvs
+  (standards-version 1.1
+   version VERSION
+   author-version AUTHOR_VERSION
+   date DATE
+   build-date BUILD_DATE
+   maintainer MAINTAINER
+   distribution xemacs
+   priority low
+   category CATEGORY
+   dump nil
+   description "Semantic bovinator."
+   filename FILENAME
+   md5sum MD5SUM
+   size SIZE
+   provides (semantic)
+   requires (REQUIRES)
+   type regular
+))
+(pcl-cvs
+  (standards-version 1.1
+   version "1.0"
+   author-version "1.2.1"
+   date "2000-07-16"
+   build-date "2000-07-16"
+   maintainer "XEmacs Development Team <xemacs-beta@xemacs.org>"
+   distribution xemacs
+   priority low
+   category "prog"
+   dump nil
+   description "Semantic bovinator."
+   filename "semantic-1.0-pkg.tar.gz"
+   md5sum "2ba12968b295a883b79b049d4ad8e49b"
+   size 73558
+   provides (semantic)
+   requires (xemacs-base speedbar)
+   type regular
+))
+;;; semantic-bnf.el --- Semantic details for some languages
+
+;;; Copyright (C) 1999, 2000 Eric M. Ludlam
+
+;; Author: Eric M. Ludlam <zappo@gnu.org>
+;; Version: 0.1
+;; Keywords: parse
+;; X-RCS: $Id$
+
+;; This file is not part of GNU Emacs.
+
+;; Semantic-bnf is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This software is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+;;
+;; Convert BNF definitions similar to bison into bovine tables.
+;;
+;; Major mode for BNF-for-emacs editing.
+;;
+;; See the semantic info file for details.
+
+;;; History:
+;; 
+
+(require 'semantic)
+
+;;; Code:
+(defvar semantic-bovine-bnf-table
+  ;; BNF's BNF
+  ;;
+  ;; rule : result punctuation ":" rule-list
+  ;;      ;
+  ;;
+  ;; result : symbol
+  ;;        ;
+  ;;
+  ;; rule-list : match-list lambda rule-or-list punctuation ";"
+  ;;           ;
+  ;;
+  ;; rule-or-list : punctuation "|" match-list lambda rule-or-list
+  ;;              | EMPTY
+  ;;              ;
+  ;;
+  ;; match-list : symbol match-list
+  ;;            | string match-list
+  ;;            | symbol
+  ;;            | string
+  ;;            ;
+  '((bovine-toplevel
+     (symbol punctuation ":" rule-list punctuation ";"
+	     (lambda (vals start end)
+	       (list (nth 0 vals) 'rule nil (nth 2 vals) start end)
+	       )))
+    (rule-list
+     (match-list lambda-fn rule-or-list
+		 (lambda (vals start end)
+		   (append (cons (cons (car (nth 1 vals)) (nth 0 vals))
+				 (nth 2 vals))
+			   (list start end))
+		   )))
+    (rule-or-list
+     (punctuation "|" match-list lambda-fn rule-or-list
+		  (lambda (vals start end)
+		    (append (cons (cons (car (nth 2 vals)) (nth 1 vals))
+				  (nth 3 vals))
+			    (list start end))
+		    ))
+     ((lambda (vals start end) (list nil))
+      ))
+    (match-list
+     (symbol match-list
+	     (lambda (vals start end)
+	       (append (cons (nth 0 vals) (nth 1 vals)) (list start end))))
+     (string match-list
+	     (lambda (vals start end)
+	       (append (cons (nth 0 vals) (nth 1 vals)) (list start end))))
+     (string)
+     (symbol)
+     )
+    (lambda-fn
+      (semantic-list
+       (lambda (vals start end)
+	 (list (buffer-substring-no-properties start end)
+	       start end)))
+      ((lambda (vals start end) (list "" start end))))
+    )
+  "Bovine table used to convert a BNF language file into a bovine table.")
+
+(defun semantic-bnf-EXPAND (lst)
+  "Insert a token expand function based on LST."
+  (let ((argv (1- (string-to-int (substring (symbol-name (car (cdr lst)))
+					    1)))))
+    (insert "\n")
+    (indent-for-tab-command)
+    (insert "(semantic-bovinate-from-nonterminal "
+	    "(car (nth " (int-to-string argv) " vals)) "
+	    "(cdr (nth " (int-to-string argv) " vals)) "
+	    "'" (symbol-name (car (cdr (cdr lst))))
+	    ")\n")
+    (indent-for-tab-command)))
+
+(defun semantic-bnf-EXPANDFULL (lst)
+  "Insert a token full expand function based on LST."
+  (let ((argv (1- (string-to-int (substring (symbol-name (car (cdr lst)))
+					    1)))))
+    (insert "\n")
+    (indent-for-tab-command)
+    (insert "(semantic-bovinate-from-nonterminal-full "
+	    "(car (nth " (int-to-string argv) " vals)) "
+	    "(cdr (nth " (int-to-string argv) " vals)) "
+	    "'" (symbol-name (car (cdr (cdr lst))))
+	    ")\n")
+    (indent-for-tab-command)))
+
+(defun semantic-bnf-lambda-substitute (lst &optional inplace)
+  "Insert LST substituting based on rules for the BNF converter.
+LST is the list in which we are substituting.
+Optional INPLACE indicates that the list is being expanded from elsewhere."
+  (if (eq (car lst) 'quote)
+      (progn
+	(setq lst (cdr lst))
+	(if (and (= (length lst) 1) (listp (car lst)))
+	    (progn
+	      (insert " (append")
+	      (semantic-bnf-lambda-substitute (car lst) nil)
+	      (insert ")")
+	      (setq lst nil inplace nil))
+	  (insert "(list")
+	  (setq inplace t))
+	)
+    (if inplace (insert " (")))
+  (cond ((eq (car lst) 'EXPAND)
+	 (semantic-bnf-EXPAND lst))
+	((eq (car lst) 'EXPANDFULL)
+	 (semantic-bnf-EXPANDFULL lst))
+	(t
+	 (let ((inlist nil))
+	   (while lst
+	     (cond ((eq (car lst) nil)
+		    (if (and (not inlist) (not inplace))
+			(progn (insert " (list")
+			       (setq inlist t)))
+		    (insert " nil"))
+		   ((listp (car lst))
+		    (let ((fn (and (symbolp (car (car lst))) (fboundp (car (car lst))))))
+		      (if (and (not inlist) (not inplace))
+			  (progn (insert " (list")
+				 (setq inlist t)))
+		      (if (and inplace (not fn) (not (eq (car (car lst)) 'EXPAND)))
+			  (insert " (append"))
+		      (semantic-bnf-lambda-substitute (car lst) (and fn (not (eq fn 'quote))))
+		      (if (and inplace (not fn) (not (eq (car (car lst)) 'EXPAND)))
+			  (insert  ")"))
+		      ))
+		   ((symbolp (car lst))
+		    (let ((n (symbol-name (car lst))) ;the name
+			  (x nil))	;expand flag
+		      (if (eq (aref n 0) ?,)
+			  (setq n (substring n 1)
+				x t))
+		      (if (string= n "")
+			  ;; We expand only the next item in place (a list?)
+			  (progn
+			    (setq lst (cdr lst))
+			    ;; A regular inline-list...
+			    (semantic-bnf-lambda-substitute (car lst) t))
+			(if (eq (aref n 0) ?$)
+			    (let ((val (1- (string-to-int (substring n 1)))))
+			      (if (and (not x) (not inlist) (not inplace))
+				  (insert " (list")
+				(if (and x inlist (not inplace))
+				    (progn (insert ")")
+					   (setq inlist nil))))
+			      (insert " (nth " (int-to-string val) " vals)")
+			      (if (and (not x) (not inplace)) (setq inlist t)))
+			  (if (and (not inlist) (not inplace))
+			      (progn (insert " (list")
+				     (setq inlist t)))
+			  (insert " " (if inplace "" "'") n)))))
+		   (t
+		    (if (and (not inlist) (not inplace))
+			(progn (insert " (list")
+			       (setq inlist t)))
+		    (insert (format " %S" (car lst)))))
+	     (setq lst (cdr lst)))
+	   (if inlist (insert ")")))))
+  (if inplace (insert ")")))
+
+(defun semantic-bnf-lambda-convert (semliststr vals)
+  "Convert SEMLISTSTR into Lisp code based on VALS.
+VALS are the matches in the BNF notation file."
+  (if (string= "" semliststr)
+      nil
+    (let ((slsr (read semliststr)))
+      ;; We converted the lambda string into a list.  Now write it
+      ;; out as the bovine lambda expression, and do macro-like
+      ;; conversion upon it.
+      (insert "\n")
+      (indent-for-tab-command)
+      (insert ",(lambda (vals start end)\n")
+      (indent-for-tab-command)
+      (cond ((eq (car slsr) 'EXPAND)
+	     (semantic-bnf-EXPAND slsr))
+	    ((and (listp (car slsr))
+		  (eq (car (car slsr)) 'EVAL))
+	     ;; The user wants to evaluate the following args.
+	     ;; Use a simpler expander
+	     )
+	    (t
+	     (insert "(append ")
+	     (semantic-bnf-lambda-substitute slsr)
+	     ;; Finish it off
+	     (insert "\n")
+	     (indent-for-tab-command)
+	     (insert "(list start end))")))
+      (insert ")"))))
+
+(defun semantic-bnf-to-bovine (file)
+  "Insert the BNF file FILE into the current buffer as a bovine table."
+  (interactive "FBNF file: ")
+  (let* ((tokstream (save-excursion
+		      (set-buffer (find-file-noselect file))
+		      (semantic-clear-toplevel-cache)
+		      (save-excursion
+			(goto-char (point-min))
+			(semantic-bovinate-toplevel 0 t))))
+	 (tl (float (length tokstream))))
+    (insert "`(")
+    (indent-for-tab-command)
+    (working-status-forms "Building bovine table" "done"
+      (while tokstream
+	;; Each element is a top level match, of the form:
+	;; ( RESULT MATCH1 MATCH2 ... )
+	;; where a match is of the form:
+	;; ( LAMBDA-STRING TOKEN1 TOKEN2 ... )
+	(let* ((rule (car tokstream))
+	       (matches (car (cdr (cdr (cdr rule))))))
+	  (insert "(" (car rule) "\n")
+	  (indent-for-tab-command)
+	  (while matches
+	    (let* ((mla (car matches))
+		   (lamb (car mla))
+		   (ml (cdr mla)))
+	      (insert "(")
+	      (if (and (= (length ml) 1) (string= (car ml) "EMPTY"))
+		  nil
+		(while ml
+		  (insert " " (car ml))
+		  (setq ml (cdr ml))))
+	      (semantic-bnf-lambda-convert lamb (car (cdr mla)))
+	      (insert ")\n")
+	      (indent-for-tab-command))
+	    (setq matches (cdr matches)))
+	  (insert ") ; end " (car rule) "\n")
+	  (indent-for-tab-command))
+	(setq tokstream (cdr tokstream))
+	(working-status (* 100.0 (- 1.0 (/ (float (length tokstream)) tl)))))
+      (working-status t))
+    (insert ")\n")
+    ))
+
+(defun semantic-bnf-find-destination ()
+  "Find the destination file for this BNF file."
+  (save-excursion
+    (goto-char (point-min))
+    (if (re-search-forward
+	 "^# TABLE: \\([-a-zA-Z0-9_-]+\\.el\\):\\([-a-zA-Z0-9_]+\\)$"
+	 nil t)
+	(save-excursion
+	  (let ((f (match-string 1))
+		(v (match-string 2)))
+	    (set-buffer (find-file-noselect f))
+	    (goto-char (point-min))
+	    (if (re-search-forward (concat "def\\(var\\|const\\)\\s-+"
+					   (regexp-quote v)) nil t)
+		(progn
+		  (goto-char (match-beginning 0))
+		  (point-marker)))))
+      nil)))
+
+(defun semantic-bnf-find-mode ()
+  "Find the mode this BNF is used in."
+  (save-excursion
+    (goto-char (point-min))
+    (if (re-search-forward "^# MODE: \\([-a-z]+\\)$" nil t)
+	(save-excursion
+	  (let ((m (match-string 1)))
+	    (read m)))
+      nil)))
+
+(defun semantic-bnf-generate-and-load ()
+  "Take the current BNF, auto-generate it into a table, and load it."
+  (interactive)
+  (if (not (eq major-mode 'semantic-bnf-mode))
+      (error "Not valid outside the scope of a BNF file"))
+  (let ((bb (current-buffer))
+	(dest (semantic-bnf-find-destination))
+	(mode (semantic-bnf-find-mode)))
+    (if (not dest)
+	(error "You must specify a destination table in your BNF file"))
+    (save-excursion
+      (set-buffer (marker-buffer dest))
+      (goto-char dest)
+      (re-search-forward "def\\(var\\|const\\)\\s-+\\(\\w\\|\\s_\\)+\\s-*\n")
+      (if (looking-at "\\s-*`(") (kill-sexp 1))
+      (delete-blank-lines)
+      (semantic-bnf-to-bovine (buffer-file-name bb))
+      (eval-defun nil))
+    (if mode
+	(save-excursion
+	  (let ((bufs (buffer-list)))
+	    (while bufs
+	      (set-buffer (car bufs))
+	      (if (eq major-mode mode)
+		  (funcall mode))
+	      (setq bufs (cdr bufs))))))))
+
+(defun semantic-test-bnf ()
+  "Convert the current buffer (in BNF mode) into a list bovine table."
+  (interactive)
+  (let ((bb (current-buffer)))
+    (switch-to-buffer "*BNF CONVERT*")
+    (emacs-lisp-mode)
+    (erase-buffer)
+    (semantic-bnf-to-bovine (buffer-file-name bb))))
+
+;;; Semantic BNF mode
+;;
+;; Major mode for editing BNF files.  More importantly, define a syntax
+;; table so that the semantic do-whatsis will work correctly.
+(defvar semantic-bnf-syntax-table nil
+  "Syntax used in a BNF buffer.")
+
+(if semantic-bnf-syntax-table
+    nil
+  (setq semantic-bnf-syntax-table (make-syntax-table (standard-syntax-table)))
+  (modify-syntax-entry ?: "." semantic-bnf-syntax-table)
+  (modify-syntax-entry ?| "." semantic-bnf-syntax-table)
+  (modify-syntax-entry ?\; "." semantic-bnf-syntax-table)
+  (modify-syntax-entry ?\" "\"" semantic-bnf-syntax-table)
+  (modify-syntax-entry ?- "_" semantic-bnf-syntax-table)
+  (modify-syntax-entry ?( "(" semantic-bnf-syntax-table)
+  (modify-syntax-entry ?) ")(" semantic-bnf-syntax-table)
+  (modify-syntax-entry ?# "<" semantic-bnf-syntax-table)
+  (modify-syntax-entry ?\n ">" semantic-bnf-syntax-table)
+  'foo
+  )
+
+(defvar semantic-bnf-mode-hook nil
+  "Hook run when starting BNF mode.")
+
+(defvar semantic-bnf-mode-keywords
+  '(("^\\(\\w+\\)\\s-*:" 1 font-lock-function-name-face)
+    ("\\<\\(EMPTY\\|symbol\\|punctuation\\|string\\|semantic-list\
+\\|\\(open\\|close\\)-paren\\|comment\\)\\>"
+     1 font-lock-keyword-face)
+    ("\\$[0-9]+" 0 font-lock-variable-name-face)
+    )
+  "Font Lock keywords used to highlight BNF buffer.")
+
+(defvar semantic-bnf-map nil
+  "Keymap used in `semantic-bnf-mode'.")
+
+(if semantic-bnf-map
+    nil
+  (setq semantic-bnf-map (make-sparse-keymap))
+  (define-key semantic-bnf-map "\t" 'semantic-bnf-indent)
+  (define-key semantic-bnf-map "|" 'semantic-bnf-electric-punctuation)
+  (define-key semantic-bnf-map ";" 'semantic-bnf-electric-punctuation)
+  (define-key semantic-bnf-map "#" 'semantic-bnf-electric-punctuation)
+  (define-key semantic-bnf-map "\C-c\C-c" 'semantic-bnf-generate-and-load)
+  )
+
+(speedbar-add-supported-extension ".bnf")
+
+(defun semantic-bnf-mode ()
+  "Initialize a buffer for editing BNF code."
+  (interactive)
+  (kill-all-local-variables)
+  (setq major-mode 'semantic-bnf-mode
+	mode-name "BNF")
+  (set-syntax-table semantic-bnf-syntax-table)
+  (use-local-map semantic-bnf-map)
+  (make-local-variable 'semantic-toplevel-bovine-table)
+  (setq semantic-toplevel-bovine-table semantic-bovine-bnf-table)
+  (make-local-variable 'indent-line-function)
+  (setq indent-line-function 'semantic-bnf-indent)
+  (make-local-variable 'font-lock-defaults)
+  (setq font-lock-defaults '((semantic-bnf-mode-keywords)
+			     nil ; do not do string/comment highlighting
+			     nil ; keywords are case insensitive.
+			     ;; This puts _ & - as a word constituant,
+			     ;; simplifying our keywords significantly
+			     ((?_ . "w") (?- . "w"))))
+  (run-hooks 'semantic-bnf-mode-hook))
+
+(defun semantic-bnf-electric-punctuation ()
+  "Insert and reindent for the symbol just typed in."
+  (interactive)
+  (self-insert-command 1)
+  (semantic-bnf-indent))
+
+(defun semantic-bnf-indent ()
+  "Indent the current line according to BNF rules."
+  (interactive)
+  (save-excursion
+    (beginning-of-line)
+    (let ((indent (current-indentation)))
+      (if (looking-at "\\s-*\\(\\w\\|\\s_\\)+\\s-*:")
+	  (delete-horizontal-space)
+	(save-excursion
+	  (forward-line -1)
+	  (if (looking-at "\\s-*\\(\\w\\|\\s_\\)+\\s-*:")
+	      (setq indent (- (match-end 0) (point) 1))
+	    (if (looking-at "\\s-*;")
+		(setq indent 0)
+	      (if (looking-at "\\s-*[|#]")
+		  (setq indent (current-indentation))
+		(setq indent (- (current-indentation) 2))))))
+	(if (not (looking-at "\\s-*[|;#]"))
+	    (setq indent (+ 2 indent)))
+	(if (= (current-indentation) indent)
+	    nil
+	  (delete-horizontal-space)
+	  (indent-to indent)))))
+  (if (bolp) (if (looking-at "\\s-+") (end-of-line))))
+
+(add-to-list 'auto-mode-alist '("\\.bnf$" . semantic-bnf-mode))
+	     
+
+(provide 'semantic-bnf)
+
+;;; semantic-bnf.el ends here

Binary file added.

+;;; semantic-c.el --- Semantic details for C
+
+;;; Copyright (C) 1999, 2000 Eric M. Ludlam
+
+;; Author: Eric M. Ludlam <zappo@gnu.org>
+;; X-RCS: $Id$
+
+;; This file is not part of GNU Emacs.
+