# # Interface Definition Language (OMG IDL CORBA v3.0) # package CORBA::IDL::AsciiVisitor; use strict; use warnings; our $VERSION = '2.60'; use File::Basename; sub new { my $proto = shift; my $class = ref($proto) || $proto; my $self = {}; bless($self, $class); my ($parser, $doc) = @_; $self->{srcname} = $parser->YYData->{srcname}; $self->{symbtab} = $parser->YYData->{symbtab}; $self->{doc} = $doc; my $filename = basename($self->{srcname}, '.idl') . '.ast'; open STDOUT, '>', $filename or die "can't open $filename ($!).\n"; $self->{num_key} = 'num_ascii'; return $self; } sub reset_tab { my $self = shift; $self->{tab} = q{}; } sub inc_tab { my $self = shift; $self->{tab} .= "\t"; } sub dec_tab { my $self = shift; $self->{tab} =~ s/\t$//; } sub get_tab { my $self = shift; return $self->{tab}; } sub _get_defn { my $self = shift; my ($defn) = @_; if (ref $defn) { return $defn; } else { return $self->{symbtab}->Lookup($defn); } } sub visitType { my $self = shift; my ($type) = @_; if (ref $type) { $type->visit($self); } else { print $self->get_tab(), "type $type\n"; } } # # 3.5 OMG IDL Specification # sub visitSpecification { my $self = shift; my ($node) = @_; $self->reset_tab(); print "source $self->{srcname} \n\n"; if (exists $node->{list_import}) { foreach (@{$node->{list_import}}) { $self->_get_defn($_)->visit($self); } print "\n"; } foreach (@{$node->{list_decl}}) { $self->_get_defn($_)->visit($self); } } # # 3.6 Import Declaration # sub visitImport { my $self = shift; my ($node) = @_; print $self->get_tab(), "import $node->{value}\n"; $self->inc_tab(); foreach (@{$node->{list_decl}}) { print $self->get_tab(),$_,"\n"; } $self->dec_tab(); } # # 3.7 Module Declaration # sub visitModules { my $self = shift; my ($node) = @_; print $self->get_tab(), "module $node->{idf} '$node->{repos_id}'\n"; unless (exists $node->{$self->{num_key}}) { $node->{$self->{num_key}} = 0; } my $module = ${$node->{list_decl}}[$node->{$self->{num_key}}]; $module->visit($self); $node->{$self->{num_key}} ++; } sub visitModule { my $self = shift; my ($node) = @_; $self->inc_tab(); $self->_xp($node); print $self->get_tab(), "doc: $node->{doc}\n" if ($self->{doc} and exists $node->{doc}); foreach (@{$node->{list_decl}}) { $self->_get_defn($_)->visit($self); } $self->dec_tab(); } # # 3.8 Interface Declaration # sub visitRegularInterface { my $self = shift; my ($node) = @_; print $self->get_tab(), "interface $node->{idf} '$node->{repos_id}'\n"; $self->inc_tab(); $self->_xp($node); print $self->get_tab(), "doc: $node->{doc}\n" if ($self->{doc} and exists $node->{doc}); if (exists $node->{inheritance}) { $node->{inheritance}->visit($self); } foreach (@{$node->{list_decl}}) { $self->_get_defn($_)->visit($self); } $self->dec_tab(); } sub visitAbstractInterface { my $self = shift; my ($node) = @_; print $self->get_tab(), "interface $node->{idf} '$node->{repos_id}'\n"; $self->inc_tab(); $self->_xp($node); print $self->get_tab(), "doc: $node->{doc}\n" if ($self->{doc} and exists $node->{doc}); if (exists $node->{inheritance}) { $node->{inheritance}->visit($self); } foreach (@{$node->{list_decl}}) { $self->_get_defn($_)->visit($self); } $self->dec_tab(); } sub visitLocalInterface { my $self = shift; my ($node) = @_; print $self->get_tab(), "local interface $node->{idf} '$node->{repos_id}'\n"; $self->inc_tab(); $self->_xp($node); print $self->get_tab(), "doc: $node->{doc}\n" if ($self->{doc} and exists $node->{doc}); if (exists $node->{inheritance}) { $node->{inheritance}->visit($self); } foreach (@{$node->{list_decl}}) { $self->_get_defn($_)->visit($self); } $self->dec_tab(); } sub visitForwardRegularInterface { my $self = shift; my ($node) = @_; print $self->get_tab(), "forward interface $node->{idf}\n"; $self->inc_tab(); $self->_xp($node); $self->dec_tab(); } sub visitForwardAbstractInterface { my $self = shift; my ($node) = @_; print $self->get_tab(), "forward abstract interface $node->{idf}\n"; $self->inc_tab(); $self->_xp($node); $self->dec_tab(); } sub visitForwardLocalInterface { my $self = shift; my ($node) = @_; print $self->get_tab(), "forward local interface $node->{idf}\n"; $self->inc_tab(); $self->_xp($node); $self->dec_tab(); } # # 3.9 Value Declaration # # 3.9.1 Regular Value Type # sub visitRegularValue { my $self = shift; my ($node) = @_; print $self->get_tab(), "regular value $node->{idf} '$node->{repos_id}'\n"; $self->inc_tab(); $self->_xp($node); print $self->get_tab(), "doc: $node->{doc}\n" if ($self->{doc} and exists $node->{doc}); if (exists $node->{modifier}) { # custom print $self->get_tab(), "modifier $node->{modifier}\n"; } if (exists $node->{inheritance}) { $node->{inheritance}->visit($self); } foreach (@{$node->{list_decl}}) { $self->_get_defn($_)->visit($self); } $self->dec_tab(); } sub visitInheritanceSpec { my $self = shift; my ($node) = @_; print $self->get_tab(), "inheritance spec\n"; $self->inc_tab(); if (exists $node->{modifier}) { # truncatable print $self->get_tab(), "modifier $node->{modifier}\n"; } if (exists $node->{list_value}) { foreach (@{$node->{list_value}}) { print $self->get_tab(), "value $_\n"; } } if (exists $node->{list_interface}) { foreach (@{$node->{list_interface}}) { print $self->get_tab(), "interface $_\n"; } } $self->dec_tab(); } sub visitStateMembers { my $self = shift; my ($node) = @_; print $self->get_tab(), "state members\n"; $self->_xp($node); $self->inc_tab(); foreach (@{$node->{list_decl}}) { $self->_get_defn($_)->visit($self); } $self->dec_tab(); } sub visitStateMember { my $self = shift; my ($node) = @_; print $self->get_tab(), "$node->{modifier} $node->{idf}\n"; $self->inc_tab(); $self->visitType($node->{type}); if (exists $node->{array_size}) { foreach (@{$node->{array_size}}) { $_->visit($self); # expression } } $self->dec_tab(); } sub visitInitializer { my $self = shift; my ($node) = @_; print $self->get_tab(), "factory $node->{idf}\n"; $self->inc_tab(); $self->_xp($node); print $self->get_tab(), "doc: $node->{doc}\n" if ($self->{doc} and exists $node->{doc}); foreach (@{$node->{list_param}}) { $_->visit($self); } if (exists $node->{list_raise}) { foreach (@{$node->{list_raise}}) { # exception print $self->get_tab(), "raise $_\n"; } } $self->dec_tab(); } # # 3.9.2 Boxed Value Type # sub visitBoxedValue { my $self = shift; my ($node) = @_; print $self->get_tab(), "boxed value $node->{idf} '$node->{repos_id}'\n"; $self->inc_tab(); $self->_xp($node); print $self->get_tab(), "doc: $node->{doc}\n" if ($self->{doc} and exists $node->{doc}); $self->visitType($node->{type}); $self->dec_tab(); } # # 3.9.3 Abstract Value Type # sub visitAbstractValue { my $self = shift; my ($node) = @_; print $self->get_tab(), "abstract value $node->{idf} '$node->{repos_id}'\n"; $self->inc_tab(); $self->_xp($node); print $self->get_tab(), "doc: $node->{doc}\n" if ($self->{doc} and exists $node->{doc}); if (exists $node->{inheritance}) { $node->{inheritance}->visit($self); } foreach (@{$node->{list_decl}}) { $self->_get_defn($_)->visit($self); } $self->dec_tab(); } # # 3.9.4 Value Forward Declaration # sub visitForwardRegularValue { my $self = shift; my ($node) = @_; print $self->get_tab(), "forward regular value $node->{idf}\n"; $self->inc_tab(); $self->_xp($node); $self->dec_tab(); } sub visitForwardAbstractValue { my $self = shift; my ($node) = @_; print $self->get_tab(), "forward abstract value $node->{idf}\n"; $self->inc_tab(); $self->_xp($node); $self->dec_tab(); } # # 3.10 Constant Declaration # sub visitConstant { my $self = shift; my ($node) = @_; print $self->get_tab(), "constant $node->{idf}\n"; $self->inc_tab(); $self->_xp($node); print $self->get_tab(), "doc: $node->{doc}\n" if ($self->{doc} and exists $node->{doc}); $self->visitType($node->{type}); $node->{value}->visit($self); # expression $self->dec_tab(); } sub visitExpression { my $self = shift; my ($node) = @_; print $self->get_tab(), "expression value $node->{value}\n"; $self->inc_tab(); foreach my $elt (@{$node->{list_expr}}) { if (ref $elt) { if ($elt->isa('Constant')) { print $self->get_tab(), "constant $elt->{idf}\n"; } else { $elt->visit($self); # literal, unop, binop } } else { print $self->get_tab(), "entry $elt\n"; } } $self->dec_tab(); } sub visitUnaryOp { my $self = shift; my ($node) = @_; print $self->get_tab(), "unop $node->{op}\n"; } sub visitBinaryOp { my $self = shift; my ($node) = @_; print $self->get_tab(), "binop $node->{op}\n"; } sub visitLiteral { my $self = shift; my ($node) = @_; print $self->get_tab(), "literal $node->{value}\n"; } # # 3.11 Type Declaration # sub visitTypeDeclarators { my $self = shift; my ($node) = @_; print $self->get_tab(), "type declarators\n"; $self->inc_tab(); $self->_xp($node); foreach (@{$node->{list_decl}}) { $self->_get_defn($_)->visit($self); } $self->dec_tab(); } sub visitTypeDeclarator { my $self = shift; my ($node) = @_; print $self->get_tab(), "type declarator $node->{idf} '$node->{repos_id}'\n"; $self->inc_tab(); $self->_xp($node); print $self->get_tab(), "doc: $node->{doc}\n" if ($self->{doc} and exists $node->{doc}); $self->visitType($node->{type}); if (exists $node->{array_size}) { foreach (@{$node->{array_size}}) { $_->visit($self); # expression } } $self->dec_tab(); } sub visitNativeType { my $self = shift; my ($node) = @_; print $self->get_tab(), "native $node->{idf}\n"; $self->inc_tab(); $self->_xp($node); $self->dec_tab(); } # # 3.11.1 Basic Types # sub visitBasicType { my $self = shift; my ($node) = @_; print $self->get_tab(), "basic type $node->{value}\n"; } # # 3.11.2 Constructed Types # # 3.11.2.1 Structures # sub visitStructType { my $self = shift; my ($node) = @_; if (defined $node->{list_expr}) { print $self->get_tab(), "struct $node->{idf} '$node->{repos_id}'\n"; $self->inc_tab(); $self->_xp($node); push @{$self->{seq}}, $node; foreach (@{$node->{list_expr}}) { $_->visit($self); # members } # foreach (@{$node->{list_member}}) { # $self->_get_defn($_)->visit($self); # member # } pop @{$self->{seq}}; $self->dec_tab(); } else { print $self->get_tab(), "struct $node->{idf} (forward)\n"; } } sub visitMembers { my $self = shift; my ($node) = @_; print $self->get_tab(), "members\n"; $self->inc_tab(); foreach (@{$node->{list_member}}) { $self->_get_defn($_)->visit($self); } $self->dec_tab(); } sub visitMember { my $self = shift; my ($node) = @_; print $self->get_tab(), "member $node->{idf}\n"; $self->inc_tab(); $self->visitType($node->{type}); if (exists $node->{array_size}) { foreach (@{$node->{array_size}}) { $_->visit($self); # expression } } $self->dec_tab(); } # 3.11.2.2 Discriminated Unions # sub visitUnionType { my $self = shift; my ($node) = @_; if (defined $node->{list_expr}) { print $self->get_tab(), "union $node->{idf} '$node->{repos_id}'\n"; $self->inc_tab(); $self->_xp($node); print $self->get_tab(), "doc: $node->{doc}\n" if ($self->{doc} and exists $node->{doc}); push @{$self->{seq}}, $node; foreach (@{$node->{list_expr}}) { $_->visit($self); # case } pop @{$self->{seq}}; $self->dec_tab(); } else { print $self->get_tab(), "union $node->{idf} (forward)\n"; } } sub visitCase { my $self = shift; my ($node) = @_; print $self->get_tab(), "case\n"; $self->inc_tab(); foreach (@{$node->{list_label}}) { $_->visit($self); # default or expression } $node->{element}->visit($self); $self->dec_tab(); } sub visitDefault { my $self = shift; my ($node) = @_; print $self->get_tab(), "default\n"; } sub visitElement { my $self = shift; my ($node) = @_; $self->_get_defn($node->{value})->visit($self); # member } # 3.11.2.3 Constructed Recursive Types and Forward Declarations # sub visitForwardStructType { my $self = shift; my ($node) = @_; print $self->get_tab(), "forward struct $node->{idf}\n"; } sub visitForwardUnionType { my $self = shift; my ($node) = @_; print $self->get_tab(), "forward union $node->{idf}\n"; } # 3.11.2.4 Enumerations # sub visitEnumType { my $self = shift; my ($node) = @_; print $self->get_tab(), "enum $node->{idf} '$node->{repos_id}'\n"; $self->inc_tab(); $self->_xp($node); print $self->get_tab(), "doc: $node->{doc}\n" if ($self->{doc} and exists $node->{doc}); foreach (@{$node->{list_expr}}) { $_->visit($self); # enum } $self->dec_tab(); } sub visitEnum { my $self = shift; my ($node) = @_; print $self->get_tab(), "$node->{idf}\n"; } # # 3.11.3 Template Types # sub visitSequenceType { my $self = shift; my ($node) = @_; print $self->get_tab(), "sequence\n"; $self->inc_tab(); my $found = 0; # recursion prevention foreach (@{$self->{seq}}) { if ($_ eq $node->{type}) { $found = 1; last; } } if ($found) { print $self->get_tab(), "recursion $node->{type}\n"; } else { push @{$self->{seq}}, $node; $self->visitType($node->{type}); pop @{$self->{seq}}; } if (exists $node->{max}) { $node->{max}->visit($self); } $self->dec_tab(); } sub visitStringType { my $self = shift; my ($node) = @_; print $self->get_tab(), "string\n"; $self->inc_tab(); if (exists $node->{max}) { $node->{max}->visit($self); } $self->dec_tab(); } sub visitWideStringType { my $self = shift; my ($node) = @_; print $self->get_tab(), "wstring\n"; $self->inc_tab(); if (exists $node->{max}) { $node->{max}->visit($self); } $self->dec_tab(); } sub visitFixedPtType { my $self = shift; my ($node) = @_; print $self->get_tab(), "fixed\n"; $self->inc_tab(); $node->{d}->visit($self); $node->{s}->visit($self); $self->dec_tab(); } sub visitFixedPtConstType { my $self = shift; my ($node) = @_; print $self->get_tab(), "fixed\n"; } # # 3.12 Exception Declaration # sub visitException { my $self = shift; my ($node) = @_; print $self->get_tab(), "exception $node->{idf} '$node->{repos_id}'\n"; $self->inc_tab(); $self->_xp($node); print $self->get_tab(), "doc: $node->{doc}\n" if ($self->{doc} and exists $node->{doc}); if (exists $node->{list_expr}) { foreach (@{$node->{list_expr}}) { $_->visit($self); # members } } # foreach (@{$node->{list_member}}) { # $self->_get_defn($_)->visit($self); # member # } $self->dec_tab(); } # # 3.13 Operation Declaration # sub visitOperation { my $self = shift; my ($node) = @_; print $self->get_tab(), "operation $node->{idf}\n"; $self->inc_tab(); $self->_xp($node); print $self->get_tab(), "doc: $node->{doc}\n" if ($self->{doc} and exists $node->{doc}); if (exists $node->{attr}) { # oneway print $self->get_tab(), "attribute $node->{attr}\n"; } $self->visitType($node->{type}); foreach (@{$node->{list_param}}) { $_->visit($self); # parameter } if (exists $node->{list_raise}) { foreach (@{$node->{list_raise}}) { # exception print $self->get_tab(), "raise $_\n"; } } if (exists $node->{list_context}) { foreach (@{$node->{list_context}}) { # string literal print $self->get_tab(), "context $_->{value}\n"; } } $self->dec_tab(); } sub visitParameter { my $self = shift; my ($node) = @_; print $self->get_tab(), "parameter $node->{idf}\n"; $self->inc_tab(); $self->_xp($node); # in, out, inout print $self->get_tab(), "attribute $node->{attr}\n"; $self->visitType($node->{type}); $self->dec_tab(); } sub visitVoidType { my $self = shift; my ($node) = @_; print $self->get_tab(), "void\n"; } # # 3.14 Attribute Declaration # sub visitAttributes { my $self = shift; my ($node) = @_; print $self->get_tab(), "attributes\n"; $self->_xp($node); $self->inc_tab(); foreach (@{$node->{list_decl}}) { $self->_get_defn($_)->visit($self); } $self->dec_tab(); } sub visitAttribute { my $self = shift; my ($node) = @_; print $self->get_tab(), "attribute $node->{idf}\n"; $self->inc_tab(); print $self->get_tab(), "doc: $node->{doc}\n" if ($self->{doc} and exists $node->{doc}); if (exists $node->{modifier}) { # readonly print $self->get_tab(), "modifier $node->{modifier}\n"; } if (exists $node->{list_getraise}) { foreach (@{$node->{list_getraise}}) { # exception print $self->get_tab(), "getraise $_\n"; } } if (exists $node->{list_setraise}) { foreach (@{$node->{list_setraise}}) { # exception print $self->get_tab(), "setraise $_\n"; } } $self->visitType($node->{type}); $self->dec_tab(); } # # 3.15 Repository Identity Related Declarations # sub visitTypeId { my $self = shift; my ($node) = @_; print $self->get_tab(), "typeid $node->{idf} '$node->{value}'\n"; } sub visitTypePrefix { my $self = shift; my ($node) = @_; print $self->get_tab(), "typeprefix $node->{idf} '$node->{value}'\n"; } # # 3.16 Event Declaration # sub visitRegularEvent { my $self = shift; my ($node) = @_; print $self->get_tab(), "regular event $node->{idf} '$node->{repos_id}'\n"; $self->inc_tab(); print $self->get_tab(), "doc: $node->{doc}\n" if ($self->{doc} and exists $node->{doc}); if (exists $node->{modifier}) { # custom print $self->get_tab(), "modifier $node->{modifier}\n"; } if (exists $node->{inheritance}) { $node->{inheritance}->visit($self); } foreach (@{$node->{list_decl}}) { $self->_get_defn($_)->visit($self); } $self->dec_tab(); } sub visitAbstractEvent { my $self = shift; my ($node) = @_; print $self->get_tab(), "abstract event $node->{idf} '$node->{repos_id}'\n"; $self->inc_tab(); print $self->get_tab(), "doc: $node->{doc}\n" if ($self->{doc} and exists $node->{doc}); if (exists $node->{inheritance}) { $node->{inheritance}->visit($self); } foreach (@{$node->{list_decl}}) { $self->_get_defn($_)->visit($self); } $self->dec_tab(); } sub visitForwardRegularEvent { my $self = shift; my ($node) = @_; print $self->get_tab(), "forward regular event $node->{idf}\n"; } sub visitForwardAbstractEvent { my $self = shift; my ($node) = @_; print $self->get_tab(), "forward abstract event $node->{idf}\n"; } # # 3.17 Component Declaration # sub visitComponent { my $self = shift; my ($node) = @_; print $self->get_tab(), "component $node->{idf} '$node->{repos_id}'\n"; $self->inc_tab(); print $self->get_tab(), "doc: $node->{doc}\n" if ($self->{doc} and exists $node->{doc}); if (exists $node->{inheritance}) { $node->{inheritance}->visit($self); } if (exists $node->{list_support}) { print $self->get_tab(), "supports \n"; foreach (@{$node->{list_support}}) { $_->visit($self); } } print $self->get_tab(), "exports \n"; foreach (@{$node->{list_decl}}) { $self->_get_defn($_)->visit($self); } $self->dec_tab(); } sub visitForwardComponent { my $self = shift; my ($node) = @_; print $self->get_tab(), "forward component $node->{idf}\n"; } sub visitProvides { my $self = shift; my ($node) = @_; print $self->get_tab(), "provides $node->{idf} $node->{type}\n"; } sub visitUses { my $self = shift; my ($node) = @_; print $self->get_tab(), "uses $node->{idf} $node->{type}\n"; $self->inc_tab(); if (exists $node->{modifier}) { # multiple print $self->get_tab(), "modifier $node->{modifier}\n"; } $self->dec_tab(); } sub visitPublishes { my $self = shift; my ($node) = @_; print $self->get_tab(), "publishes $node->{idf} $node->{type}\n"; } sub visitEmits { my $self = shift; my ($node) = @_; print $self->get_tab(), "emits $node->{idf} $node->{type}\n"; } sub visitConsumes { my $self = shift; my ($node) = @_; print $self->get_tab(), "consumes $node->{idf} $node->{type}\n"; } # # 3.18 Home Declaration # sub visitHome { my $self = shift; my ($node) = @_; print $self->get_tab(), "home $node->{idf} '$node->{repos_id}'\n"; $self->inc_tab(); print $self->get_tab(), "doc: $node->{doc}\n" if ($self->{doc} and exists $node->{doc}); if (exists $node->{inheritance}) { $node->{inheritance}->visit($self); } if (exists $node->{list_support}) { print $self->get_tab(), "supports \n"; foreach (@{$node->{list_support}}) { $_->visit($self); } } $node->{manage}->visit($self); if (exists $node->{primakey}) { print $self->get_tab(), "primarykey $self->{primarykey}\n"; } print $self->get_tab(), "exports \n"; foreach (@{$node->{list_decl}}) { $self->_get_defn($_)->visit($self); } $self->dec_tab(); } sub visitFactory { my $self = shift; my ($node) = @_; print $self->get_tab(), "factory $node->{idf}\n"; $self->inc_tab(); print $self->get_tab(), "doc: $node->{doc}\n" if ($self->{doc} and exists $node->{doc}); foreach (@{$node->{list_param}}) { $_->visit($self); } if (exists $node->{list_raise}) { foreach (@{$node->{list_raise}}) { # exception print $self->get_tab(), "raise $_\n"; } } $self->dec_tab(); } sub visitFinder { my $self = shift; my ($node) = @_; print $self->get_tab(), "finder $node->{idf}\n"; $self->inc_tab(); print $self->get_tab(), "doc: $node->{doc}\n" if ($self->{doc} and exists $node->{doc}); foreach (@{$node->{list_param}}) { $_->visit($self); } if (exists $node->{list_raise}) { foreach (@{$node->{list_raise}}) { # exception print $self->get_tab(), "raise $_\n"; } } $self->dec_tab(); } # # XPIDL # sub _xp { my $self = shift; my ($node) = @_; if (exists $node->{declspec}) { print $self->get_tab(), "declspec : ",$node->{declspec},"\n"; } if (exists $node->{props}) { print $self->get_tab(), "props : "; while (my ($key, $value) = each (%{$node->{props}})) { print $key," "; print "(",$value,") " if (defined $value); } print "\n"; } if (exists $node->{native}) { print $self->get_tab(), "native : ",$node->{native},"\n"; } } sub visitEllipsis { my $self = shift; my ($node) = @_; print $self->get_tab(), "...\n"; } sub visitCodeFragment { my $self = shift; my ($node) = @_; print $self->get_tab(), "code:\n"; print $node->{value},"\n"; } 1;