File Coverage

blib/lib/Sub/Multi/Tiny/SigParse.pm
Criterion Covered Total %
statement 9 9 100.0
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 12 12 100.0


line stmt bran cond sub pod time code
1             ####################################################################
2             #
3             # This file was generated using Parse::Yapp version 1.21.
4             #
5             # Don't edit this file, use source file instead.
6             #
7             # ANY CHANGE MADE HERE WILL BE LOST !
8             #
9             ####################################################################
10             package Sub::Multi::Tiny::SigParse;
11 14     14   16619 use vars qw ( @ISA );
  14         24  
  14         590  
12 14     14   62 use strict;
  14         26  
  14         406  
13              
14             @ISA= qw ( Parse::Yapp::Driver );
15 14     14   5986 use Parse::Yapp::Driver;
  14         26062  
  14         3740  
16              
17             #line 6 "/root/.cpan/build/Sub-Multi-Tiny-0.000012-0/support/SigParse.yp"
18              
19              
20             # Imports {{{1
21              
22             use 5.006;
23             use strict;
24             use warnings;
25              
26             use Text::Balanced qw(extract_codeblock);
27              
28             # Types of constraints we've seen - bit offsets
29             use enum
30             # Flags set by the parser
31             'SEEN_WHERE', # `where` clause
32             'SEEN_TYPE', # Type constraint
33             'SEEN_POS', # Positional argument
34             'SEEN_NAMED', # Named argument
35             # future: SEEN_LITERAL for signatures holding literal values
36             # instead of name matches.
37              
38             # Flags set by later processing
39             'HAS_MULTIPLE_ARITIES', # Set if there are at least two
40             # different positional arities in a
41             # set of impls
42             ;
43              
44             # Set bits in YYData->{SEEN}
45             sub _seen {
46             vec($_[0]->YYData->{SEEN}, $_[$_], 1) = 1 foreach 1..$#_;
47             }
48              
49             # }}}1
50             # Documentation {{{1
51              
52             =head1 NAME
53              
54             Sub::Multi::Tiny::SigParse - Parse::Yapp input to parse signatures in Sub::Multi::Tiny
55              
56             =head1 SYNOPSIS
57              
58             Generate the .pm file:
59              
60             yapp -m Sub::Multi::Tiny::SigParse -o lib/Sub/Multi/Tiny/SigParse.pm support/SigParse.yp
61              
62             And then:
63              
64             use Sub::Multi::Tiny::SigParse;
65             my $ast = Sub::Multi::Tiny::SigParse::Parse($signature);
66              
67             =head1 FUNCTIONS
68              
69             =cut
70              
71             # }}}1
72              
73              
74              
75             sub new {
76             my($class)=shift;
77             ref($class)
78             and $class=ref($class);
79              
80             my($self)=$class->SUPER::new( yyversion => '1.21',
81             yystates =>
82             [
83             {#State 0
84             ACTIONS => {
85             'PARAM' => 3,
86             'TYPE' => 4
87             },
88             DEFAULT => -1,
89             GOTOS => {
90             'parameter' => 1,
91             'signature' => 2
92             }
93             },
94             {#State 1
95             ACTIONS => {
96             'SEPAR' => 5
97             },
98             DEFAULT => -2
99             },
100             {#State 2
101             ACTIONS => {
102             '' => 6
103             }
104             },
105             {#State 3
106             ACTIONS => {
107             'WHERE' => 7
108             },
109             DEFAULT => -5
110             },
111             {#State 4
112             ACTIONS => {
113             'PARAM' => 8
114             }
115             },
116             {#State 5
117             ACTIONS => {
118             'TYPE' => 4,
119             'PARAM' => 3
120             },
121             DEFAULT => -1,
122             GOTOS => {
123             'signature' => 9,
124             'parameter' => 1
125             }
126             },
127             {#State 6
128             DEFAULT => 0
129             },
130             {#State 7
131             DEFAULT => -6
132             },
133             {#State 8
134             ACTIONS => {
135             'WHERE' => 10
136             },
137             DEFAULT => -7
138             },
139             {#State 9
140             ACTIONS => {
141             'SEPAR' => 11
142             },
143             DEFAULT => -3
144             },
145             {#State 10
146             DEFAULT => -8
147             },
148             {#State 11
149             DEFAULT => -4
150             }
151             ],
152             yyrules =>
153             [
154             [#Rule 0
155             '$start', 2, undef
156             ],
157             [#Rule 1
158             'signature', 0,
159             sub
160             #line 86 "/root/.cpan/build/Sub-Multi-Tiny-0.000012-0/support/SigParse.yp"
161             { [] }
162             ],
163             [#Rule 2
164             'signature', 1,
165             sub
166             #line 87 "/root/.cpan/build/Sub-Multi-Tiny-0.000012-0/support/SigParse.yp"
167             { [ $_[1] ] }
168             ],
169             [#Rule 3
170             'signature', 3,
171             sub
172             #line 88 "/root/.cpan/build/Sub-Multi-Tiny-0.000012-0/support/SigParse.yp"
173             { [ $_[1], @{$_[3]} ] }
174             ],
175             [#Rule 4
176             'signature', 4,
177             sub
178             #line 90 "/root/.cpan/build/Sub-Multi-Tiny-0.000012-0/support/SigParse.yp"
179             { [ $_[1], @{$_[3]} ] }
180             ],
181             [#Rule 5
182             'parameter', 1,
183             sub
184             #line 95 "/root/.cpan/build/Sub-Multi-Tiny-0.000012-0/support/SigParse.yp"
185             {
186             _seen $_[0], $_[1]->{named} ? SEEN_NAMED : SEEN_POS;
187             return $_[1];
188             }
189             ],
190             [#Rule 6
191             'parameter', 2,
192             sub
193             #line 101 "/root/.cpan/build/Sub-Multi-Tiny-0.000012-0/support/SigParse.yp"
194             {
195             _seen $_[0], $_[1]->{named} ? SEEN_NAMED : SEEN_POS;
196             _seen $_[0], SEEN_WHERE;
197             return +{%{$_[1]}, where=>$_[2]};
198             }
199             ],
200             [#Rule 7
201             'parameter', 2,
202             sub
203             #line 108 "/root/.cpan/build/Sub-Multi-Tiny-0.000012-0/support/SigParse.yp"
204             {
205             _seen $_[0], $_[2]->{named} ? SEEN_NAMED : SEEN_POS;
206             _seen $_[0], SEEN_TYPE;
207             return +{%{$_[2]}, type => $_[1]};
208             }
209             ],
210             [#Rule 8
211             'parameter', 3,
212             sub
213             #line 115 "/root/.cpan/build/Sub-Multi-Tiny-0.000012-0/support/SigParse.yp"
214             {
215             _seen $_[0], $_[2]->{named} ? SEEN_NAMED : SEEN_POS;
216             _seen $_[0], SEEN_TYPE, SEEN_WHERE;
217             return +{%{$_[2]}, where=>$_[3], type => $_[1]}
218             }
219             ]
220             ],
221             @_);
222             bless($self,$class);
223             }
224              
225             #line 122 "/root/.cpan/build/Sub-Multi-Tiny-0.000012-0/support/SigParse.yp"
226              
227              
228             #############################################################################
229             # Footer
230              
231             # Tokenizer and error-reporting routine for Parse::Yapp {{{1
232              
233             # The lexer
234             sub _next_token {
235             my $parser = shift;
236             my $text = $parser->YYData->{TEXT};
237              
238             $$text =~ m/\G\s+/gc; # Skip H and V whitespace
239             $parser->YYData->{CURR_TOK_POS} = pos($$text);
240              
241             return ('', undef) unless (pos($$text)||0) < length($$text); # EOF
242              
243             $$text =~ m/\G,/gc and return (SEPAR => 0); # 0 is a dummy value
244              
245             if($$text =~ m/\G([:]?)([\$\@\%\&\*]\w+)\b([?!]?)/gc) {
246             my $retval = {};
247             $retval->{name} = $2;
248             $retval->{named} = !!$1;
249             $retval->{reqd} = (
250             ($retval->{named} && $3 eq '!') || # Named: optional unless !
251             (!$retval->{named} && $3 ne '?') # Positional: reqd unless ?
252             );
253             return (PARAM => $retval);
254             }
255              
256             if($$text =~ m/\Gwhere\s*\{/gci) {
257             pos($$text) -= 1; # Get the lbrace back
258             my ($block) = extract_codeblock($$text); # Updates pos()
259             return (WHERE => $block) if defined $block;
260             die "Saw a 'where' without a valid block after it";
261             }
262              
263             # Permit braced expressions for complex type checks
264             if($$text =~ m/\G\{/gc) {
265             pos($$text) -= 1; # Get the lbrace back
266             my ($block) = extract_codeblock($$text); # Updates pos()
267             return (TYPE => $block) if defined $block;
268             die "Saw an opening brace without a valid block after it";
269             }
270              
271             # If the next thing is a backslash, die --- prohibit backslash to start
272             # a typecheck as a guard against '' vs "" confusion. If you want a
273             # backslash, use the {} form.
274             if($$text =~ m{\G\\}gc) {
275             die "Saw a backslash where I don't know what to do with it! ('' vs \"\" confusion?)";
276             }
277              
278             # Otherwise, assume a single word is a typecheck
279             $$text =~ m/\G(\S+)/gc and return (TYPE => $1);
280              
281             die "This should never happen! Unlexable text was: " .
282             substr($$text, pos($$text));
283             } #_next_token()
284              
285             # Report an error
286             sub _report_error {
287             my $parser = shift;
288             my $startpos = $parser->YYData->{CURR_TOK_POS};
289             my $endpos = pos(${ $parser->YYData->{TEXT} });
290             my $got = $parser->YYCurtok || '<end of input>';
291             my $val='';
292             $val = ' (' . $parser->YYCurval . ')' if $parser->YYCurval;
293              
294             my $errmsg = 'Syntax error: could not understand ' . $got . $val .
295             " at positions $startpos..$endpos";
296             if(ref($parser->YYExpect) eq 'ARRAY') {
297             $errmsg .= ".\nExpected one of: " . join(',', @{$parser->YYExpect});
298             } else {
299             $errmsg .= ':'
300             }
301              
302             # Print the text and flag the error
303             my $copy = ${ $parser->YYData->{TEXT} };
304             $copy =~ s/\s/ /g; # Normalize spaces so pos values line up
305             $errmsg .= "\n$copy";
306             $errmsg .= "\n" . (' ' x $startpos) . ('^' x ($endpos-$startpos));
307              
308             $errmsg .= "\n"; # No stack trace
309             die $errmsg;
310             } #_report_error()
311              
312             # }}}1
313             # Top-level parse function {{{1
314              
315             =head2 Parse
316              
317             Parse arguments. Usage:
318              
319             my $ast = Sub::Multi::Tiny::SigParse::Parse($signature);
320              
321             =cut
322              
323             sub Parse {
324             my $text = shift;
325             unless(defined $text) {
326             require Carp;
327             Carp::croak 'Parse: Need a signature to parse';
328             }
329              
330             my $parser = __PACKAGE__->new;
331             my $hrData = $parser->YYData;
332              
333             # Data we use while parsing.
334              
335             # TEXT: The input text. Store it as a reference so pos() will
336             # be preserved across calls to _next_token.
337             $hrData->{TEXT} = \"$text";
338              
339             # CURR_TOK_POS: the pos() value where the current token started.
340             # Used in reporting errors.
341             $hrData->{CURR_TOK_POS} = -1;
342              
343             # SEEN: bit flags for which types of things we've seen
344             $hrData->{SEEN} = '';
345              
346             my $lrParms = $parser->YYParse(yylex => \&_next_token,
347             yyerror => \&_report_error,
348             (@_ ? (yydebug => $_[0]) : ()),
349             );
350             my %retval = (seen => $hrData->{SEEN}, parms => $lrParms);
351              
352             return \%retval;
353             } #Parse()
354              
355             # }}}1
356             # Rest of the docs {{{1
357              
358             =head1 AUTHOR
359              
360             Chris White E<lt>cxw@cpan.orgE<gt>
361              
362             =head1 LICENSE
363              
364             Copyright (C) 2019 Chris White E<lt>cxw@cpan.orgE<gt>
365              
366             This library is free software; you can redistribute it and/or modify
367             it under the same terms as Perl itself.
368              
369             =cut
370              
371             # }}}1
372              
373             # vi: set fdm=marker: #
374              
375             1;