File Coverage

blib/lib/Parse/Vipar.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             # -*- cperl -*-
2 1     1   1709 use lib '..';
  1         595  
  1         4  
3              
4             # find . -name '*.pm' | xargs etags -r '/package \(.+\);/\1/' -r '/use [a-zA-Z:]+/'
5              
6             package Parse::Vipar;
7              
8 1     1   99 use strict;
  1         1  
  1         25  
9 1     1   5 use vars qw($VERSION);
  1         4  
  1         50  
10              
11             $VERSION = '0.01';
12              
13 1     1   1280 use Tk;
  0            
  0            
14              
15             # Preload things to keep perly.y from getting them
16             use Tk::Menu;
17             use Tk::Menubutton;
18              
19             use Parse::Vipar::Common;
20             use Parse::YALALR::Common;
21             use Parse::YALALR::Build;
22             use Parse::Vipar::Ministates;
23             use Parse::Vipar::Rules;
24             use Parse::Vipar::Symbols;
25             use Parse::Vipar::State;
26             use Parse::Vipar::Shell;
27             use Parse::Vipar::ParseView;
28             use Parse::Vipar::StateGraph;
29              
30             use Tk::English;
31              
32             # BEGIN {
33             # $SIG{__WARN__} = sub {
34             # use Carp;
35             # confess @_;
36             # }
37             # }
38              
39             sub new {
40             my ($class, %args) = @_;
41             die "Currently need to start with a parser"
42             if ! $args{parser};
43             my $self = bless { window => MainWindow->new(-height => SCREENHEIGHT),
44             data => {},
45             %args }, (ref $class || $class);
46              
47             $self->{step_window} = $self->{window}->Toplevel(-height => SCREENHEIGHT);
48              
49             # View window
50             $self->{state} = Parse::Vipar::State->new($self);
51             $self->{stategraph} = Parse::Vipar::StateGraph->new($self);
52             $self->{ministates} = Parse::Vipar::Ministates->new($self);
53             $self->{rules} = Parse::Vipar::Rules->new($self);
54             $self->{symbols} = Parse::Vipar::Symbols->new($self);
55              
56             push(@{ $self->{view_children} },
57             $self->{state},
58             $self->{stategraph},
59             $self->{ministates},
60             $self->{rules},
61             $self->{symbols});
62              
63             print "Laying out parser view...\n";
64             $self->{view} = $self->layout_parser_view($self->{window});
65              
66             # Step window
67             $self->{shell} = Parse::Vipar::Shell->new($self);
68             $self->{parsetree} = Parse::Vipar::ParseView->new($self);
69              
70             push(@{ $self->{step_children} },
71             $self->{shell},
72             $self->{parsetree});
73              
74             print "Laying out step window...\n";
75             $self->{step} = $self->layout_step_window($self->{step_window});
76              
77             print "Done creating Vipar object\n";
78             return $self;
79             }
80              
81             sub subnew {
82             my ($class, $vipar, %opts) = @_;
83             die "Must give parent object" if ! UNIVERSAL::isa($vipar, __PACKAGE__);
84             return bless { parent => $vipar, %opts }, (ref $class || $class);
85             }
86              
87             sub data { $_[0]->{data} }
88              
89             sub fillin {
90             my $self = shift;
91              
92             foreach (@{ $self->{view_children} }) {
93             print "Filling in $_...\n";
94             $_->fillin();
95             }
96             }
97              
98             sub main { $_[0]->{window} }
99              
100             sub layout_parser_view {
101             my $self = shift;
102             my ($win) = @_;
103            
104             my $view = {};
105              
106             # Set up the overall layout
107             $view->{topline_f} = $win->Frame()
108             ->pack(-side => TOP, -fill => 'x');
109             $view->{main_f} = $win->Frame()
110             ->pack(-side => TOP, -fill => 'both', -expand => 1);
111             $view->{statusline_f} = $win->Frame()
112             ->pack(-side => TOP, -fill => 'x');
113              
114             # Left pane
115             $view->{left_f} = $view->{main_f}->Frame()
116             ->pack(-side => LEFT, -fill => 'both', -expand => 1);
117             $view->{state_f} = $view->{left_f}->Frame()
118             ->pack(-side => TOP, -fill => 'x');
119             $view->{graph_f} = $view->{left_f}->Frame()
120             ->pack(-side => TOP, -fill => 'both', -expand => 1);
121              
122             # Middle pane
123             $view->{ministates_f} = $view->{main_f}->Frame()
124             ->pack(-side => LEFT, -fill => 'y');
125              
126             # Right pane
127             $view->{right_f} = $view->{main_f}->Frame()
128             ->pack(-fill => 'y', -expand => 1);
129             $view->{rules_f} = $view->{right_f}->Frame()
130             ->pack(-side => TOP, -fill => 'both', -expand => 1);
131             $view->{symbols_f} = $view->{right_f}->Frame()
132             ->pack(-side => TOP, -fill => 'both', -expand => 1);
133            
134             $self->layout_menubar($view);
135             $self->layout_statusline($view);
136              
137             for my $child (@{ $self->{view_children} }) {
138             $child->layout_view($view);
139             }
140              
141             return $view;
142             }
143              
144             sub layout_step_window {
145             my $self = shift;
146             my ($win) = @_;
147            
148             my $info = $win->{info} = {};
149              
150             # Set up the overall layout
151             $info->{topline_f} = $win->Frame()
152             ->pack(-side => TOP, -fill => 'x');
153             $info->{parse_f} = $win->Frame()
154             ->pack(-side => LEFT, -fill => 'y');
155             $info->{shell_f} = $win->Frame()
156             ->pack(-side => RIGHT, -fill => 'y');
157              
158             for my $child (@{ $self->{step_children} }) {
159             $child->layout($info, $win);
160             }
161              
162             return $info;
163             }
164              
165             sub layout_menubar {
166             my $self = shift;
167             my ($view) = @_;
168              
169             $view->{topline_m} = $view->{topline_f}->Menubutton(-text => "Pulldown")
170             ->pack(-anchor => 'w', -fill => 'x');
171              
172             return $view;
173             }
174              
175             sub popup_debug_window {
176             my $top = Toplevel->new();
177             $top->Entry()->pack();
178             }
179              
180             sub layout_statusline {
181             my $self = shift;
182             my ($view) = @_;
183              
184             $view->{statusline_l} = $view->{statusline_f}->Label(-text => "Status Line")
185             ->pack();
186              
187             return $view;
188             }
189              
190             sub status {
191             my $self = shift;
192             $self->{view}->{statusline_l}->configure(-text => shift());
193             }
194              
195             ################ CONTROLS ######################
196              
197             ######## GENERAL ###########
198              
199             sub bind_symbol {
200             my ($self, $t, $tag, $symbol) = @_;
201              
202             $t->tagBind($tag, "",
203             sub { $self->view_symbols($symbol); });
204             $t->tagBind($tag, "", sub { });
205             $t->tagBind($tag, "",
206             sub { $self->select_symbols($symbol); });
207             $t->tagBind($tag, "",
208             sub { $self->restrict_symbols($symbol) });
209             }
210              
211             sub bind_object {
212             my ($self, $obj, $t, $tag, $id) = @_;
213              
214             $t->tagBind($tag, "",
215             sub { $obj->view($id); });
216             $t->tagBind($tag, "", sub { });
217             $t->tagBind($tag, "",
218             sub { $obj->select($id); });
219             $t->tagBind($tag, "",
220             sub { $obj->restrict($id) });
221             }
222              
223             ######## SYMBOLS #########
224              
225             sub view_symbols {
226             my $self = shift;
227             my (@symbols) = @_;
228             my $view = $self->{view};
229              
230             $self->{rules}->view_symbols(@symbols);
231             $self->{symbols}->view(@symbols);
232             $self->{ministates}->view_symbols(@symbols);
233             }
234              
235             sub select_symbols {
236             my $self = shift;
237             my (@symbols) = @_;
238             my $view = $self->{view};
239             my $n = @symbols;
240             $self->status("Selecting $P{'symbol', $n} "
241             .join(" ", $self->{parser}->dump_sym(@symbols)));
242              
243             $self->{rules}->select_symbols(@symbols);
244             $self->{symbols}->select(@symbols);
245             }
246              
247             sub restrict_symbols {
248             my $self = shift;
249             my (@symbols) = @_;
250             my $view = $self->{view};
251             my $n = @symbols;
252             $self->status("Restricting view to $P{'symbol', $n} "
253             .join(" ", $self->{parser}->dump_sym(@symbols)));
254              
255             $self->{rules}->restrict_symbols(@symbols);
256             $self->{symbols}->restrict(@symbols);
257             }
258              
259             ######## RULES #########
260              
261             sub view_rule {
262             my $self = shift;
263             my ($rule) = @_;
264             my $view = $self->{view};
265             $self->status("Viewing rule #$rule");
266              
267             $self->{ministates}->view_rule($rule);
268             $self->{rules}->view($rule);
269             }
270              
271             sub select_rule {
272             my $self = shift;
273             my ($rule) = @_;
274             my $view = $self->{view};
275             $self->status("Selecting rule #$rule");
276              
277             $self->{ministates}->select_rule($rule);
278             $self->{rules}->select($rule);
279             }
280              
281             ######## ITEMS #########
282              
283             sub select_item {
284             my $self = shift;
285             my ($item) = @_;
286             my $view = $self->{view};
287             $self->status("Selecting item ".$self->{parser}->dump_item($item));
288             }
289              
290             ######## STATES #########
291              
292             sub view_state {
293             my $self = shift;
294             my ($state) = @_;
295             my $view = $self->{view};
296              
297             $self->{ministates}->view($state);
298             }
299              
300             sub select_state {
301             my $self = shift;
302             my ($state) = @_;
303             my $view = $self->{view};
304             $self->status("Selecting state #$state");
305             $self->{ministates}->select($state);
306             $self->{state}->select($state);
307             $self->{stategraph}->select_state($state);
308             }
309              
310             ###############################################
311              
312             sub unrestrict {
313             my ($self) = @_;
314             $self->{rules}->unrestrict();
315             $self->{symbols}->restrict();
316             $self->{state}->unrestrict();
317             }
318              
319             ############ ACTIONS (in Shell window) ###############
320              
321             sub why_lookahead {
322             my ($self, $state, $item, $token) = @_;
323             my $tokenname = $self->{parser}->dump_sym($token);
324             $self->status("Why lookahead $tokenname in state $state: see shell window");
325             $self->{shell}->run("why lookahead token $tokenname "
326             ."in state $state item $item");
327             }
328              
329             1;
330              
331             __END__