39
|
1 package IMPL::Text::Parser::Player;
|
|
2 use strict;
|
|
3 use warnings;
|
|
4
|
|
5 use base qw(IMPL::Object);
|
|
6 use IMPL::Class::Property;
|
|
7 use IMPL::Class::Property::Direct;
|
|
8
|
|
9 use IMPL::Text::Parser::Chunk;
|
|
10
|
|
11 my %opCodesMap = (
|
|
12 IMPL::Text::Parser::Chunk::OP_REGEXP , &MatchRegexp ,
|
|
13 IMPL::Text::Parser::Chunk::OP_STRING , &MatchString ,
|
|
14 IMPL::Text::Parser::Chunk::OP_REFERENCE , &MatchReference ,
|
|
15 IMPL::Text::Parser::Chunk::OP_CHUNK , &PlayChunk ,
|
|
16 IMPL::Text::Parser::Chunk::OP_SWITCH , &MatchSwitch ,
|
|
17 IMPL::Text::Parser::Chunk::OP_REPEAT , &MatchRepeat
|
|
18 );
|
|
19
|
|
20 BEGIN {
|
|
21 private _direct property _data => prop_all;
|
40
|
22 private _direct property _current => prop_all;
|
39
|
23 public _direct property Punctuation => prop_all;
|
|
24 public _direct property Delimier => prop_all;
|
|
25 }
|
|
26
|
|
27 sub LoadString {
|
|
28 my ($this,$string) = @_;
|
|
29
|
40
|
30 my $rxDelim = /(\s+|[.,;!-+*~$^&|%()`@\\\/])/;
|
|
31
|
|
32 my $line = 0;
|
39
|
33
|
40
|
34 $this->{$_data} = [
|
|
35 map {
|
|
36 $line++;
|
|
37 map {
|
|
38 [$line,$_]
|
|
39 } split $rxDelim, $_
|
|
40 } split /\n/, $string
|
|
41 ]
|
39
|
42 }
|
|
43
|
|
44 sub PlayChunk {
|
|
45 my ($this,$chunk) = @_;
|
|
46
|
|
47 $opCodesMap{shift @$_}->(@$_) foreach @{$chunk->opStream};
|
|
48 }
|
|
49
|
|
50 sub MatchRegexp {
|
|
51 my ($this,$rx) = @_;
|
|
52
|
40
|
53 if ($this->{$_current}{token} =~ $rx) {
|
39
|
54
|
|
55 }
|
|
56 }
|
|
57
|
40
|
58 sub moveNext {
|
|
59 my ($this) = @_;
|
|
60
|
|
61 my $pos = $this->{$_current}{pos};
|
|
62
|
|
63 $pos ++;
|
|
64
|
|
65 if ($pos < @{$this->{$_data}}) {
|
|
66
|
|
67 $this->{$_current} = {
|
|
68 pos => $pos
|
|
69 };
|
|
70
|
|
71 } else {
|
|
72 return undef;
|
|
73 }
|
|
74 }
|
|
75
|
39
|
76 1;
|