# # Interface Definition Language (OMG IDL CORBA v3.0) # use strict; use warnings; package CORBA::IDL::Scope; sub new { my $proto = shift; my $class = ref($proto) || $proto; my $self = {}; bless $self, $class; my($symbtab, $classname, $full, $name) = @_; $self->{class} = $classname; $self->{full} = $full; $self->{entry} = {}; return $self; } sub _Insert { my $self = shift; my($name, $defn) = @_; $self->{entry}->{lc $name} = $defn; } sub _Lookup { my $self = shift; return $self->{entry}->{lc shift}; } ############################################################################## package CORBA::IDL::Symbtab; our $VERSION = '2.63'; sub new { my $proto = shift; my $class = ref($proto) || $proto; my $self = {}; bless $self, $class; my($parser) = @_; $self->{current_root} = q{}; $self->{current_scope} = q{}; $self->{parser} = $parser; $self->{scopes} = { q{} => new CORBA::IDL::Scope($self, 'CORBA::IDL::Module', q{}, q{}) }; $self->{prefix} = {}; $self->{typeprefix} = {}; # C Mapping $self->{c_mapping} = {}; # $self->_Init(); return $self; } #sub _Init { # my $self = shift; #} sub _CheckCMapping { my $self = shift; my($full) = @_; my $c_key = $full; $c_key =~ s/^:://; $c_key =~ s/::/_/g; if (exists $self->{c_mapping}{$c_key}) { $self->{parser}->Info( "'$full' is ambiguous (C mapping) with '$self->{c_mapping}{$c_key}'.\n"); } else { $self->{c_mapping}{$c_key} = $full } } sub PushCurrentRoot { my $self = shift; my($node) = @_; my $name = $node->{idf}; my $class = ref $node; $class = substr $class, rindex($class, ':') + 1; ## print "PushCurrentRoot '$name' $class\n"; $self->{parser}->Error("PushCurrentRoot: INTERNAL_ERROR ($class).\n") unless ($class eq 'Module'); # OpenModule $self->{parser}->Error("PushCurrentRoot: INTERNAL_ERROR current_scope not empty ($self->{current_scope}).\n") if ($self->{current_scope}); delete $self->{msg} if (exists $self->{msg}); my $scope = $self->{current_root}; my $key_prefix = $self->{parser}->YYData->{filename} . $scope; my $new_scope = $self->{current_root} . '::' . $name; my $prev = $self->{scopes}->{$scope}->_Lookup($name); if (defined $prev) { while ($prev->isa('Entry')) { $prev = $self->{scopes}->{$prev->{scope}}->_Lookup($name); } if ($prev->isa('Modules')) { # reopen push @{$prev->{list_decl}}, $node; if ($prev->{prefix} ne $node->{prefix}) { $self->{parser}->Error("Prefix redefinition for '$name'.\n"); } } else { $self->{msg} ||= "Identifier '$name' already exists.\n"; $self->{parser}->Error($self->{msg}); unless (exists $self->{scopes}->{$new_scope}) { $self->{scopes}->{$new_scope} = new CORBA::IDL::Scope($self, ref $node, $new_scope, $name); my $modules = bless { idf => $name, full => $new_scope, prefix => $node->{prefix}, _typeprefix => $node->{_typeprefix}, list_decl => [ $node ], }, 'CORBA::IDL::Modules'; $modules->{typeprefix} = $node->{typeprefix} if (exists $node->{typeprefix}); $modules->{declspec} = $node->{declspec} if (exists $node->{declspec}); $self->{scopes}->{$new_scope}->_Insert($name, $modules); } } } else { $self->{scopes}->{$scope}->_Insert($name, bless({'scope' => $new_scope}, 'Entry')); $self->_CheckCMapping($new_scope); $self->{scopes}->{$new_scope} = new CORBA::IDL::Scope($self, ref $node, $new_scope, $name); my $modules = bless { idf => $name, full => $new_scope, prefix => $node->{prefix}, _typeprefix => $node->{_typeprefix}, list_decl => [ $node ], }, 'CORBA::IDL::Modules'; $modules->{typeprefix} = $node->{typeprefix} if (exists $node->{typeprefix}); $modules->{declspec} = $node->{declspec} if (exists $node->{declspec}); $self->{scopes}->{$new_scope}->_Insert($name, $modules); } $self->{current_root} = $new_scope; $node->{full} = $new_scope; if (defined $node->{_typeprefix}) { my $typeprefix = $node->{_typeprefix}; if ($typeprefix) { $typeprefix .= '/' . $node->{idf}; } else { $typeprefix = $node->{idf}; } $self->{typeprefix}->{$new_scope} = $typeprefix; } else { $key_prefix .= '::' . $node->{idf}; my $prefix = $node->{prefix}; if ($prefix) { $prefix .= '/' . $node->{idf}; } else { $prefix = $node->{idf}; } $self->{prefix}->{$key_prefix} = $prefix; } return; } sub PopCurrentRoot { my $self = shift; my($node) = @_; return unless (defined $node); return if ($self->{current_root} =~ s/::$node->{idf}$//); $self->{parser}->Error( "PopCurrentRoot: INTERNAL_ERROR $self->{current_root} $node->{idf}.\n"); return; } sub PushCurrentScope { my $self = shift; my($node) = @_; my $name = $node->{idf}; my $class = ref $node; $class = substr $class, rindex($class, ':') + 1; ## print "PushCurrentScope '$name' $class\n"; # Insert delete $self->{msg} if (exists $self->{msg}); my $scope = $self->{current_root} . $self->{current_scope}; my $key_prefix = $self->{parser}->YYData->{filename} . $scope; my $new_scope = $scope . '::' . $name; my $prev = $self->{scopes}->{$scope}->_Lookup($name); if (defined $prev) { while ($prev->isa('Entry')) { $prev = $self->{scopes}->{$prev->{scope}}->_Lookup($name); } if ($prev->isa('Forward' . $class)) { # the previous must be the same foreach (keys %{$prev}) { if ( $_ eq 'full' or $_ eq 'filename' or $_ eq 'lineno' or $_ eq 'typeprefix' or $_ eq '_typeprefix' or $_ eq 'hash_attribute_operation' ) { next; } if ( $_ eq 'id' or $_ eq 'version' ) { $node->{$_} = $prev->{$_}; next; } if ($prev->{$_} ne $node->{$_}) { ## print "$_ $prev->{$_} $node->{$_}\n"; if ($_ eq 'prefix') { unless (defined $node->{_typeprefix}) { $self->{parser}->Error( "Prefix redefinition for '$name'.\n"); } next; } $self->{parser}->Error( "Definition of '$name' conflicts with previous declaration.\n"); return; } } $node->{typeprefix} = $prev->{typeprefix} if (exists $prev->{typeprefix}); $self->{scopes}->{$scope}->_Insert($name, bless({'scope' => $new_scope}, 'Entry')); $self->{scopes}->{$new_scope} = new CORBA::IDL::Scope($self, ref $node, $new_scope, $name); $self->{scopes}->{$new_scope}->_Insert($name, $node); } else { $self->{msg} ||= "Identifier '$name' already exists.\n"; $self->{parser}->Error($self->{msg}); unless (exists $self->{scopes}->{$new_scope}) { $self->{scopes}->{$new_scope} = new CORBA::IDL::Scope($self, ref $node, $new_scope, $name); $self->{scopes}->{$new_scope}->_Insert($name, $node); } } } else { $self->{scopes}->{$scope}->_Insert($name, bless({'scope' => $new_scope}, 'Entry')); $self->_CheckCMapping($new_scope); $self->{scopes}->{$new_scope} = new CORBA::IDL::Scope($self, ref $node, $new_scope, $name); $self->{scopes}->{$new_scope}->_Insert($name, $node); } $self->{current_scope} .= '::' . $name; $node->{full} = $new_scope; if (defined $node->{_typeprefix}) { my $typeprefix = $node->{_typeprefix}; if ($typeprefix) { $typeprefix .= '/' . $node->{idf}; } else { $typeprefix = $node->{idf}; } $self->{typeprefix}->{$new_scope} = $typeprefix; } else { $key_prefix .= '::' . $node->{idf}; my $prefix = $node->{prefix}; if ($prefix) { $prefix .= '/' . $node->{idf}; } else { $prefix = $node->{idf}; } $self->{prefix}->{$key_prefix} = $prefix; } return; } sub PopCurrentScope { my $self = shift; my($node) = @_; return unless (defined $node); return if ($self->{current_scope} =~ s/::$node->{idf}$//); $self->{parser}->Error( "PopCurrentScope: INTERNAL_ERROR $self->{current_scope} $node->{idf}.\n"); return; } sub Insert { my $self = shift; my($node) = @_; if ($node->isa('Specification')) { $node->{full} = q{}; $self->{scopes}->{''}->_Insert(q{}, $node); return; } my $name = $node->{idf}; return unless ($name); delete $self->{msg} if (exists $self->{msg}); my $scope = $self->{current_root} . $self->{current_scope}; ## print "Insert '$name' ",ref $node," => $scope\n"; unless (exists $self->{scopes}->{$scope}) { warn "'$scope' not exist.\n"; return; } my $prev = $self->{scopes}->{$scope}->_Lookup($name); if (defined $prev) { while ($prev->isa('Entry')) { $prev = $self->{scopes}->{$prev->{scope}}->_Lookup($name); } my $class = ref $prev; $class = substr $class, rindex($class, ':') + 1; if ($class =~ s/^Forward//) { if (ref $node ne $class) { $self->{parser}->Error( "Definition of '$name' conflicts with previous declaration.\n"); return; } else { # the previous must be the same foreach (keys %{$prev}) { if ( $_ eq 'full' or $_ eq 'lineno' or $_ eq 'hash_attribute_operation' ) { next; } if ( $_ eq 'id' or $_ eq 'version' ) { $node->{$_} = $prev->{$_}; next; } if ($_ eq 'filename') { if ( $prev->isa('ForwardStruct') or $prev->isa('ForwardUnion') ) { if ($prev->{$_} ne $node->{$_}) { $self->{parser}->Error( "Definition of '$name' is not in the same file.\n"); } } next; } if ($prev->{$_} ne $node->{$_}) { if ($_ eq 'prefix') { unless (defined $node->{_typeprefix}) { $self->{parser}->Error( "Prefix redefinition for '$name'.\n"); } next; } $self->{parser}->Error( "Definition of '$name' conflicts with previous declaration.\n"); } } } } else { if ($prev->{idf} eq $name) { $self->{msg} ||= "Identifier '$name' already exists.\n"; } else { $self->{msg} ||= "Identifier '$name' collides with '$prev->{idf}'.\n"; } $self->{parser}->Error($self->{msg}); return; } } # insert $node->{full} = $scope . '::' . $name; $self->{scopes}->{$scope}->_Insert($name, $node); $self->_CheckCMapping($node->{full}); return; } sub InsertForward { my $self = shift; my($node) = @_; my $name = $node->{idf}; return unless ($name); my $class = ref $node; $class = substr $class, rindex($class, ':') + 1; ## print "InsertForward '$name' '$node->{idf}'\n"; delete $self->{msg} if (exists $self->{msg}); my $scope = $self->{current_root} . $self->{current_scope}; my $prev = $self->{scopes}->{$scope}->_Lookup($name); if (defined $prev) { while ($prev->isa('Entry')) { $prev = $self->{scopes}->{$prev->{scope}}->_Lookup($name); } my $class = ref $prev; $class = substr $class, rindex($class, ':') + 1; if ($class =~ /^Forward/) { # redeclaration if (ref $node ne ref $prev) { $self->{parser}->Error( "Definition of '$name' conflicts with previous declaration.\n"); return; } else { # the previous must be the same foreach (keys %{$prev}) { if ( $_ eq 'full' or $_ eq 'lineno' or $_ eq 'filename' or $_ eq 'typeprefix' or $_ eq '_typeprefix' ) { next; } if ( $_ eq 'id' or $_ eq 'version' ) { $node->{$_} = $prev->{$_}; next; } if ($prev->{$_} ne $node->{$_}) { if ($_ eq 'prefix') { unless (defined $node->{_typeprefix}) { $self->{parser}->Error( "Prefix redefinition for '$name'.\n"); } next; } $self->{parser}->Error( "Definition of '$name' conflicts with previous declaration.\n"); return; } } } } else { $self->{msg} ||= "Identifier '$name' already exists.\n"; $self->{parser}->Error($self->{msg}); return; } } # insert $node->{full} = $scope . '::' . $name; $self->{scopes}->{$scope}->_Insert($name, $node); return; } sub InsertInherit { my $self = shift; my($node, $name, $full) = @_; ## print "InsertInherit '$name' $full \n"; # Insert delete $self->{msg} if (exists $self->{msg}); my $scope = $self->{current_root} . $self->{current_scope}; my $prev = $self->{scopes}->{$scope}->_Lookup($name); if (defined $prev) { $self->{parser}->Error(__PACKAGE__ . "::InsertInherit: INTERNAL_ERROR ($full).\n"); } else { my $scope_base = $full; $scope_base =~ s/::[0-9A-Z_a-z]+$//; $self->{scopes}->{$scope}->_Insert($name, bless({'scope' => $scope_base}, 'Entry')); } return; } sub InsertBogus { my $self = shift; my($node) = @_; my $scope = $self->{current_root} . $self->{current_scope}; $node->{full} = $scope . '::_seq_'; } sub Lookup { my $self = shift; my($name) = @_; delete $self->{msg} if (exists $self->{msg}); if (ref $name) { warn __PACKAGE__,"::Lookup $name ",caller," PB\n"; return $name; } my $defn = $self->_Lookup($name); if (defined $defn) { $self->{parser}->Error($self->{msg}) if (exists $self->{msg}); } else { ## print __PACKAGE__,"::Lookup $name ",caller()," PB\n"; $self->{parser}->Error("Undefined symbol '$name'.\n"); } return $defn; } sub _Lookup { my $self = shift; my($name) = @_; my $defn; ## print "_Lookup: '$name'\n"; if (ref $name) { warn __PACKAGE__,"::_Lookup $name ",caller," PB\n"; return $name; } return undef unless ($name); if ($name =~ /^::/) { # global name ## print "_global name.\n"; return $self->___Lookup($name); } elsif ($name =~ /^[0-9A-Z_a-z]+$/) { # identifier alone my $scope_init = $self->{current_root} . $self->{current_scope}; my $scope = $scope_init; ## print "_Lookup init : '$scope'\n"; while (1) { # Section 3.15.3 Special Scoping Rules for Type Names my $g_name = $scope . '::' . $name; $defn = $self->__Lookup($scope, $g_name, $name); last if (defined $defn || $scope eq ''); $scope =~ s/::[0-9A-Z_a-z]+$//; ## print "_Lookup curr : '$scope'\n"; }; if (defined $defn) { ## print "_found $name $scope_init $scope\n"; my $scope_real = $defn->{full}; $scope_real =~ s/::[0-9A-Z_a-z]+$//; while ($scope_init ne $scope) { my $node = $self->___Lookup($scope_init); if ($defn->isa('Modules') or ! $node->isa('Modules')) { ## print "_insert $name $scope_init $scope_real\n"; $self->{scopes}->{$scope_init}->_Insert($name, bless({'scope' => $scope_real}, 'Entry')); } $scope_init =~ s/::[0-9A-Z_a-z]+$//; } } return $defn; } else { # qualified name my @list = split /::/, $name; my $idf = pop @list; my $scoped_name = $name; $scoped_name =~ s/::[0-9A-Z_a-z]+$//; ## print "_qualified name : '$scoped_name' '$idf'\n"; my $scope = $self->_Lookup($scoped_name); # recursive if (defined $scope) { $defn = $self->___Lookup($scope->{full} . '::' . $idf); } return $defn; } } sub __Lookup { my $self = shift; my ($scope, $g_name, $name) = @_; ## print "__Lookup: '$scope' '$g_name' '$name'\n"; my $defn = $self->___Lookup($g_name); return $defn if (defined $defn); return undef unless($scope); my $node = $self->___Lookup($scope); if (defined $node) { ## print "__inherit $node->{full}\n"; my @list; foreach ($node->getInheritance()) { my $base = $self->Lookup($_); if (defined $base) { $g_name = $base->{full} . '::' . $name; $defn = $self->___Lookup($g_name); if (defined $defn) { my $found = 0; foreach (@list) { if ($defn == $_) { $found = 1; last; } } push @list, $defn unless ($found); } } } if (@list) { if (scalar @list > 1) { $self->{parser}->Error("Ambiguous symbol '$name'.\n"); } return pop @list; } } return undef; } sub ___Lookup { my $self = shift; my ($full) = @_; ## print "___Lookup: '$full'\n"; if ($full =~ /^((?:::[0-9A-Z_a-z]+)*)::([0-9A-Z_a-z]+)$/) { if (exists $self->{scopes}->{$1}) { my $defn = $self->{scopes}->{$1}->_Lookup($2); if (defined $defn) { while ($defn->isa('Entry')) { $defn = $self->{scopes}->{$defn->{scope}}->_Lookup($2); last unless (defined $defn); } unless (defined $defn) { $self->{parser}->Error(__PACKAGE__ . "::___Lookup: INTERNAL_ERROR ($full).\n"); return undef; } if ($defn->{idf} ne $2) { $self->{msg} = "Identifier '$2' collides with '$defn->{idf}'.\n"; } ## print "___found $defn->{full}\n"; return $defn; } else { ## print "___not found '$2' in '$1'.\n"; return undef; } } else { ## print "___not found scope '$1'.\n"; return undef; } } else { $self->{parser}->Error(__PACKAGE__ . "::___Lookup: INTERNAL_ERROR not match ($full).\n"); return undef; } } sub PragmaID { # 10.7.5.1 The ID Pragma my $self = shift; my($name, $id) = @_; my $node = $self->Lookup($name); if (defined $node) { if (exists $node->{typeid}) { $self->{parser}->Warning("TypeId/pragma conflict for '$self->{idf}'.\n"); } if (exists $node->{id}) { $self->{parser}->Error("Repository ID redefinition for '$name'.\n") unless ($id eq $node->{id}); } else { $node->{id} = $id; $self->CheckID($node, $id); } if ($node->isa('Modules')) { foreach (@{$node->{list_decl}}) { if ($_->{filename} eq $self->{parser}->YYData->{filename}) { $_->{id} = $id; } } } } else { $self->{parser}->Warning("Undefined symbol '$name' for '$id'.\n") } } sub CheckID { my $self = shift; my($node, $id) = @_; if ($id =~ /^IDL:/) { # 10.7.1 OMG IDL Format if ($id =~ /^IDL:[0-9A-Za-z_:\.\/\-]+:([0-9]+)\.([0-9]+)/) { my $version = $1 . '.' . $2; if (exists $node->{version}) { $self->{parser}->Error("Version redefinition for '$node->{idf}'.\n") unless ($version eq $node->{version}); } else { $node->{version} = $version; } } else { $self->{parser}->Error("Bad IDL format for Repository ID '$id'.\n"); } } elsif ($id =~ /^RMI:/) { # 10.7.2 RMI Hashed Format $self->{parser}->Error("Bad RMI format for Repository ID '$id'.\n") unless ($id =~ /^RMI:[0-9A-Za-z_\[\-\.\/\$\\]+:[0-9A-Fa-f]{16}(:[0-9A-Fa-f]{16})?/); } elsif ($id =~ /^DCE:/) { # 10.7.3 DCE UUID Format $self->{parser}->Error("Bad DCE format for Repository ID '$id'.\n") unless ($id =~ /^DCE:[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}(:[0-9]+)?/); } elsif ($id =~ /^LOCAL:/) { # 10.7.4 LOCAL Format # followed by an arbitrary string. } } sub PragmaPrefix { # 10.7.5.2 The Prefix Pragma my $self = shift; my($prefix) = @_; my $key_prefix = $self->{parser}->YYData->{filename} . $self->{current_root} . $self->{current_scope}; $self->{prefix}->{$key_prefix} = $prefix; } sub GetPrefix { my $self = shift; my $scope = $self->{current_root} . $self->{current_scope}; my $key_prefix = $self->{parser}->YYData->{filename} . $scope; if (exists $self->{prefix}->{$key_prefix}) { return $self->{prefix}->{$key_prefix}; } else { return q{}; } } sub GetTypePrefix { my $self = shift; my $scope = $self->{current_root} . $self->{current_scope}; if (exists $self->{typeprefix}->{$scope}) { return $self->{typeprefix}->{$scope}; } else { return undef; } } sub PragmaVersion { # 10.7.5.3 The Version Pragma my $self = shift; my($name, $major, $minor) = @_; my $version = $major . '.' . $minor; my $node = $self->Lookup($name); if (defined $node) { if (exists $node->{version}) { $self->{parser}->Error("Version redefinition for '$name'.\n") unless ($version eq $node->{version}); } else { $node->{version} = $version; } } } sub CheckForward { my $self = shift; foreach my $scope (values %{$self->{scopes}}) { foreach my $entry (values %{$scope->{entry}}) { if ($entry->isa('_ForwardConstructedType')) { $self->{parser}->Error("'$entry->{idf}' never defined.\n"); } } } } sub CheckRepositoryID { my $self = shift; foreach my $scope (values %{$self->{scopes}}) { foreach my $entry (values %{$scope->{entry}}) { if ($entry->isa('Modules') and exists $entry->{id}) { foreach (@{$entry->{list_decl}}) { if ( ! exists $_->{id} or $_->{id} ne $entry->{id} ) { $self->{parser}->Error("Repository ID inconsistent for '$entry->{idf}'.\n"); } } } } } } sub Import { my $self = shift; my($node) = @_; my %imports = ($node->{value} => 1) ; my $dirname = $self->{parser}->YYData->{opt_i}; my $fullname = $node->{value}; $fullname =~ s/::/_/g; my $filename = $fullname . '.mod'; $filename = $dirname . '/' . $filename if ($dirname); require $filename; my $scope = eval('$main::' . $fullname); if (defined $scope and $scope->isa('CORBA::IDL::Scope')) { my $class = $scope->{class}; if ( $class eq 'CORBA::IDL::Module' or $class eq 'CORBA::IDL::RegularInterface' or $class eq 'CORBA::IDL::LocalInterface' or $class eq 'CORBA::IDL::AbstractInterface' or $class eq 'CORBA::IDL::RegularValue' or $class eq 'CORBA::IDL::BoxedValue' or $class eq 'CORBA::IDL::AbstractValue' or $class eq 'CORBA::IDL::RegularEvent' or $class eq 'CORBA::IDL::AbstractEvent' ) { $self->{scopes}->{$node->{value}} = $scope; my $root = $node->{value}; $root =~ s/::([0-9A-Z_a-z]+)$//; my $name = lc $1; $self->{scopes}->{$root}->_Insert($name, bless({'scope' => $node->{value}}, 'Entry')); foreach (values %{$scope->{entry}}) { next if (ref $_ ne 'Entry'); next if (exists $self->{scopes}->{$_->{scope}}); $self->_Import($_->{scope}, \%imports); } $node->{list_decl} = [ keys %imports ]; } else { $self->{parser}->Error("'$node->{value}' can't imported (bad type).\n"); } } else { $self->{parser}->Error("Import: INTERNAL_ERROR ($node->{value}).\n"); } } sub _Import { my $self = shift; my($full, $r_import) = @_; $r_import->{$full} = 1; my $dirname = $self->{parser}->YYData->{opt_i}; my $fullname = $full; $fullname =~ s/::/_/g; my $filename = $fullname . '.mod'; $filename = $dirname . '/' . $filename if ($dirname); require $filename; my $scope = eval('$main::' . $fullname); if (defined $scope and $scope->isa('CORBA::IDL::Scope')) { $self->{scopes}->{$full} = $scope; my $root = $full; $root =~ s/::([0-9A-Z_a-z]+)$//; my $name = lc $1; $self->{scopes}->{$root}->_Insert($name, bless({'scope' => $full}, 'Entry')); foreach (values %{$scope->{entry}}) { next if (ref $_ ne 'Entry'); next if (exists $self->{scopes}->{$_->{scope}}); $self->_Import($_->{scope}, $r_import); } } else { $self->{parser}->Error("_Import: INTERNAL_ERROR ($full).\n"); } } sub Export { my $self = shift; use Data::Dumper; my $dirname = $self->{parser}->YYData->{opt_i}; if ($dirname) { unless (-d $dirname) { mkdir $dirname or die "can't create $dirname ($!).\n"; } } foreach my $scope (values %{$self->{scopes}}) { my $fullname = $scope->{full}; next unless ($fullname); $fullname =~ s/::/_/g; my $filename = $fullname . '.mod'; $filename = $dirname . '/' . $filename if ($dirname); open my $OUT, '>', $filename or die "can't open $filename ($!).\n"; my $d = Data::Dumper->new([$scope], [$fullname]); $d->Indent(1); # $d->Indent(0); $d->Purity(1); print $OUT "package main;\n"; print $OUT $d->Dump(); close $OUT; } } sub Dump { my $self = shift; use Data::Dumper; my $d = Data::Dumper->new([$self->{scopes}], [qw(scopes)]); $d->Indent(1); # $d->Indent(0); print $d->Dump(); } ############################################################################## package CORBA::IDL::UnnamedSymbtab; sub new { my $proto = shift; my $class = ref($proto) || $proto; my($parser) = @_; my $self = {}; bless $self, $class; $self->{parser} = $parser; $self->{entry} = {}; return $self; } sub Insert { my $self = shift; my($name) = @_; ## print "Insert '$name'\n"; my $key = lc $name; if (exists $self->{entry}{$key}) { if ($self->{entry}{$key} eq $name) { $self->{parser}->Error( "Identifier '$name' already exists.\n"); } else { $self->{parser}->Error( "Identifier '$name' collides with '$self->{entry}{$key}'.\n"); } } else { $self->{entry}{$key} = $name; } return; } sub InsertUsed { my $self = shift; return if ($self->{parser}->YYData->{collision_allowed}); my($name) = @_; ## print "InsertUsed '$name'\n"; my $key = lc $name; $self->{entry}{$key} = $name unless (exists $self->{entry}{$key}); return; } 1;