Browse Source

more restrictive grammar

David Rose 21 years ago
parent
commit
88975f5f9d
3 changed files with 549 additions and 378 deletions
  1. 4 0
      direct/src/dcparser/dcClass.cxx
  2. 414 327
      direct/src/dcparser/dcParser.cxx.prebuilt
  3. 131 51
      direct/src/dcparser/dcParser.yxx

+ 4 - 0
direct/src/dcparser/dcClass.cxx

@@ -805,6 +805,10 @@ void DCClass::
 generate_hash(HashGenerator &hashgen) const {
   hashgen.add_string(_name);
 
+  if (is_struct()) {
+    hashgen.add_int(1);
+  }
+
   hashgen.add_int(_parents.size());
   Parents::const_iterator pi;
   for (pi = _parents.begin(); pi != _parents.end(); ++pi) {

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


+ 131 - 51
direct/src/dcparser/dcParser.yxx

@@ -115,13 +115,16 @@ dc_cleanup_parser() {
 %token START_DC
 %token START_PARAMETER_VALUE
 
-%type <u.flag> kw_struct_or_kw_dclass
-%type <u.dclass> dclass_name
-%type <u.dclass> dclass
-%type <u.dswitch> switch
 %type <u.atomic> atomic_name
 %type <u.s_int> server_flags
+%type <u.dclass> dclass_or_struct
+%type <u.dclass> dclass_name
+%type <u.dclass> dclass
 %type <u.field> dclass_field
+%type <u.dclass> struct_name
+%type <u.dclass> struct
+%type <u.field> struct_field
+%type <u.dswitch> switch
 %type <u.field> switch_field
 %type <u.field> atomic_field
 %type <u.field> molecular_field
@@ -152,7 +155,7 @@ grammar:
 dc:
         empty
         | dc ';'
-        | dc dclass
+        | dc dclass_or_struct
 {
   if (!dc_file->add_class($2)) {
     DCClass *old_class = dc_file->get_class_by_name($2->get_name());
@@ -173,44 +176,6 @@ dc:
         | dc typedef_decl
         ;
 
-dclass:
-        kw_struct_or_kw_dclass optional_name 
-{
-  $$ = current_class;
-  current_class = new DCClass($2, $1, false);
-}
-        dclass_derivation '{' dclass_fields '}'
-{
-  $$ = current_class;
-  current_class = $<u.dclass>3;
-}
-        ;
-
-kw_struct_or_kw_dclass:
-	KW_STRUCT
-{
-  $$ = true;
-}
-	| KW_DCLASS
-{
-  $$ = false;
-}
-	;
-
-dclass_name:
-        IDENTIFIER
-{
-  DCClass *dclass = dc_file->get_class_by_name($1);
-  if (dclass == (DCClass *)NULL) {
-    // Create a bogus class as a forward reference.
-    dclass = new DCClass($1, false, true);
-    dc_file->add_class(dclass);
-  }
-  
-  $$ = dclass;
-}
-	;
-
 slash_identifier:
         IDENTIFIER
 	| slash_identifier '/' IDENTIFIER
@@ -274,19 +239,54 @@ typedef_decl:
 }
 	;
 
+dclass_or_struct:
+        dclass
+	| struct
+	;
+
+dclass:
+        KW_DCLASS optional_name 
+{
+  $$ = current_class;
+  current_class = new DCClass($2, false, false);
+}
+        dclass_derivation '{' dclass_fields '}'
+{
+  $$ = current_class;
+  current_class = $<u.dclass>3;
+}
+        ;
+
+dclass_name:
+        IDENTIFIER
+{
+  DCClass *dclass = dc_file->get_class_by_name($1);
+  if (dclass == (DCClass *)NULL) {
+    // Create a bogus class as a forward reference.
+    dclass = new DCClass($1, false, true);
+    dc_file->add_class(dclass);
+  }
+  if (dclass->is_struct()) {
+    yyerror("struct name not allowed");
+  }
+  
+  $$ = dclass;
+}
+	;
+
 dclass_derivation:
         empty
-        | ':' base_list
+        | ':' dclass_base_list
         ;
 
-base_list:
+dclass_base_list:
         dclass_name
 {
   if ($1 != (DCClass *)NULL) {
     current_class->add_parent($1);
   }
 }
-        | base_list ',' dclass_name
+        | dclass_base_list ',' dclass_name
 {
   if ($3 != (DCClass *)NULL) {
     current_class->add_parent($3);
@@ -306,7 +306,11 @@ dclass_fields:
         ;
 
 dclass_field:
-	atomic_field
+	atomic_field server_flags
+{
+  $$ = $1;
+  $$->set_flags($2);
+}
 	| molecular_field
 	| unnamed_parameter server_flags ';'
 {
@@ -320,17 +324,90 @@ dclass_field:
 }
 	;
 
+struct:
+        KW_STRUCT optional_name 
+{
+  $$ = current_class;
+  current_class = new DCClass($2, true, false);
+}
+        struct_derivation '{' struct_fields '}'
+{
+  $$ = current_class;
+  current_class = $<u.dclass>3;
+}
+        ;
+
+struct_name:
+        IDENTIFIER
+{
+  DCClass *dstruct = dc_file->get_class_by_name($1);
+  if (dstruct == (DCClass *)NULL) {
+    // Create a bogus class as a forward reference.
+    dstruct = new DCClass($1, false, true);
+    dc_file->add_class(dstruct);
+  }
+  if (!dstruct->is_struct()) {
+    yyerror("struct name required");
+  }
+  
+  $$ = dstruct;
+}
+	;
+
+struct_derivation:
+        empty
+        | ':' struct_base_list
+        ;
+
+struct_base_list:
+        struct_name
+{
+  if ($1 != (DCClass *)NULL) {
+    current_class->add_parent($1);
+  }
+}
+        | struct_base_list ',' struct_name
+{
+  if ($3 != (DCClass *)NULL) {
+    current_class->add_parent($3);
+  }
+}
+        ;
+
+struct_fields:
+        empty
+        | struct_fields ';'
+        | struct_fields struct_field
+{
+  if (!current_class->add_field($2)) {
+    yyerror("Duplicate field name: " + $2->get_name());
+  }
+}
+        ;
+
+struct_field:
+	atomic_field
+	| molecular_field
+	| unnamed_parameter ';'
+{
+  $$ = $1;
+}
+	| named_parameter
+{
+  $$ = $1;
+}
+	;
+
 atomic_field:
         IDENTIFIER '('
 {
   $$ = current_atomic;
   current_atomic = new DCAtomicField($1);
 }
-        parameter_list ')' server_flags
+        parameter_list ')'
 {
   $$ = current_atomic;
   current_atomic = $<u.atomic>3;
-  $$->set_flags($6);
 }
         ;
 
@@ -454,6 +531,9 @@ type_name:
     // Maybe it's a class name.
     DCClass *dclass = dc_file->get_class_by_name($1);
     if (dclass != (DCClass *)NULL) {
+      if (!dclass->is_struct()) {
+        yyerror("cannot embed a dclass object within a message; use a struct");
+      }
       // Create an implicit typedef for this.
       dtypedef = new DCTypedef(new DCClassParameter(dclass), true);
     } else {
@@ -473,9 +553,9 @@ type_name:
 
   $$ = dtypedef->make_new_parameter();
 }
-	| dclass
+	| struct
 {
-  // This is an inline class definition.
+  // This is an inline struct definition.
   dc_file->add_thing_to_delete($1);
   $$ = new DCClassParameter($1);
 }

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