Browse Source

add customizable dc keywords

David Rose 20 years ago
parent
commit
2cc8ea03b8

+ 4 - 1
direct/src/dcparser/Sources.pp

@@ -18,7 +18,9 @@
   #define SOURCES \
      dcAtomicField.h dcClass.h dcClass.I \
      dcDeclaration.h \
-     dcField.h dcFile.h dcLexer.lxx  \
+     dcField.h dcFile.h \
+     dcKeyword.h dcKeywordList.h \
+     dcLexer.lxx  \
      dcLexerDefs.h dcMolecularField.h dcParser.yxx dcParserDefs.h  \
      dcSubatomicType.h \
      dcPackData.h dcPackData.I \
@@ -38,6 +40,7 @@
      dcAtomicField.cxx dcClass.cxx \
      dcDeclaration.cxx \
      dcField.cxx dcFile.cxx \
+     dcKeyword.cxx dcKeywordList.cxx \
      dcMolecularField.cxx dcSubatomicType.cxx \
      dcPackData.cxx \
      dcPacker.cxx \

+ 3 - 2
direct/src/dcparser/dcAtomicField.cxx

@@ -202,7 +202,7 @@ output(ostream &out, bool brief) const {
   }
   out << ")";
 
-  output_flags(out);
+  output_keywords(out);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -237,7 +237,8 @@ generate_hash(HashGenerator &hashgen) const {
   for (ei = _elements.begin(); ei != _elements.end(); ++ei) {
     (*ei)->generate_hash(hashgen);
   }
-  hashgen.add_int(get_flags());
+
+  DCKeywordList::generate_hash(hashgen);
 }
 
 ////////////////////////////////////////////////////////////////////

+ 9 - 89
direct/src/dcparser/dcField.cxx

@@ -38,7 +38,6 @@ DCField()
 #endif
 {
   _number = -1;
-  _flags = 0;
   _has_default_value = false;
   _default_value_stale = true;
 
@@ -65,7 +64,6 @@ DCField(const string &name, DCClass *dclass) :
 #endif
 {
   _number = -1;
-  _flags = 0;
   _has_default_value = false;
   _default_value_stale = true;
 
@@ -288,7 +286,7 @@ get_default_value() const {
 ////////////////////////////////////////////////////////////////////
 bool DCField::
 is_required() const {
-  return (_flags & F_required) != 0;
+  return has_keyword("required");
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -299,7 +297,7 @@ is_required() const {
 ////////////////////////////////////////////////////////////////////
 bool DCField::
 is_broadcast() const {
-  return (_flags & F_broadcast) != 0;
+  return has_keyword("broadcast");
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -310,7 +308,7 @@ is_broadcast() const {
 ////////////////////////////////////////////////////////////////////
 bool DCField::
 is_p2p() const {
-  return (_flags & F_p2p) != 0;
+  return has_keyword("p2p");
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -321,7 +319,7 @@ is_p2p() const {
 ////////////////////////////////////////////////////////////////////
 bool DCField::
 is_ram() const {
-  return (_flags & F_ram) != 0;
+  return has_keyword("ram");
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -332,7 +330,7 @@ is_ram() const {
 ////////////////////////////////////////////////////////////////////
 bool DCField::
 is_db() const {
-  return (_flags & F_db) != 0;
+  return has_keyword("db");
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -343,7 +341,7 @@ is_db() const {
 ////////////////////////////////////////////////////////////////////
 bool DCField::
 is_clsend() const {
-  return (_flags & F_clsend) != 0;
+  return has_keyword("clsend");
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -354,7 +352,7 @@ is_clsend() const {
 ////////////////////////////////////////////////////////////////////
 bool DCField::
 is_clrecv() const {
-  return (_flags & F_clrecv) != 0;
+  return has_keyword("clrecv");
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -365,7 +363,7 @@ is_clrecv() const {
 ////////////////////////////////////////////////////////////////////
 bool DCField::
 is_ownsend() const {
-  return (_flags & F_ownsend) != 0;
+  return has_keyword("ownsend");
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -376,19 +374,7 @@ is_ownsend() const {
 ////////////////////////////////////////////////////////////////////
 bool DCField::
 is_airecv() const {
-  return (_flags & F_airecv) != 0;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DCField::compare_flags
-//       Access: Published
-//  Description: Returns true if this field has the same flags
-//               settings as the other field, false if some flags
-//               differ.
-////////////////////////////////////////////////////////////////////
-bool DCField::
-compare_flags(const DCField &other) const {
-  return _flags == other._flags;
+  return has_keyword("airecv");
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -720,36 +706,6 @@ set_default_value(const string &default_value) {
   _default_value_stale = false;
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: DCField::add_flag
-//       Access: Public
-//  Description: Adds a new flag to the field.
-////////////////////////////////////////////////////////////////////
-void DCField::
-add_flag(enum Flags flag) {
-  _flags |= flag;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DCField::set_flags
-//       Access: Public
-//  Description: Resets the flag bitmask to the indicated value.
-////////////////////////////////////////////////////////////////////
-void DCField::
-set_flags(int flags) {
-  _flags = flags;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DCField::get_flags
-//       Access: Public
-//  Description: Returns the complete flag bitmask.
-////////////////////////////////////////////////////////////////////
-int DCField::
-get_flags() const {
-  return _flags;
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: DCField::refresh_default_value
 //       Access: Protected
@@ -768,39 +724,3 @@ refresh_default_value() {
   }
   _default_value_stale = false;
 }
-
-////////////////////////////////////////////////////////////////////
-//     Function: DCField::output_flags
-//       Access: Protected
-//  Description: 
-////////////////////////////////////////////////////////////////////
-void DCField::
-output_flags(ostream &out) const {
-  if ((_flags & F_required) != 0) {
-    out << " required";
-  }
-  if ((_flags & F_broadcast) != 0) {
-    out << " broadcast";
-  }
-  if ((_flags & F_p2p) != 0) {
-    out << " p2p";
-  }
-  if ((_flags & F_ram) != 0) {
-    out << " ram";
-  }
-  if ((_flags & F_db) != 0) {
-    out << " db";
-  }
-  if ((_flags & F_clsend) != 0) {
-    out << " clsend";
-  }
-  if ((_flags & F_clrecv) != 0) {
-    out << " clrecv";
-  }
-  if ((_flags & F_ownsend) != 0) {
-    out << " ownsend";
-  }
-  if ((_flags & F_airecv) != 0) {
-    out << " airecv";
-  }
-}

+ 2 - 28
direct/src/dcparser/dcField.h

@@ -21,6 +21,7 @@
 
 #include "dcbase.h"
 #include "dcPackerInterface.h"
+#include "dcKeywordList.h"
 #include "dcPython.h"
 
 #ifdef WITHIN_PANDA
@@ -40,7 +41,7 @@ class HashGenerator;
 // Description : A single field of a Distributed Class, either atomic
 //               or molecular.
 ////////////////////////////////////////////////////////////////////
-class EXPCL_DIRECT DCField : public DCPackerInterface {
+class EXPCL_DIRECT DCField : public DCPackerInterface, public DCKeywordList {
 public:
   DCField();
   DCField(const string &name, DCClass *dclass);
@@ -76,8 +77,6 @@ PUBLISHED:
   bool is_ownsend() const;
   bool is_airecv() const;
 
-  bool compare_flags(const DCField &other) const;
-
   void output(ostream &out) const;
   void write(ostream &out, int indent_level) const;
 
@@ -101,31 +100,8 @@ public:
   void set_number(int number);
   void set_default_value(const string &default_value);
 
-  enum Flags {
-    F_required        = 0x0001,
-    F_broadcast       = 0x0002,
-    F_p2p             = 0x0004,
-    F_ram             = 0x0008,
-    F_db              = 0x0010,
-    F_clsend          = 0x0020,
-    F_clrecv          = 0x0040,
-    F_ownsend         = 0x0080,
-    F_airecv          = 0x0100,
-
-    // These are reserved for client code use; they are not set or
-    // cleared by any code in this module.
-    F_user_1          = 0x1000,
-    F_user_2          = 0x2000,
-    F_user_3          = 0x4000,
-    F_user_4          = 0x8000,
-  };
-  void add_flag(enum Flags flag);
-  void set_flags(int flags);
-  int get_flags() const;
-
 protected:
   void refresh_default_value();
-  void output_flags(ostream &out) const;
 
 protected:
   int _number;
@@ -133,8 +109,6 @@ protected:
   bool _has_default_value;
 
 private:
-  int _flags;  // A bitmask union of any of the above values.
-
   string _default_value;
 
 #ifdef WITHIN_PANDA

+ 105 - 0
direct/src/dcparser/dcFile.cxx

@@ -22,6 +22,7 @@
 #include "dcParserDefs.h"
 #include "dcLexerDefs.h"
 #include "dcTypedef.h"
+#include "dcKeyword.h"
 #include "hashGenerator.h"
 
 #ifdef WITHIN_PANDA
@@ -41,6 +42,8 @@
 DCFile::
 DCFile() {
   _all_objects_valid = true;
+
+  setup_default_keywords();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -74,8 +77,10 @@ clear() {
   _things_by_name.clear();
   _typedefs.clear();
   _typedefs_by_name.clear();
+  _keywords.clear_keywords();
   _declarations.clear();
   _things_to_delete.clear();
+  setup_default_keywords();
 
   _all_objects_valid = true;
 }
@@ -439,6 +444,48 @@ get_typedef_by_name(const string &name) const {
   return NULL;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: DCFile::get_num_keywords
+//       Access: Published
+//  Description: Returns the number of keywords read from the .dc
+//               file(s).
+////////////////////////////////////////////////////////////////////
+int DCFile::
+get_num_keywords() const {
+  return _keywords.get_num_keywords();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCFile::get_keyword
+//       Access: Published
+//  Description: Returns the nth keyword read from the .dc file(s).
+////////////////////////////////////////////////////////////////////
+const DCKeyword *DCFile::
+get_keyword(int n) const {
+  return _keywords.get_keyword(n);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCFile::get_keyword_by_name
+//       Access: Published
+//  Description: Returns the keyword that has the indicated name, or
+//               NULL if there is no such keyword name.
+////////////////////////////////////////////////////////////////////
+const DCKeyword *DCFile::
+get_keyword_by_name(const string &name) const {
+  const DCKeyword *keyword = _keywords.get_keyword_by_name(name);
+  if (keyword == (const DCKeyword *)NULL) {
+    keyword = _default_keywords.get_keyword_by_name(name);
+    if (keyword != (const DCKeyword *)NULL) {
+      // One of the historical default keywords was used, but wasn't
+      // defined.  Define it implicitly right now.
+      ((DCFile *)this)->_keywords.add_keyword(keyword);
+    }
+  }
+
+  return keyword;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: DCFile::get_hash
 //       Access: Published
@@ -597,6 +644,28 @@ add_typedef(DCTypedef *dtypedef) {
   return true;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: DCFile::add_keyword
+//       Access: Public
+//  Description: Adds the indicated keyword string to the list of
+//               keywords known to the DCFile.  These keywords may
+//               then be added to DCFields.  It is not an error to add
+//               a particular keyword more than once.
+////////////////////////////////////////////////////////////////////
+bool DCFile::
+add_keyword(const string &name) {
+  DCKeyword *keyword = new DCKeyword(name);
+  bool added = _keywords.add_keyword(keyword);
+
+  if (added) {
+    _declarations.push_back(keyword);
+  } else {
+    delete keyword;
+  }
+
+  return added;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: DCFile::add_thing_to_delete
 //       Access: Public
@@ -624,3 +693,39 @@ set_new_index_number(DCField *field) {
   field->set_number((int)_fields_by_index.size());
   _fields_by_index.push_back(field);
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCFile::setup_default_keywords
+//       Access: Public
+//  Description: Adds an entry for each of the default keywords that
+//               are defined for every DCFile for legacy reasons.
+////////////////////////////////////////////////////////////////////
+void DCFile::
+setup_default_keywords() {
+  struct KeywordDef {
+    const char *name;
+    int flag;
+  };
+  static KeywordDef default_keywords[] = {
+    { "required", 0x0001 },
+    { "broadcast", 0x0002 },
+    { "p2p", 0x0004 },
+    { "ram", 0x0008 },
+    { "db", 0x0010 },
+    { "clsend", 0x0020 },
+    { "clrecv", 0x0040 },
+    { "ownsend", 0x0080 },
+    { "airecv", 0x0100 },
+    { NULL, 0 }
+  };
+
+  _default_keywords.clear_keywords();
+  for (int i = 0; default_keywords[i].name != NULL; ++i) {
+    DCKeyword *keyword = 
+      new DCKeyword(default_keywords[i].name, 
+                    default_keywords[i].flag);
+    
+    _default_keywords.add_keyword(keyword);
+    _things_to_delete.push_back(keyword);
+  }
+}

+ 12 - 0
direct/src/dcparser/dcFile.h

@@ -20,12 +20,14 @@
 #define DCFILE_H
 
 #include "dcbase.h"
+#include "dcKeywordList.h"
 
 class DCClass;
 class DCSwitch;
 class DCField;
 class HashGenerator;
 class DCTypedef;
+class DCKeyword;
 class DCDeclaration;
 
 ////////////////////////////////////////////////////////////////////
@@ -68,6 +70,10 @@ PUBLISHED:
   DCTypedef *get_typedef(int n) const;
   DCTypedef *get_typedef_by_name(const string &name) const;
 
+  int get_num_keywords() const;
+  const DCKeyword *get_keyword(int n) const;
+  const DCKeyword *get_keyword_by_name(const string &name) const;
+
   unsigned long get_hash() const;
 
 public:
@@ -77,11 +83,14 @@ public:
   void add_import_module(const string &import_module);
   void add_import_symbol(const string &import_symbol);
   bool add_typedef(DCTypedef *dtypedef);
+  bool add_keyword(const string &name);
   void add_thing_to_delete(DCDeclaration *decl);
 
   void set_new_index_number(DCField *field);
 
 private:
+  void setup_default_keywords();
+
   typedef pvector<DCClass *> Classes;
   Classes _classes;
 
@@ -104,6 +113,9 @@ private:
   typedef pmap<string, DCTypedef *> TypedefsByName;
   TypedefsByName _typedefs_by_name;
 
+  DCKeywordList _keywords;
+  DCKeywordList _default_keywords;
+
   typedef pvector<DCDeclaration *> Declarations;
   Declarations _declarations;
   Declarations _things_to_delete;

+ 111 - 0
direct/src/dcparser/dcKeyword.cxx

@@ -0,0 +1,111 @@
+// Filename: dcKeyword.cxx
+// Created by:  drose (22Jul05)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "dcKeyword.h"
+#include "hashGenerator.h"
+#include "dcindent.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeyword::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+DCKeyword::
+DCKeyword(const string &name, int historical_flag) :
+  _name(name),
+  _historical_flag(historical_flag)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeyword::Destructor
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+DCKeyword::
+~DCKeyword() {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeyword::get_name
+//       Access: Published
+//  Description: Returns the name of this keyword.
+////////////////////////////////////////////////////////////////////
+const string &DCKeyword::
+get_name() const {
+  return _name;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeyword::get_historical_flag
+//       Access: Public
+//  Description: Returns the bitmask associated with this keyword, if
+//               any.  This is the value that was historically
+//               associated with this keyword, and was used to
+//               generate a hash code before we had user-customizable
+//               keywords.  It will return ~0 if this is not an
+//               historical keyword.
+////////////////////////////////////////////////////////////////////
+int DCKeyword::
+get_historical_flag() const {
+  return _historical_flag;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeyword::clear_historical_flag
+//       Access: Public
+//  Description: Resets the historical flag to ~0, as if the keyword
+//               were not one of the historically defined keywords.
+////////////////////////////////////////////////////////////////////
+void DCKeyword::
+clear_historical_flag() {
+  _historical_flag = ~0;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function : DCKeyword::output
+//       Access : Public, Virtual
+//  Description : Write a string representation of this instance to
+//                <out>.
+////////////////////////////////////////////////////////////////////
+void DCKeyword::
+output(ostream &out, bool brief) const {
+  out << "keyword " << _name;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeyword::write
+//       Access: Public, Virtual
+//  Description: 
+////////////////////////////////////////////////////////////////////
+void DCKeyword::
+write(ostream &out, bool, int indent_level) const {
+  indent(out, indent_level)
+    << "keyword " << _name << ";\n";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeyword::generate_hash
+//       Access: Public
+//  Description: Accumulates the properties of this keyword into the
+//               hash.
+////////////////////////////////////////////////////////////////////
+void DCKeyword::
+generate_hash(HashGenerator &hashgen) const {
+  hashgen.add_string(_name);
+}

+ 59 - 0
direct/src/dcparser/dcKeyword.h

@@ -0,0 +1,59 @@
+// Filename: dcKeyword.h
+// Created by:  drose (22Jul05)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef DCKEYWORD_H
+#define DCKEYWORD_H
+
+#include "dcbase.h"
+#include "dcDeclaration.h"
+
+class DCParameter;
+class HashGenerator;
+
+////////////////////////////////////////////////////////////////////
+//       Class : DCKeyword
+// Description : This represents a single keyword declaration in the
+//               dc file.  It is used to define a communication
+//               property associated with a field, for instance
+//               "broadcast" or "airecv".
+////////////////////////////////////////////////////////////////////
+class EXPCL_DIRECT DCKeyword : public DCDeclaration {
+public:
+  DCKeyword(const string &name, int historical_flag = ~0);
+  virtual ~DCKeyword();
+
+PUBLISHED:
+  const string &get_name() const;
+
+public:
+  int get_historical_flag() const;
+  void clear_historical_flag();
+
+  virtual void output(ostream &out, bool brief) const;
+  virtual void write(ostream &out, bool brief, int indent_level) const;
+  void generate_hash(HashGenerator &hashgen) const;
+
+private:
+  const string _name;
+
+  // This flag is only kept for historical reasons, so we can preserve
+  // the file's hash code if no new flags are in use.
+  int _historical_flag;
+};
+
+#endif

+ 220 - 0
direct/src/dcparser/dcKeywordList.cxx

@@ -0,0 +1,220 @@
+// Filename: dcKeywordList.cxx
+// Created by:  drose (25Jul05)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "dcKeywordList.h"
+#include "dcKeyword.h"
+#include "hashGenerator.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+DCKeywordList::
+DCKeywordList() :
+  _flags(0)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::Copy Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+DCKeywordList::
+DCKeywordList(const DCKeywordList &copy) :
+  _keywords(copy._keywords),
+  _keywords_by_name(copy._keywords_by_name),
+  _flags(copy._flags)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::Copy Assignment Operator
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+void DCKeywordList::
+operator = (const DCKeywordList &copy) {
+  _keywords = copy._keywords;
+  _keywords_by_name = copy._keywords_by_name;
+  _flags = copy._flags;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::Destructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+DCKeywordList::
+~DCKeywordList() {
+  nassertv(_keywords_by_name.size() == _keywords.size());
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::has_keyword
+//       Access: Published
+//  Description: Returns true if this list includes the indicated
+//               keyword, false otherwise.
+////////////////////////////////////////////////////////////////////
+bool DCKeywordList::
+has_keyword(const string &name) const {
+  return (_keywords_by_name.find(name) != _keywords_by_name.end());
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::has_keyword
+//       Access: Published
+//  Description: Returns true if this list includes the indicated
+//               keyword, false otherwise.
+////////////////////////////////////////////////////////////////////
+bool DCKeywordList::
+has_keyword(const DCKeyword *keyword) const {
+  return has_keyword(keyword->get_name());
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::get_num_keywords
+//       Access: Published
+//  Description: Returns the number of keywords in the list.
+////////////////////////////////////////////////////////////////////
+int DCKeywordList::
+get_num_keywords() const {
+  nassertr(_keywords_by_name.size() == _keywords.size(), 0);
+  return _keywords.size();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::get_keyword
+//       Access: Published
+//  Description: Returns the nth keyword in the list.
+////////////////////////////////////////////////////////////////////
+const DCKeyword *DCKeywordList::
+get_keyword(int n) const {
+  nassertr(n >= 0 && n < (int)_keywords.size(), NULL);
+  return _keywords[n];
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::get_keyword_by_name
+//       Access: Published
+//  Description: Returns the keyword in the list with the indicated
+//               name, or NULL if there is no keyword in the list with
+//               that name.
+////////////////////////////////////////////////////////////////////
+const DCKeyword *DCKeywordList::
+get_keyword_by_name(const string &name) const {
+  KeywordsByName::const_iterator ni;
+  ni = _keywords_by_name.find(name);
+  if (ni != _keywords_by_name.end()) {
+    return (*ni).second;
+  }
+
+  return NULL;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::compare_keywords
+//       Access: Published
+//  Description: Returns true if this list has the same keywords
+//               as the other list, false if some keywords differ.
+//               Order is not considered important.
+////////////////////////////////////////////////////////////////////
+bool DCKeywordList::
+compare_keywords(const DCKeywordList &other) const {
+  return _keywords_by_name == other._keywords_by_name;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::copy_keywords
+//       Access: Public
+//  Description: Replaces this keyword list with those from the other
+//               list.
+////////////////////////////////////////////////////////////////////
+void DCKeywordList::
+copy_keywords(const DCKeywordList &other) {
+  (*this) = other;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::add_keyword
+//       Access: Public
+//  Description: Adds the indicated keyword to the list.  Returns true
+//               if it is added, false if it was already there.
+////////////////////////////////////////////////////////////////////
+bool DCKeywordList::
+add_keyword(const DCKeyword *keyword) {
+  bool inserted = _keywords_by_name.insert(KeywordsByName::value_type(keyword->get_name(), keyword)).second;
+  if (inserted) {
+    _keywords.push_back(keyword);
+    _flags |= keyword->get_historical_flag();
+  }
+
+  return inserted;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::clear_keywords
+//       Access: Public
+//  Description: Removes all keywords from the field.
+////////////////////////////////////////////////////////////////////
+void DCKeywordList::
+clear_keywords() {
+  _keywords.clear();
+  _keywords_by_name.clear();
+  _flags = 0;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::output_keywords
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+void DCKeywordList::
+output_keywords(ostream &out) const {
+  Keywords::const_iterator ki;
+  for (ki = _keywords.begin(); ki != _keywords.end(); ++ki) {
+    out << " " << (*ki)->get_name();
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DCKeywordList::generate_hash
+//       Access: Public
+//  Description: Accumulates the properties of these keywords into the
+//               hash.
+////////////////////////////////////////////////////////////////////
+void DCKeywordList::
+generate_hash(HashGenerator &hashgen) const {
+  if (_flags != ~0) {
+    // All of the flags are historical flags only, so add just the
+    // flags bitmask to keep the hash code the same as it has
+    // historically been.
+    hashgen.add_int(_flags);
+
+  } else {
+    // There is at least one custom flag, so go ahead and make the
+    // hash code reflect it.
+
+    hashgen.add_int(_keywords_by_name.size());
+    KeywordsByName::const_iterator ni;
+    for (ni = _keywords_by_name.begin(); ni != _keywords_by_name.end(); ++ni) {
+      (*ni).second->generate_hash(hashgen);
+    }
+  }
+}

+ 67 - 0
direct/src/dcparser/dcKeywordList.h

@@ -0,0 +1,67 @@
+// Filename: dcKeywordList.h
+// Created by:  drose (25Jul05)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef DCKEYWORDLIST_H
+#define DCKEYWORDLIST_H
+
+#include "dcbase.h"
+
+class DCKeyword;
+class HashGenerator;
+
+////////////////////////////////////////////////////////////////////
+//       Class : DCKeywordList
+// Description : This is a list of keywords (see DCKeyword) that may
+//               be set on a particular field.
+////////////////////////////////////////////////////////////////////
+class EXPCL_DIRECT DCKeywordList {
+public:
+  DCKeywordList();
+  DCKeywordList(const DCKeywordList &copy);
+  void operator = (const DCKeywordList &copy);
+  ~DCKeywordList();
+
+PUBLISHED:
+  bool has_keyword(const string &name) const;
+  bool has_keyword(const DCKeyword *keyword) const;
+  int get_num_keywords() const;
+  const DCKeyword *get_keyword(int n) const;
+  const DCKeyword *get_keyword_by_name(const string &name) const;
+
+  bool compare_keywords(const DCKeywordList &other) const;
+
+public:
+  void copy_keywords(const DCKeywordList &other);
+
+  bool add_keyword(const DCKeyword *keyword);
+  void clear_keywords();
+
+  void output_keywords(ostream &out) const;
+  void generate_hash(HashGenerator &hashgen) const;
+
+private:
+  typedef pvector<const DCKeyword *> Keywords;
+  Keywords _keywords;
+
+  typedef pmap<string, const DCKeyword *> KeywordsByName;
+  KeywordsByName _keywords_by_name;
+
+  int _flags;
+};
+
+#endif

+ 218 - 290
direct/src/dcparser/dcLexer.cxx.prebuilt

@@ -300,32 +300,28 @@ static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
 	*yy_cp = '\0'; \
 	yy_c_buf_p = yy_cp;
 
-#define YY_NUM_RULES 52
-#define YY_END_OF_BUFFER 53
-static yyconst short int yy_accept[201] =
+#define YY_NUM_RULES 44
+#define YY_END_OF_BUFFER 45
+static yyconst short int yy_accept[165] =
     {   0,
-        0,    0,   53,   51,    2,    1,   47,   48,   51,   51,
-       51,   43,   43,   49,   50,   50,   50,   50,   50,   50,
-       50,   50,   50,   50,   50,   50,   50,    1,    0,   44,
-       46,    4,    3,   46,   43,   45,   50,   50,   50,   50,
-       50,   50,   50,   38,   50,   50,   50,   50,   50,   50,
-       50,   50,   50,   50,   50,   50,   50,   50,    0,    3,
-       45,   50,   50,   50,   50,   50,   50,   50,   50,   50,
-       50,   50,   50,   50,   50,   50,   36,   37,   50,   50,
-       50,   50,   50,    0,   46,   50,   24,   50,   50,   11,
-       33,   50,   50,   50,   50,   50,    7,   50,   50,   50,
-
-       50,   14,   50,   50,   50,   50,   50,   50,   50,   50,
-       50,   13,   50,   50,   50,   50,   50,   50,   50,   15,
-       16,   17,   50,   50,   50,   50,   50,   50,   50,   50,
-       50,   50,   18,   42,   25,   50,   40,   39,    5,   50,
-       50,    8,   50,   50,   50,   50,   50,   23,    6,   10,
-       50,   19,   20,   21,   50,   50,   12,   22,   50,   50,
-       50,   41,   50,    9,   50,   50,   50,   50,   50,   50,
-       50,   50,   34,   50,   50,   50,   50,   35,   50,   50,
-       26,   50,   50,   50,   50,   27,   28,   50,   50,   50,
-       29,   30,   31,   50,   50,   50,   50,   50,   32,    0
-
+        0,    0,   45,   43,    2,    1,   39,   40,   43,   43,
+       43,   35,   35,   41,   42,   42,   42,   42,   42,   42,
+       42,   42,   42,   42,    1,    0,   36,   38,    4,    3,
+       38,   35,   37,   42,   42,   42,   42,   42,   42,   42,
+       42,   42,   42,   42,   42,   42,   42,   42,   42,    0,
+        3,   37,   42,   42,   42,   42,   42,   42,   42,   42,
+       42,   42,   42,   42,   42,   42,   42,    0,   38,   25,
+       42,   12,   34,   42,   42,   42,    7,   42,   42,   42,
+       42,   15,   42,   42,   42,   42,   42,   42,   42,   14,
+       42,   42,   42,   42,   16,   17,   18,   42,   42,   42,
+
+       42,   42,   42,   42,   42,   42,   19,   26,    5,   42,
+       42,    8,   42,   42,   42,   42,   24,    6,   11,   42,
+       20,   21,   22,   42,   13,   23,   42,   42,   42,    9,
+       10,   42,   42,   42,   42,   42,   42,   42,   42,   42,
+       42,   42,   42,   42,   27,   42,   42,   42,   42,   28,
+       29,   42,   42,   42,   30,   31,   32,   42,   42,   42,
+       42,   42,   33,    0
     } ;
 
 static yyconst int yy_ec[256] =
@@ -342,8 +338,8 @@ static yyconst int yy_ec[256] =
         1,    1,    1,    1,   21,    1,   22,   23,   24,   25,
 
        26,   27,   28,   29,   30,   21,   31,   32,   33,   34,
-       35,   36,   37,   38,   39,   40,   41,   42,   43,   44,
-       45,   21,    1,    1,    1,    1,    1,    1,    1,    1,
+       35,   36,   21,   37,   38,   39,   40,   21,   41,   42,
+       43,   21,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -360,137 +356,123 @@ static yyconst int yy_ec[256] =
         1,    1,    1,    1,    1
     } ;
 
-static yyconst int yy_meta[46] =
+static yyconst int yy_meta[44] =
     {   0,
         1,    1,    2,    1,    1,    1,    3,    4,    1,    5,
         5,    5,    5,    5,    5,    5,    5,    1,    6,    6,
         7,    6,    6,    6,    6,    6,    6,    7,    7,    7,
         7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
-        7,    7,    7,    8,    7
+        7,    8,    7
     } ;
 
-static yyconst short int yy_base[209] =
+static yyconst short int yy_base[173] =
     {   0,
-        0,    0,  244,  245,  245,    0,  245,  245,  235,    0,
-       40,   39,   40,  245,    0,  212,   18,   29,   29,   22,
-       29,  198,  228,   42,   26,  194,  208,    0,    0,  229,
-       39,  245,    0,    0,    0,    0,    0,  198,  200,   41,
-      195,  211,   32,    0,  200,  204,  195,  194,  192,  187,
-      192,  189,  191,  186,  184,  191,  184,  185,  211,    0,
-        0,  191,  193,  193,  192,  187,  174,  185,  184,  187,
-      186,  185,  173,  170,   61,  165,    0,    0,  162,   45,
-      162,  175,  160,  192,  191,  173,  183,  164,  169,    0,
-        0,  169,  158,  152,  149,  149,    0,  150,  171,  174,
-
-      171,  162,  157,  152,  147,  156,  155,  153,   74,  135,
-      164,    0,  151,  132,  148,  133,  139,  154,  129,  146,
-      145,    0,  128,  131,  126,  135,  122,  132,  134,  143,
-      146,  143,  134,    0,    0,  133,    0,    0,    0,  114,
-      139,    0,  114,  113,  112,  124,  122,    0,    0,    0,
-      120,  124,   51,    0,  107,  105,    0,    0,  105,  104,
-      119,    0,  115,    0,  101,  100,  107,   98,   95,  112,
-      111,   87,    0,   93,   92,   95,  106,    0,   82,   81,
-        0,  103,  101,   73,   61,    0,    0,   60,   49,   72,
-        0,    0,    0,   66,   44,   43,   58,   34,    0,  245,
-
-       92,   97,   52,   99,  103,  111,  115,  119
+        0,    0,  209,  210,  210,    0,  210,  210,  200,    0,
+       38,   37,   38,  210,    0,   16,   27,   26,   22,   24,
+      181,   21,  163,  175,    0,    0,  196,   35,  210,    0,
+        0,    0,    0,    0,  168,  176,  163,  178,  167,  171,
+      162,  161,  159,  155,  150,  155,  161,  154,  155,  181,
+        0,    0,  164,  164,  159,  147,  161,  160,  159,  147,
+      144,   52,  137,   34,  138,  150,  136,  167,  166,  159,
+      140,    0,    0,  132,  129,  129,    0,  130,  150,  153,
+      150,  141,  127,  127,  136,  135,  133,   59,  145,    0,
+      118,  123,  138,  114,  130,  129,    0,  113,  112,  120,
+
+      108,  117,  119,  128,  131,  128,  119,    0,    0,  101,
+      125,    0,  101,  100,   99,  110,    0,    0,    0,  107,
+      111,   44,    0,   95,    0,    0,   94,   93,  107,    0,
+        0,   91,   90,   96,   88,  102,  101,   79,   84,   83,
+       85,   96,   74,   72,    0,   83,   76,   58,   43,    0,
+        0,   40,   39,   64,    0,    0,    0,   56,   40,   36,
+       49,   24,    0,  210,   84,   89,   46,   91,   95,  103,
+      107,  111
     } ;
 
-static yyconst short int yy_def[209] =
+static yyconst short int yy_def[173] =
     {   0,
-      200,    1,  200,  200,  200,  201,  200,  200,  202,  203,
-      200,  204,  204,  200,  205,  205,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  201,  203,  202,
-      203,  200,  206,   31,   13,  207,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  205,  208,  206,
-      207,  205,  205,  205,  205,  205,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  205,  205,  205,
-      205,  205,  205,  208,  208,  205,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  205,  205,  205,
-
-      205,  205,  205,  205,  205,  205,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  205,  205,  205,
-      205,  205,  205,  205,  205,  205,  205,  205,  205,    0,
-
-      200,  200,  200,  200,  200,  200,  200,  200
+      164,    1,  164,  164,  164,  165,  164,  164,  166,  167,
+      164,  168,  168,  164,  169,  169,  169,  169,  169,  169,
+      169,  169,  169,  169,  165,  167,  166,  167,  164,  170,
+       28,   13,  171,  169,  169,  169,  169,  169,  169,  169,
+      169,  169,  169,  169,  169,  169,  169,  169,  169,  172,
+      170,  171,  169,  169,  169,  169,  169,  169,  169,  169,
+      169,  169,  169,  169,  169,  169,  169,  172,  172,  169,
+      169,  169,  169,  169,  169,  169,  169,  169,  169,  169,
+      169,  169,  169,  169,  169,  169,  169,  169,  169,  169,
+      169,  169,  169,  169,  169,  169,  169,  169,  169,  169,
+
+      169,  169,  169,  169,  169,  169,  169,  169,  169,  169,
+      169,  169,  169,  169,  169,  169,  169,  169,  169,  169,
+      169,  169,  169,  169,  169,  169,  169,  169,  169,  169,
+      169,  169,  169,  169,  169,  169,  169,  169,  169,  169,
+      169,  169,  169,  169,  169,  169,  169,  169,  169,  169,
+      169,  169,  169,  169,  169,  169,  169,  169,  169,  169,
+      169,  169,  169,    0,  164,  164,  164,  164,  164,  164,
+      164,  164
     } ;
 
-static yyconst short int yy_nxt[291] =
+static yyconst short int yy_nxt[254] =
     {   0,
         4,    5,    6,    7,    8,    4,    9,   10,   11,   12,
        13,   13,   13,   13,   13,   13,   13,   14,   15,   15,
-       15,   16,   17,   18,   19,   15,   20,   15,   15,   21,
-       15,   15,   15,   15,   22,   23,   15,   24,   25,   26,
-       27,   15,   15,   15,   15,   32,   34,   34,   33,   39,
-       41,   44,   45,   47,   46,   40,   31,   42,   59,   48,
-       43,   49,   50,   53,   59,   55,   64,   54,   56,   68,
-       69,   99,  166,  100,  105,   65,  101,  102,  199,  198,
-      197,  196,   36,  200,  130,  106,  131,  195,  194,  132,
-      133,  167,   28,  193,   28,   28,   28,   28,   28,   28,
-
-       30,   30,   35,   35,  192,  191,   35,   37,   37,   37,
-       37,   60,  190,   60,   60,   60,   60,   60,   60,   61,
-       61,   85,  189,   85,  188,  187,  186,  185,  184,  183,
-      182,  181,  180,  179,  178,  177,  176,  175,  174,  173,
-      172,  171,  170,  169,  168,  165,  164,  163,  162,  161,
-      160,  159,  158,  157,  156,  155,  154,  153,  152,  151,
-      150,  149,  148,  147,  146,  145,  144,  143,  142,  141,
-      140,  139,  138,  137,  136,  135,  134,  129,  128,  127,
-      126,  125,  124,  123,  122,  121,  120,  119,  118,  117,
-      116,  115,  114,  113,  112,  111,  110,  200,  200,  109,
-
-      108,  107,  104,  103,   98,   97,   96,   95,   94,   93,
-       92,   91,   90,   89,   88,   87,   86,   84,   83,   82,
-       81,   80,   79,   78,   77,   76,   75,   74,   73,   72,
-       71,   70,   67,   66,   63,   62,   34,   58,   57,   52,
-       51,   38,   29,  200,    3,  200,  200,  200,  200,  200,
-      200,  200,  200,  200,  200,  200,  200,  200,  200,  200,
-      200,  200,  200,  200,  200,  200,  200,  200,  200,  200,
-      200,  200,  200,  200,  200,  200,  200,  200,  200,  200,
-      200,  200,  200,  200,  200,  200,  200,  200,  200,  200
+       15,   15,   16,   17,   18,   15,   19,   15,   15,   20,
+       21,   15,   15,   15,   15,   15,   15,   22,   23,   24,
+       15,   15,   15,   29,   31,   31,   30,   35,   37,   39,
+       28,   40,   36,   41,   50,   38,   43,   44,   42,   46,
+       50,   47,   79,   84,   80,  133,  163,   81,   82,  104,
+      162,  105,  161,   85,  106,  107,  160,  159,   33,  164,
+      158,  157,  156,  134,   25,  155,   25,   25,   25,   25,
+       25,   25,   27,   27,   32,   32,  154,  153,   32,   34,
+
+       34,   34,   34,   51,  152,   51,   51,   51,   51,   51,
+       51,   52,   52,   69,  151,   69,  150,  149,  148,  147,
+      146,  145,  144,  143,  142,  141,  140,  139,  138,  137,
+      136,  135,  132,  131,  130,  129,  128,  127,  126,  125,
+      124,  123,  122,  121,  120,  119,  118,  117,  116,  115,
+      114,  113,  112,  111,  110,  109,  108,  103,  102,  101,
+      100,   99,   98,   97,   96,   95,   94,   93,   92,   91,
+       90,   89,  164,  164,   88,   87,   86,   83,   78,   77,
+       76,   75,   74,   73,   72,   71,   70,   68,   67,   66,
+       65,   64,   63,   62,   61,   60,   59,   58,   57,   56,
+
+       55,   54,   53,   31,   49,   48,   45,   26,  164,    3,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      164,  164,  164
     } ;
 
-static yyconst short int yy_chk[291] =
+static yyconst short int yy_chk[254] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,   11,   12,   13,   11,   17,
-       18,   19,   19,   20,   19,   17,  203,   18,   31,   20,
-       18,   21,   21,   24,   31,   25,   40,   24,   25,   43,
-       43,   75,  153,   75,   80,   40,   75,   75,  198,  197,
-      196,  195,   12,   13,  109,   80,  109,  194,  190,  109,
-      109,  153,  201,  189,  201,  201,  201,  201,  201,  201,
-
-      202,  202,  204,  204,  188,  185,  204,  205,  205,  205,
-      205,  206,  184,  206,  206,  206,  206,  206,  206,  207,
-      207,  208,  183,  208,  182,  180,  179,  177,  176,  175,
-      174,  172,  171,  170,  169,  168,  167,  166,  165,  163,
-      161,  160,  159,  156,  155,  152,  151,  147,  146,  145,
-      144,  143,  141,  140,  136,  133,  132,  131,  130,  129,
-      128,  127,  126,  125,  124,  123,  121,  120,  119,  118,
-      117,  116,  115,  114,  113,  111,  110,  108,  107,  106,
-      105,  104,  103,  102,  101,  100,   99,   98,   96,   95,
-       94,   93,   92,   89,   88,   87,   86,   85,   84,   83,
-
-       82,   81,   79,   76,   74,   73,   72,   71,   70,   69,
-       68,   67,   66,   65,   64,   63,   62,   59,   58,   57,
-       56,   55,   54,   53,   52,   51,   50,   49,   48,   47,
-       46,   45,   42,   41,   39,   38,   30,   27,   26,   23,
-       22,   16,    9,    3,  200,  200,  200,  200,  200,  200,
-      200,  200,  200,  200,  200,  200,  200,  200,  200,  200,
-      200,  200,  200,  200,  200,  200,  200,  200,  200,  200,
-      200,  200,  200,  200,  200,  200,  200,  200,  200,  200,
-      200,  200,  200,  200,  200,  200,  200,  200,  200,  200
+        1,    1,    1,   11,   12,   13,   11,   16,   17,   18,
+      167,   18,   16,   19,   28,   17,   20,   20,   19,   22,
+       28,   22,   62,   64,   62,  122,  162,   62,   62,   88,
+      161,   88,  160,   64,   88,   88,  159,  158,   12,   13,
+      154,  153,  152,  122,  165,  149,  165,  165,  165,  165,
+      165,  165,  166,  166,  168,  168,  148,  147,  168,  169,
+
+      169,  169,  169,  170,  146,  170,  170,  170,  170,  170,
+      170,  171,  171,  172,  144,  172,  143,  142,  141,  140,
+      139,  138,  137,  136,  135,  134,  133,  132,  129,  128,
+      127,  124,  121,  120,  116,  115,  114,  113,  111,  110,
+      107,  106,  105,  104,  103,  102,  101,  100,   99,   98,
+       96,   95,   94,   93,   92,   91,   89,   87,   86,   85,
+       84,   83,   82,   81,   80,   79,   78,   76,   75,   74,
+       71,   70,   69,   68,   67,   66,   65,   63,   61,   60,
+       59,   58,   57,   56,   55,   54,   53,   50,   49,   48,
+       47,   46,   45,   44,   43,   42,   41,   40,   39,   38,
+
+       37,   36,   35,   27,   24,   23,   21,    9,    3,  164,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      164,  164,  164,  164,  164,  164,  164,  164,  164,  164,
+      164,  164,  164
     } ;
 
 static yy_state_type yy_last_accepting_state;
@@ -516,6 +498,7 @@ char *yytext;
 #include "dcLexerDefs.h"
 #include "dcParserDefs.h"
 #include "dcParser.h"
+#include "dcFile.h"
 #include "dcindent.h"
 
 
@@ -903,7 +886,7 @@ inline void accept() {
   col_number += yyleng;
 }
 
-#line 908 "lex.yy.c"
+#line 891 "lex.yy.c"
 
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
@@ -1054,7 +1037,7 @@ YY_DECL
 	register char *yy_cp = NULL, *yy_bp = NULL;
 	register int yy_act;
 
-#line 406 "dcLexer.lxx"
+#line 407 "dcLexer.lxx"
 
 
 
@@ -1065,7 +1048,7 @@ YY_DECL
   }
 
 
-#line 1070 "lex.yy.c"
+#line 1053 "lex.yy.c"
 
 	if ( yy_init )
 		{
@@ -1116,13 +1099,13 @@ yy_match:
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 				{
 				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 201 )
+				if ( yy_current_state >= 165 )
 					yy_c = yy_meta[(unsigned int) yy_c];
 				}
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
 			++yy_cp;
 			}
-		while ( yy_base[yy_current_state] != 245 );
+		while ( yy_base[yy_current_state] != 210 );
 
 yy_find_action:
 		yy_act = yy_accept[yy_current_state];
@@ -1150,7 +1133,7 @@ do_action:	/* This label is used only to access EOF actions. */
 
 case 1:
 YY_RULE_SETUP
-#line 416 "dcLexer.lxx"
+#line 417 "dcLexer.lxx"
 {
   // New line.  Save a copy of the line so we can print it out for the
   // benefit of the user in case we get an error.
@@ -1167,7 +1150,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 430 "dcLexer.lxx"
+#line 431 "dcLexer.lxx"
 { 
   // Eat whitespace.
   accept();
@@ -1175,7 +1158,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 435 "dcLexer.lxx"
+#line 436 "dcLexer.lxx"
 { 
   // Eat C++-style comments.
   accept();
@@ -1183,7 +1166,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 440 "dcLexer.lxx"
+#line 441 "dcLexer.lxx"
 {
   // Eat C-style comments.
   accept();
@@ -1192,7 +1175,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 447 "dcLexer.lxx"
+#line 448 "dcLexer.lxx"
 {
   accept();
   return KW_DCLASS;
@@ -1200,7 +1183,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 452 "dcLexer.lxx"
+#line 453 "dcLexer.lxx"
 {
   accept();
   return KW_STRUCT;
@@ -1208,7 +1191,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 457 "dcLexer.lxx"
+#line 458 "dcLexer.lxx"
 {
   accept();
   return KW_FROM;
@@ -1216,7 +1199,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 462 "dcLexer.lxx"
+#line 463 "dcLexer.lxx"
 {
   accept();
   return KW_IMPORT;
@@ -1224,279 +1207,215 @@ YY_RULE_SETUP
 	YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 467 "dcLexer.lxx"
+#line 468 "dcLexer.lxx"
 {
   accept();
-  return KW_TYPEDEF;
+  return KW_KEYWORD;
 }
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 472 "dcLexer.lxx"
+#line 473 "dcLexer.lxx"
 {
   accept();
-  return KW_SWITCH;
+  return KW_TYPEDEF;
 }
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 477 "dcLexer.lxx"
+#line 478 "dcLexer.lxx"
 {
   accept();
-  return KW_CASE;
+  return KW_SWITCH;
 }
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 482 "dcLexer.lxx"
+#line 483 "dcLexer.lxx"
 {
   accept();
-  return KW_DEFAULT;
+  return KW_CASE;
 }
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 487 "dcLexer.lxx"
+#line 488 "dcLexer.lxx"
 {
   accept();
-  return KW_BREAK;
+  return KW_DEFAULT;
 }
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 492 "dcLexer.lxx"
+#line 493 "dcLexer.lxx"
 {
   accept();
-  return KW_INT8;
+  return KW_BREAK;
 }
 	YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 497 "dcLexer.lxx"
+#line 498 "dcLexer.lxx"
 {
   accept();
-  return KW_INT16;
+  return KW_INT8;
 }
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 502 "dcLexer.lxx"
+#line 503 "dcLexer.lxx"
 {
   accept();
-  return KW_INT32;
+  return KW_INT16;
 }
 	YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 507 "dcLexer.lxx"
+#line 508 "dcLexer.lxx"
 {
   accept();
-  return KW_INT64;
+  return KW_INT32;
 }
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 512 "dcLexer.lxx"
+#line 513 "dcLexer.lxx"
 {
   accept();
-  return KW_UINT8;
+  return KW_INT64;
 }
 	YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 517 "dcLexer.lxx"
+#line 518 "dcLexer.lxx"
 {
   accept();
-  return KW_UINT16;
+  return KW_UINT8;
 }
 	YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 522 "dcLexer.lxx"
+#line 523 "dcLexer.lxx"
 {
   accept();
-  return KW_UINT32;
+  return KW_UINT16;
 }
 	YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 527 "dcLexer.lxx"
+#line 528 "dcLexer.lxx"
 {
   accept();
-  return KW_UINT64;
+  return KW_UINT32;
 }
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 532 "dcLexer.lxx"
+#line 533 "dcLexer.lxx"
 {
   accept();
-  return KW_FLOAT64;
+  return KW_UINT64;
 }
 	YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 537 "dcLexer.lxx"
+#line 538 "dcLexer.lxx"
 {
   accept();
-  return KW_STRING;
+  return KW_FLOAT64;
 }
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 542 "dcLexer.lxx"
+#line 543 "dcLexer.lxx"
 {
   accept();
-  return KW_BLOB;
+  return KW_STRING;
 }
 	YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 547 "dcLexer.lxx"
+#line 548 "dcLexer.lxx"
 {
   accept();
-  return KW_BLOB32;
+  return KW_BLOB;
 }
 	YY_BREAK
 case 26:
 YY_RULE_SETUP
-#line 552 "dcLexer.lxx"
+#line 553 "dcLexer.lxx"
 {
   accept();
-  return KW_INT8ARRAY;
+  return KW_BLOB32;
 }
 	YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 557 "dcLexer.lxx"
+#line 558 "dcLexer.lxx"
 {
   accept();
-  return KW_INT16ARRAY;
+  return KW_INT8ARRAY;
 }
 	YY_BREAK
 case 28:
 YY_RULE_SETUP
-#line 562 "dcLexer.lxx"
+#line 563 "dcLexer.lxx"
 {
   accept();
-  return KW_INT32ARRAY;
+  return KW_INT16ARRAY;
 }
 	YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 567 "dcLexer.lxx"
+#line 568 "dcLexer.lxx"
 {
   accept();
-  return KW_UINT8ARRAY;
+  return KW_INT32ARRAY;
 }
 	YY_BREAK
 case 30:
 YY_RULE_SETUP
-#line 572 "dcLexer.lxx"
+#line 573 "dcLexer.lxx"
 {
   accept();
-  return KW_UINT16ARRAY;
+  return KW_UINT8ARRAY;
 }
 	YY_BREAK
 case 31:
 YY_RULE_SETUP
-#line 577 "dcLexer.lxx"
+#line 578 "dcLexer.lxx"
 {
   accept();
-  return KW_UINT32ARRAY;
+  return KW_UINT16ARRAY;
 }
 	YY_BREAK
 case 32:
 YY_RULE_SETUP
-#line 582 "dcLexer.lxx"
+#line 583 "dcLexer.lxx"
 {
   accept();
-  return KW_UINT32UINT8ARRAY;
+  return KW_UINT32ARRAY;
 }
 	YY_BREAK
 case 33:
 YY_RULE_SETUP
-#line 587 "dcLexer.lxx"
+#line 588 "dcLexer.lxx"
 {
   accept();
-  return KW_CHAR;
+  return KW_UINT32UINT8ARRAY;
 }
 	YY_BREAK
 case 34:
 YY_RULE_SETUP
-#line 592 "dcLexer.lxx"
+#line 593 "dcLexer.lxx"
 {
   accept();
-  return KW_REQUIRED;
+  return KW_CHAR;
 }
 	YY_BREAK
 case 35:
 YY_RULE_SETUP
-#line 597 "dcLexer.lxx"
-{
-  accept();
-  return KW_BROADCAST;
-}
-	YY_BREAK
-case 36:
-YY_RULE_SETUP
-#line 602 "dcLexer.lxx"
-{
-  accept();
-  return KW_P2P;
-}
-	YY_BREAK
-case 37:
-YY_RULE_SETUP
-#line 607 "dcLexer.lxx"
-{
-  accept();
-  return KW_RAM;
-}
-	YY_BREAK
-case 38:
-YY_RULE_SETUP
-#line 612 "dcLexer.lxx"
-{
-  accept();
-  return KW_DB;
-}
-	YY_BREAK
-case 39:
-YY_RULE_SETUP
-#line 617 "dcLexer.lxx"
-{
-  accept();
-  return KW_CLSEND;
-}
-	YY_BREAK
-case 40:
-YY_RULE_SETUP
-#line 622 "dcLexer.lxx"
-{
-  accept();
-  return KW_CLRECV;
-}
-	YY_BREAK
-case 41:
-YY_RULE_SETUP
-#line 627 "dcLexer.lxx"
-{
-  accept();
-  return KW_OWNSEND;
-}
-	YY_BREAK
-case 42:
-YY_RULE_SETUP
-#line 632 "dcLexer.lxx"
-{
-  accept();
-  return KW_AIRECV;
-}
-	YY_BREAK
-case 43:
-YY_RULE_SETUP
-#line 637 "dcLexer.lxx"
+#line 598 "dcLexer.lxx"
 { 
   // An unsigned integer number.
   accept();
@@ -1520,9 +1439,9 @@ YY_RULE_SETUP
   return UNSIGNED_INTEGER;
 }
 	YY_BREAK
-case 44:
+case 36:
 YY_RULE_SETUP
-#line 660 "dcLexer.lxx"
+#line 621 "dcLexer.lxx"
 { 
   // A signed integer number.
   accept();
@@ -1569,9 +1488,9 @@ YY_RULE_SETUP
   return SIGNED_INTEGER;
 }
 	YY_BREAK
-case 45:
+case 37:
 YY_RULE_SETUP
-#line 706 "dcLexer.lxx"
+#line 667 "dcLexer.lxx"
 {
   // A hexadecimal integer number.
   accept(); 
@@ -1599,9 +1518,9 @@ YY_RULE_SETUP
   return UNSIGNED_INTEGER; 
 }
 	YY_BREAK
-case 46:
+case 38:
 YY_RULE_SETUP
-#line 733 "dcLexer.lxx"
+#line 694 "dcLexer.lxx"
 { 
   // A floating-point number.
   accept(); 
@@ -1610,9 +1529,9 @@ YY_RULE_SETUP
   return REAL; 
 }
 	YY_BREAK
-case 47:
+case 39:
 YY_RULE_SETUP
-#line 741 "dcLexer.lxx"
+#line 702 "dcLexer.lxx"
 {
   // Quoted string.
   accept();
@@ -1620,9 +1539,9 @@ YY_RULE_SETUP
   return STRING;
 }
 	YY_BREAK
-case 48:
+case 40:
 YY_RULE_SETUP
-#line 748 "dcLexer.lxx"
+#line 709 "dcLexer.lxx"
 {
   // Single-quoted string.
   accept();
@@ -1630,9 +1549,9 @@ YY_RULE_SETUP
   return STRING;
 }
 	YY_BREAK
-case 49:
+case 41:
 YY_RULE_SETUP
-#line 755 "dcLexer.lxx"
+#line 716 "dcLexer.lxx"
 {
   // Long hex string.
   accept();
@@ -1640,31 +1559,39 @@ YY_RULE_SETUP
   return HEX_STRING;
 }
 	YY_BREAK
-case 50:
+case 42:
 YY_RULE_SETUP
-#line 762 "dcLexer.lxx"
+#line 723 "dcLexer.lxx"
 { 
-  // Identifier.
+  // Identifier or keyword.
   accept();
   dcyylval.str = dcyytext;
+
+  if (dc_file != (DCFile *)NULL) {
+    const DCKeyword *keyword = dc_file->get_keyword_by_name(dcyylval.str);
+    if (keyword != (DCKeyword *)NULL) {
+      dcyylval.u.keyword = keyword;
+      return KEYWORD;
+    }
+  }
   return IDENTIFIER;
 }
 	YY_BREAK
-case 51:
+case 43:
 YY_RULE_SETUP
-#line 770 "dcLexer.lxx"
+#line 739 "dcLexer.lxx"
 {
   // Send any other printable character as itself.
   accept(); 
   return dcyytext[0];
 }
 	YY_BREAK
-case 52:
+case 44:
 YY_RULE_SETUP
-#line 776 "dcLexer.lxx"
+#line 745 "dcLexer.lxx"
 ECHO;
 	YY_BREAK
-#line 1669 "lex.yy.c"
+#line 1596 "lex.yy.c"
 case YY_STATE_EOF(INITIAL):
 	yyterminate();
 
@@ -1956,7 +1883,7 @@ static yy_state_type yy_get_previous_state()
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			{
 			yy_current_state = (int) yy_def[yy_current_state];
-			if ( yy_current_state >= 201 )
+			if ( yy_current_state >= 165 )
 				yy_c = yy_meta[(unsigned int) yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1991,11 +1918,11 @@ yy_state_type yy_current_state;
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		{
 		yy_current_state = (int) yy_def[yy_current_state];
-		if ( yy_current_state >= 201 )
+		if ( yy_current_state >= 165 )
 			yy_c = yy_meta[(unsigned int) yy_c];
 		}
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-	yy_is_jam = (yy_current_state == 200);
+	yy_is_jam = (yy_current_state == 164);
 
 	return yy_is_jam ? 0 : yy_current_state;
 	}
@@ -2046,6 +1973,7 @@ register char *yy_bp;
 #endif	/* ifndef YY_NO_UNPUT */
 
 
+#ifndef YY_NO_INPUT
 #ifdef __cplusplus
 static int yyinput()
 #else
@@ -2117,7 +2045,7 @@ static int input()
 
 	return c;
 	}
-
+#endif /* YY_NO_INPUT */
 
 #ifdef YY_USE_PROTOS
 void yyrestart( FILE *input_file )
@@ -2545,4 +2473,4 @@ int main()
 	return 0;
 	}
 #endif
-#line 776 "dcLexer.lxx"
+#line 745 "dcLexer.lxx"

+ 15 - 46
direct/src/dcparser/dcLexer.lxx

@@ -9,6 +9,7 @@
 #include "dcLexerDefs.h"
 #include "dcParserDefs.h"
 #include "dcParser.h"
+#include "dcFile.h"
 #include "dcindent.h"
 
 
@@ -464,6 +465,11 @@ REALNUM              ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
   return KW_IMPORT;
 }
 
+"keyword" {
+  accept();
+  return KW_KEYWORD;
+}
+
 "typedef" {
   accept();
   return KW_TYPEDEF;
@@ -589,51 +595,6 @@ REALNUM              ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
   return KW_CHAR;
 }
 
-"required" {
-  accept();
-  return KW_REQUIRED;
-}
-
-"broadcast" {
-  accept();
-  return KW_BROADCAST;
-}
-
-"p2p" {
-  accept();
-  return KW_P2P;
-}
-
-"ram" {
-  accept();
-  return KW_RAM;
-}
-
-"db" {
-  accept();
-  return KW_DB;
-}
-
-"clsend" {
-  accept();
-  return KW_CLSEND;
-}
-
-"clrecv" {
-  accept();
-  return KW_CLRECV;
-}
-
-"ownsend" {
-  accept();
-  return KW_OWNSEND;
-}
-
-"airecv" {
-  accept();
-  return KW_AIRECV;
-}
-
 {UNSIGNED_INTEGERNUM} { 
   // An unsigned integer number.
   accept();
@@ -760,9 +721,17 @@ REALNUM              ([+-]?(([0-9]+[.])|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
 }
 
 [A-Za-z_][A-Za-z_0-9]* { 
-  // Identifier.
+  // Identifier or keyword.
   accept();
   dcyylval.str = dcyytext;
+
+  if (dc_file != (DCFile *)NULL) {
+    const DCKeyword *keyword = dc_file->get_keyword_by_name(dcyylval.str);
+    if (keyword != (DCKeyword *)NULL) {
+      dcyylval.u.keyword = keyword;
+      return KEYWORD;
+    }
+  }
   return IDENTIFIER;
 }
 

+ 1 - 1
direct/src/dcparser/dcMolecularField.cxx

@@ -95,7 +95,7 @@ get_atomic(int n) const {
 void DCMolecularField::
 add_atomic(DCAtomicField *atomic) {
   if (_fields.empty()) {
-    set_flags(atomic->get_flags());
+    copy_keywords(*atomic);
   }
   _fields.push_back(atomic);
 

+ 4 - 4
direct/src/dcparser/dcParameter.cxx

@@ -232,7 +232,7 @@ write_instance(ostream &out, bool brief, int indent_level,
                const string &postname) const {
   indent(out, indent_level);
   output_instance(out, brief, prename, name, postname);
-  output_flags(out);
+  output_keywords(out);
   out << ";";
   if (!brief && _number >= 0) {
     out << "  // field " << _number;
@@ -270,7 +270,7 @@ write_typedef_name(ostream &out, bool brief, int indent_level,
   if (!prename.empty() || !name.empty() || !postname.empty()) {
     out << " " << prename << name << postname;
   }
-  output_flags(out);
+  output_keywords(out);
   out << ";";
   if (!brief && _number >= 0) {
     out << "  // field " << _number;
@@ -289,7 +289,7 @@ generate_hash(HashGenerator &hashgen) const {
   // We specifically don't call up to DCField::generate_hash(), since
   // the parameter name is not actually significant to the hash.
 
-  if (get_flags() != 0) {
-    hashgen.add_int(get_flags());
+  if (get_num_keywords() != 0) {
+    DCKeywordList::generate_hash(hashgen);
   }
 }

File diff suppressed because it is too large
+ 693 - 556
direct/src/dcparser/dcParser.cxx.prebuilt


+ 124 - 51
direct/src/dcparser/dcParser.h.prebuilt

@@ -1,55 +1,128 @@
-#ifndef BISON_Y_TAB_H
-# define BISON_Y_TAB_H
-
-# define	UNSIGNED_INTEGER	257
-# define	SIGNED_INTEGER	258
-# define	REAL	259
-# define	STRING	260
-# define	HEX_STRING	261
-# define	IDENTIFIER	262
-# define	KW_DCLASS	263
-# define	KW_STRUCT	264
-# define	KW_FROM	265
-# define	KW_IMPORT	266
-# define	KW_TYPEDEF	267
-# define	KW_SWITCH	268
-# define	KW_CASE	269
-# define	KW_DEFAULT	270
-# define	KW_BREAK	271
-# define	KW_INT8	272
-# define	KW_INT16	273
-# define	KW_INT32	274
-# define	KW_INT64	275
-# define	KW_UINT8	276
-# define	KW_UINT16	277
-# define	KW_UINT32	278
-# define	KW_UINT64	279
-# define	KW_FLOAT64	280
-# define	KW_STRING	281
-# define	KW_BLOB	282
-# define	KW_BLOB32	283
-# define	KW_INT8ARRAY	284
-# define	KW_INT16ARRAY	285
-# define	KW_INT32ARRAY	286
-# define	KW_UINT8ARRAY	287
-# define	KW_UINT16ARRAY	288
-# define	KW_UINT32ARRAY	289
-# define	KW_UINT32UINT8ARRAY	290
-# define	KW_CHAR	291
-# define	KW_REQUIRED	292
-# define	KW_BROADCAST	293
-# define	KW_P2P	294
-# define	KW_RAM	295
-# define	KW_DB	296
-# define	KW_CLSEND	297
-# define	KW_CLRECV	298
-# define	KW_OWNSEND	299
-# define	KW_AIRECV	300
-# define	START_DC	301
-# define	START_PARAMETER_VALUE	302
-# define	START_PARAMETER_DESCRIPTION	303
+/* A Bison parser, made by GNU Bison 2.0.  */
 
+/* Skeleton parser for Yacc-like parsing with Bison,
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+   This program 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 program 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 this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     UNSIGNED_INTEGER = 258,
+     SIGNED_INTEGER = 259,
+     REAL = 260,
+     STRING = 261,
+     HEX_STRING = 262,
+     IDENTIFIER = 263,
+     KEYWORD = 264,
+     KW_DCLASS = 265,
+     KW_STRUCT = 266,
+     KW_FROM = 267,
+     KW_IMPORT = 268,
+     KW_TYPEDEF = 269,
+     KW_KEYWORD = 270,
+     KW_SWITCH = 271,
+     KW_CASE = 272,
+     KW_DEFAULT = 273,
+     KW_BREAK = 274,
+     KW_INT8 = 275,
+     KW_INT16 = 276,
+     KW_INT32 = 277,
+     KW_INT64 = 278,
+     KW_UINT8 = 279,
+     KW_UINT16 = 280,
+     KW_UINT32 = 281,
+     KW_UINT64 = 282,
+     KW_FLOAT64 = 283,
+     KW_STRING = 284,
+     KW_BLOB = 285,
+     KW_BLOB32 = 286,
+     KW_INT8ARRAY = 287,
+     KW_INT16ARRAY = 288,
+     KW_INT32ARRAY = 289,
+     KW_UINT8ARRAY = 290,
+     KW_UINT16ARRAY = 291,
+     KW_UINT32ARRAY = 292,
+     KW_UINT32UINT8ARRAY = 293,
+     KW_CHAR = 294,
+     START_DC = 295,
+     START_PARAMETER_VALUE = 296,
+     START_PARAMETER_DESCRIPTION = 297
+   };
+#endif
+#define UNSIGNED_INTEGER 258
+#define SIGNED_INTEGER 259
+#define REAL 260
+#define STRING 261
+#define HEX_STRING 262
+#define IDENTIFIER 263
+#define KEYWORD 264
+#define KW_DCLASS 265
+#define KW_STRUCT 266
+#define KW_FROM 267
+#define KW_IMPORT 268
+#define KW_TYPEDEF 269
+#define KW_KEYWORD 270
+#define KW_SWITCH 271
+#define KW_CASE 272
+#define KW_DEFAULT 273
+#define KW_BREAK 274
+#define KW_INT8 275
+#define KW_INT16 276
+#define KW_INT32 277
+#define KW_INT64 278
+#define KW_UINT8 279
+#define KW_UINT16 280
+#define KW_UINT32 281
+#define KW_UINT64 282
+#define KW_FLOAT64 283
+#define KW_STRING 284
+#define KW_BLOB 285
+#define KW_BLOB32 286
+#define KW_INT8ARRAY 287
+#define KW_INT16ARRAY 288
+#define KW_INT32ARRAY 289
+#define KW_UINT8ARRAY 290
+#define KW_UINT16ARRAY 291
+#define KW_UINT32ARRAY 292
+#define KW_UINT32UINT8ARRAY 293
+#define KW_CHAR 294
+#define START_DC 295
+#define START_PARAMETER_VALUE 296
+#define START_PARAMETER_DESCRIPTION 297
+
+
+
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+typedef int YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
 
 extern YYSTYPE dcyylval;
 
-#endif /* not BISON_Y_TAB_H */
+
+

+ 48 - 73
direct/src/dcparser/dcParser.yxx

@@ -16,6 +16,7 @@
 #include "dcArrayParameter.h"
 #include "dcSimpleParameter.h"
 #include "dcTypedef.h"
+#include "dcKeyword.h"
 #include "dcPacker.h"
 #include "dcNumericRange.h"
 
@@ -27,12 +28,13 @@
 #define YYINITDEPTH 1000
 #define YYMAXDEPTH 1000
 
-static DCFile *dc_file = (DCFile *)NULL;
+DCFile *dc_file = (DCFile *)NULL;
 static DCClass *current_class = (DCClass *)NULL;
 static DCSwitch *current_switch = (DCSwitch *)NULL;
 static DCAtomicField *current_atomic = (DCAtomicField *)NULL;
 static DCMolecularField *current_molecular = (DCMolecularField *)NULL;
 static DCParameter *current_parameter = (DCParameter *)NULL;
+static DCKeywordList current_keyword_list;
 static DCPacker default_packer;
 static DCPacker *current_packer;
 static DCDoubleRange double_range;
@@ -83,12 +85,14 @@ dc_cleanup_parser() {
 %token <u.int64> SIGNED_INTEGER
 %token <u.real> REAL
 %token <str> STRING HEX_STRING IDENTIFIER
+%token <u.keyword> KEYWORD
 
 %token KW_DCLASS 
 %token KW_STRUCT 
 %token KW_FROM 
 %token KW_IMPORT 
 %token KW_TYPEDEF 
+%token KW_KEYWORD 
 %token KW_SWITCH
 %token KW_CASE
 %token KW_DEFAULT
@@ -115,16 +119,6 @@ dc_cleanup_parser() {
 %token KW_UINT32UINT8ARRAY
 %token KW_CHAR
 
-%token KW_REQUIRED
-%token KW_BROADCAST
-%token KW_P2P
-%token KW_RAM
-%token KW_DB
-%token KW_CLSEND
-%token KW_CLRECV
-%token KW_OWNSEND
-%token KW_AIRECV
-
 /* These special tokens are used to set the starting state of the
    parser.  The lexer places the appropriate one of these on the head
    of the input stream. */
@@ -133,8 +127,6 @@ dc_cleanup_parser() {
 %token START_PARAMETER_DESCRIPTION
 
 %type <u.atomic> atomic_name
-%type <u.s_int> server_flags
-%type <u.s_int> no_server_flags
 %type <u.dclass> dclass_or_struct
 %type <u.dclass> dclass_name
 %type <u.dclass> dclass
@@ -203,6 +195,7 @@ dc:
 }
         | dc import
         | dc typedef_decl
+        | dc keyword_decl
         ;
 
 slash_identifier:
@@ -270,6 +263,21 @@ typedef_decl:
 }
 	;
 
+keyword_decl:
+        KW_KEYWORD IDENTIFIER
+{
+  dc_file->add_keyword($2);
+}
+        | KW_KEYWORD KEYWORD
+{
+  // This keyword has already been defined.  But since we are now
+  // explicitly defining it, clear its bitmask, so that we will have a
+  // new hash code--doing this will allow us to phase out the
+  // historical hash code support later.
+  ((DCKeyword *)$2)->clear_historical_flag();
+}
+	;
+
 dclass_or_struct:
         dclass
 	| struct
@@ -339,7 +347,7 @@ dclass_base_list:
 dclass_fields:
         empty
         | dclass_fields ';'
-        | dclass_fields dclass_field
+        | dclass_fields dclass_field ';'
 {
   if ($2 == (DCField *)NULL) {
     // Pass this error up.
@@ -352,29 +360,29 @@ dclass_fields:
         ;
 
 dclass_field:
-	atomic_field server_flags
+	atomic_field keyword_list
 {
   if ($1 != (DCField *)NULL) {
     if ($1->get_name().empty()) {
       yyerror("Field name required.");
     }
-    $1->set_flags($2);
+    $1->copy_keywords(current_keyword_list);
   }
   $$ = $1;
 }
-	| molecular_field no_server_flags
-	| unnamed_parameter_with_default server_flags ';'
+	| molecular_field no_keyword_list
+	| unnamed_parameter_with_default keyword_list ';'
 {
   yyerror("Unnamed parameters are not allowed on a dclass");
   if ($1 != (DCField *)NULL) {
-    $1->set_flags($2);
+    $1->copy_keywords(current_keyword_list);
   }
   $$ = $1;
 }
-	| named_parameter_with_default server_flags
+	| named_parameter_with_default keyword_list
 {
   if ($1 != (DCField *)NULL) {
-    $1->set_flags($2);
+    $1->copy_keywords(current_keyword_list);
   }
   $$ = $1;
 }
@@ -439,7 +447,7 @@ struct_base_list:
 struct_fields:
         empty
         | struct_fields ';'
-        | struct_fields struct_field
+        | struct_fields struct_field ';'
 {
   if ($2 == (DCField *)NULL) {
     // Pass this error up.
@@ -450,19 +458,19 @@ struct_fields:
         ;
 
 struct_field:
-	atomic_field no_server_flags
+	atomic_field no_keyword_list
 {
   if ($1->get_name().empty()) {
     yyerror("Field name required.");
   }
   $$ = $1;
 }
-	| molecular_field no_server_flags
-	| unnamed_parameter_with_default no_server_flags ';'
+	| molecular_field no_keyword_list
+	| unnamed_parameter_with_default no_keyword_list ';'
 {
   $$ = $1;
 }
-	| named_parameter_with_default no_server_flags
+	| named_parameter_with_default no_keyword_list
 {
   $$ = $1;
 }
@@ -603,15 +611,15 @@ parameter_or_atomic:
 	;
 
 parameter_description:
-	atomic_field no_server_flags
+	atomic_field no_keyword_list
 {
   $$ = $1;
 }
-	| unnamed_parameter_with_default no_server_flags
+	| unnamed_parameter_with_default no_keyword_list
 {
   $$ = $1;
 }
-	| named_parameter_with_default no_server_flags
+	| named_parameter_with_default no_keyword_list
 {
   $$ = $1;
 }
@@ -1140,56 +1148,23 @@ type_token:
 }
         ;
 
-server_flags:
+keyword_list:
         empty
 {
-  $$ = 0;
-}
-        | server_flags KW_REQUIRED
-{
-  $$ = $1 | DCAtomicField::F_required;
-}
-        | server_flags KW_BROADCAST
-{
-  $$ = $1 | DCAtomicField::F_broadcast;
-}
-        | server_flags KW_P2P
-{
-  $$ = $1 | DCAtomicField::F_p2p;
+  current_keyword_list.clear_keywords();
 }
-        | server_flags KW_RAM
+        | keyword_list KEYWORD
 {
-  $$ = $1 | DCAtomicField::F_ram;
+  current_keyword_list.add_keyword($2);
 }
-        | server_flags KW_DB
-{
-  $$ = $1 | DCAtomicField::F_db;
-}
-        | server_flags KW_CLSEND
-{
-  $$ = $1 | DCAtomicField::F_clsend;
-}
-        | server_flags KW_CLRECV
-{
-  $$ = $1 | DCAtomicField::F_clrecv;
-}
-        | server_flags KW_OWNSEND
-{
-  $$ = $1 | DCAtomicField::F_ownsend;
-}
-        | server_flags KW_AIRECV
-{
-  $$ = $1 | DCAtomicField::F_airecv;
-}
-        ;
+	;
 
-no_server_flags:
-        server_flags
+no_keyword_list:
+        keyword_list
 {
-  if ($1 != 0) {
-    yyerror("Server flags are not allowed here.");
+  if (current_keyword_list.get_num_keywords() != 0) {
+    yyerror("Communication keywords are not allowed here.");
   }
-  $$ = $1;
 }
 	;
 
@@ -1231,8 +1206,8 @@ molecular_atom_list:
 {
   if ($3 != (DCAtomicField *)NULL) {
     current_molecular->add_atomic($3);
-    if (!current_molecular->compare_flags(*$3)) {
-      yyerror("Mismatched flags in molecule between " + 
+    if (!current_molecular->compare_keywords(*$3)) {
+      yyerror("Mismatched keywords in molecule between " + 
               current_molecular->get_atomic(0)->get_name() + " and " +
               $3->get_name());
     }

+ 4 - 0
direct/src/dcparser/dcParserDefs.h

@@ -28,6 +28,7 @@ class DCSwitch;
 class DCField;
 class DCAtomicField;
 class DCParameter;
+class DCKeyword;
 class DCPacker;
 
 void dc_init_parser(istream &in, const string &filename, DCFile &file);
@@ -39,6 +40,8 @@ DCField *dc_get_parameter_description();
 void dc_cleanup_parser();
 int dcyyparse();
 
+extern DCFile *dc_file;
+
 // This structure holds the return value for each token.
 // Traditionally, this is a union, and is declared with the %union
 // declaration in the parser.y file, but unions are pretty worthless
@@ -61,6 +64,7 @@ public:
     DCAtomicField *atomic;
     DCSubatomicType subatomic;
     DCParameter *parameter;
+    const DCKeyword *keyword;
   } u;
   string str;
 };

+ 3 - 0
direct/src/dcparser/dcbase.h

@@ -36,6 +36,7 @@
 #include "numeric_types.h"
 #include "pvector.h"
 #include "pmap.h"
+#include "pset.h"
 
 #else  // WITHIN_PANDA
 
@@ -100,8 +101,10 @@ typedef string Filename;
 
 #include <vector>
 #include <map>
+#include <set>
 #define pvector vector
 #define pmap map
+#define pset set
 
 #ifdef WIN32
 typedef __int64 PN_int64;

+ 2 - 0
direct/src/dcparser/dcparser_composite1.cxx

@@ -4,6 +4,8 @@
 #include "dcAtomicField.cxx"
 #include "dcClass.cxx"
 #include "dcDeclaration.cxx"
+#include "dcKeyword.cxx"
+#include "dcKeywordList.cxx"
 #include "dcPackData.cxx"
 #include "dcPacker.cxx"
 #include "dcPackerCatalog.cxx"

Some files were not shown because too many files changed in this diff