more restrictive grammar

This commit is contained in:
David Rose 2004-07-01 21:14:07 +00:00
parent a689a27760
commit 88975f5f9d
3 changed files with 779 additions and 608 deletions

View File

@ -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 Load Diff

View File

@ -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_derivation:
empty
| ':' base_list
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;
}
;
base_list:
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
| ':' dclass_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);
}