14 my $debug_tree = 0; # show tree while it is built
19 return ' ' x
$tab_depth;
23 printf "# %04d: %s\n", $line_number, $line;
24 print "# *** $_[0]\n";
30 return shift @tokens if @tokens;
32 unless ( $line = <> ) {
33 return shift @post_tokens if @post_tokens;
39 if ( $line =~ /^#/ || $line =~ /^$/ ) {
42 # printf "# %04d: %s\n", $line_number, $line;
43 @tokens = split( /\b/, $line );
53 unshift @tokens, $word;
59 my @param = @_; # not used
61 print tab
(), "sentence(\n" if $debug_tree;
68 #print "# Start sentence [@param]\n";
74 if ( $word =~ /^(.*?\S)(\s.*?)$/ ) {
75 # split on inner space left from the simple tokenizer, like in ' = {'
80 if ( $word =~ /^\s*\;/ ) {
81 #print "# End sentence [@param] [$word]\n";
83 unshift @tokens, $word if $word ne '';
86 print tab
(), ")sentence,\n" if $debug_tree;
91 if ( $word =~ /^\s*\(/ ) {
93 unshift @tokens, $word;
94 push @ret, [ parenthesis
( 'bare paren' ) ];
95 #print "# continue sentence: \n";
99 if ( $word =~ /^\s*\{/ ) {
100 # print "# start block\n";
101 unshift @tokens, $word;
102 push @ret, [ block
( 'bare block' ) ];
103 #print "# continue sentence: \n";
107 if ( $word =~ /^\s*\)/ ) {
108 # print "# end paren\n";
109 unshift @tokens, $word;
111 print tab
(), ")sentence,\n" if $debug_tree;
116 if ( $word =~ /^\s*\}/ ) {
117 # print "# end block\n";
118 unshift @tokens, $word;
120 print tab
(), ")sentence,\n" if $debug_tree;
126 print tab
(), "'$word'\n" if $debug_tree;
133 my @param = @_; # not used
135 print tab
(), "paren(\n" if $debug_tree;
142 #print "# Start paren $tab_depth [@param] [$word]\n";
143 $word =~ s/^\s*\(// or error
"not a <(> [$word]\n";
144 unshift @tokens, $word if $word ne '';
147 # print " [ $word ] ";
149 if ( $word =~ /^\s*\)/ ) {
150 #print "# End paren $tab_depth [@param] [$word]\n";
152 unshift @tokens, $word if $word ne '';
155 print tab
(), ")paren,\n" if $debug_tree;
160 if ( $word =~ /^\s*\(/ ) {
162 unshift @tokens, $word;
163 push @ret, [ parenthesis
( 'bare paren' ) ];
166 unshift @tokens, $word;
167 push @ret, [ sentence
( $word ) ];
173 my @param = @_; # not used
177 #print "# Start block $tab_depth [@param] [$word]\n";
178 print tab
(), "block{\n" if $debug_tree;
183 $word =~ s/^\s*{// or error
"not a <{> [$word]\n";
184 unshift @tokens, $word if $word ne '';
187 # print " [ $word ] ";
188 if ( $word =~ /^(class|method|submethod|sub|multi|macro)$/ ) {
189 print tab
(), "define(\n" if $debug_tree;
195 if ( $word eq 'multi' ) {
198 if ( $word2 eq 'method' || $word2 eq 'sub' ) {
199 $word .= ' ' . $word2;
202 push @tokens, $word2;
205 $block{thing
} = $word;
207 print tab
(), "thing = $word,\n" if $debug_tree;
212 if ($word eq '*') { $namespace = $word }
213 else { unshift @tokens, $word };
214 print tab
(), "namespace_modifier = $namespace,\n" if $debug_tree;
215 $block{namespace_modifier
} = $namespace;
219 if ($word =~ /(\(|\{)/) { unshift @tokens, $word }
220 else { $name = $word };
221 print tab
(), "name = $name,\n" if $debug_tree;
222 $block{name
} = $name;
225 unshift @tokens, $word;
226 if ( $word =~ /^\s*\(/ ) {
227 print tab
(), "param = \n" if $debug_tree;
229 $block{param
} = [ parenthesis
( 'parameter paren' ) ];
233 print tab
(), "block = \n" if $debug_tree;
235 $block{block
} = [ block
( $1, $name ) ];
242 print tab
(), "}define,\n" if $debug_tree;
246 if ( $word =~ /^\s*}/ ) {
247 #print "# End block $tab_depth [@param] [$word]\n";
249 unshift @tokens, $word if $word ne '';
252 print tab
(), "}block,\n" if $debug_tree;
256 if ( $word =~ /^\s*{/ ) {
257 # print "# bare block\n";
258 unshift @tokens, $word;
259 push @ret, [ block
( 'bare block' ) ];
263 if ( $word =~ /^\s+$/ ) {
268 unshift @tokens, $word;
269 push @ret, [ sentence
( $word ) ];
278 @post_tokens = ( '}' );
281 my @tree = block
( 'main block' );
284 $Data::Dumper
::Indent
= 1;
285 print Dumper
( \
@tree );