#!/usr/bin/perl package Sexpr; use strict; use warnings; use SexprNode; use Carp; sub new { my $class = shift; my $sexprt = {_root => undef}; bless $sexprt, $class; return $sexprt; } sub set_root { my $sexprt = shift; my $sexprn = shift; unless (ref $sexprn eq 'SexprNode'){ croak "method set_root() requires a SexprNode ref"; } $sexprt->{_root} = $sexprn; } sub DESTROY { my $sexprt = shift; $sexprt->{_root}->DESTROY; } sub read_wsjsynt { my $sexprt = shift; my $fileh = shift; my @sexprnstack = (); my $inputl = <$fileh>; chomp($inputl); $inputl =~ s/\s+/ /g; while ($inputl){ $inputl =~ s/^\s+//; $inputl =~ s/\s+$//; if ($inputl =~ /^\(([^ \(\)]+) ([^ \(\)]+)\)/){ # terminal node my $label = $1 . " " . $2; my $sexprn = SexprNode->new($label); if (my $super = pop @sexprnstack){ $super->attachsexprn($sexprn); push @sexprnstack, $super; }else{ croak "method read_wsjsynt(): root terminal in $inputl"; } $inputl = $'; # $' i.e. $POSTMATCH }elsif ($inputl =~ /^\(([^ \(\)]+)/){ # nonterminal node my $label = $1; my $sexprn = SexprNode->new($label); push @sexprnstack, $sexprn; $inputl = $'; # $' i.e. $POSTMATCH }elsif ($inputl =~ /^\)/){ my $sexprn = pop @sexprnstack; if (@sexprnstack){ $sexprnstack[$#sexprnstack]->attachsexprn($sexprn); }else{ $sexprt->{_root} = $sexprn; } $inputl = $'; # $' i.e. $POSTMATCH }else{ croak "method read_wsjsynt(): unknown token in $inputl"; } } } sub dfs { my $sexprt = shift; return $sexprt->{_root}->dfs; } sub prettystring { my $sexprt = shift; return $sexprt->{_root}->prettystring(' '); } 1;