File Coverage

blib/lib/Inline/Flex.pm
Criterion Covered Total %
statement 3 3 100.0
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 4 4 100.0


line stmt bran cond sub pod time code
1              
2             package Inline::Flex ;
3              
4 1     1   30144 use base 'Inline::C' ;
  1         2  
  1         961  
5             use Config ;
6              
7             use strict;
8             use warnings ;
9             use Carp qw(carp croak confess) ;
10              
11             BEGIN
12             {
13             use Sub::Exporter -setup =>
14             {
15             exports => [ qw() ],
16             groups =>
17             {
18             all => [ qw() ],
19             }
20             };
21            
22             use vars qw ($VERSION);
23             $VERSION = '0.01_01';
24             }
25              
26             #-------------------------------------------------------------------------------
27              
28             use English qw( -no_match_vars ) ;
29              
30             use Readonly ;
31             Readonly my $EMPTY_STRING => q{} ;
32              
33             use File::Slurp ;
34              
35             #-------------------------------------------------------------------------------
36              
37             =head1 NAME
38              
39             Inline::Flex - Inline module to use flex generated lexers
40              
41             =head1 SYNOPSIS
42              
43             use Inline Flex =><<'END_FLEX' ;
44             %option noyywrap
45             %option prefix="Default"
46            
47             %{
48             #undef YY_MAIN
49             #define INTEGER 1
50             #define IDENTIFIER 2
51             #define UNEXPECTED 3
52             %}
53            
54             %{
55             // replacement macros
56             %}
57             exp (([eE][0-9]+)?)
58             fltsuf (([lL]|[fF])?)
59             intsuf (([lL]?[uU]?)|([uU]?[lL]?))
60            
61             %%
62            
63             %{
64             // regexes and action code
65             %}
66             [1-9][0-9]*{intsuf} { return(INTEGER) ; }
67            
68             [a-z_A-Z][a-z_A-Z0-9]+ { return(IDENTIFIER) ; }
69            
70             \ + // ignore
71             [\n\t ]+ ; // ignore
72            
73             [^a-z_A-Z0-9 ]+ { return(UNEXPECTED) ; }
74            
75             %{
76             // comment section
77             %}
78            
79             %%
80             END_FLEX
81            
82             print <<'EOT' ;
83             Type an integer or an identfier and end your input with a '\n'.
84             End the program with ctl+c
85            
86             EOT
87            
88             my %type = ( 1 => 'INTEGER', 2 => 'IDENTIFIER', 3 => 'UNEXPECTED') ;
89            
90             while(0 != (my $lexem = yylex()))
91             {
92             if(exists $type{$lexem})
93             {
94             print "$type{$lexem} [$lexem] .\n" ;
95             }
96             else
97             {
98             print "Can't find type [$lexem] !\n" ;
99             }
100             }
101              
102             =head1 DESCRIPTION
103              
104             Inline::Flex Allows you to define a lexer with the help of B and to use it in perl.
105             Inline::Flex inherits B. All the option available in B are
106             also available in Inline::Flex.
107              
108             As of version 0.02 all C functions declared in the lexer are made available to perl.
109              
110             A B<'yylex'> sub is exported to perl space by this module.
111              
112             =item Limitation
113              
114             You can't write your lexer after the __END__ tag. You must write it inline where you declare your Inline::Flex section.
115             If your lexer is so big that you need to separate it from the rest of your code, considermoving it to another package.
116              
117             =item Inline::Flex aliases:
118              
119             Inline::FLEX
120              
121             Inline::flex
122              
123             =item Options
124              
125             Inline::Flex supports the following options:
126              
127             FLEX_COMMAND_LINE:
128              
129             This is the command line used to generate the lexer. It defaults to 'flex -f -8 -oOUTPUT_FILE INPUT_FILE'
130             where OUTPUT_FILE and INPUT_FILE are automatically replaced by Inline::Flex. This option allows to tweak
131             the generated lexers. Look at the flex man page for more information.
132              
133             =head1 SUBROUTINES/METHODS
134              
135             =cut
136              
137              
138             #-------------------------------------------------------------------------------
139              
140             sub register
141             {
142              
143             =head2 register()
144              
145             Register this module as an Inline language support module . This is called by Inline.
146              
147             I - None
148              
149             I - See L
150              
151             I - None
152              
153             =cut
154              
155             return
156             {
157             language => 'Flex',
158             aliases => ['FLEX', 'flex'],
159             type => 'compiled',
160             suffix => $Config{dlext},
161             } ;
162             }
163              
164             #-------------------------------------------------------------------------------
165              
166             sub validate
167             {
168              
169             =head2 validate($self, %configuration)
170              
171             Sets default command line or uses user defined command line.
172              
173             I
174              
175             =over 2
176              
177             =item $self - inline object.
178              
179             =item %configuration - options
180              
181             =back
182              
183             I - Inline::C configuration validation code
184              
185             See L
186              
187             =cut
188              
189             my ($self, %configuration) = @_ ;
190              
191             # set default command line
192             $self->{ILSM}{FLEX_COMMAND_LINE} = 'flex -f -8 -oOUTPUT_FILE INPUT_FILE' ;
193            
194             while (my ($key, $value) = each %configuration)
195             {
196             if ($key eq 'FLEX_COMMAND_LINE')
197             {
198             $self->{ILSM}{$key} = $value ;
199             delete $configuration{$key} ;
200             }
201             }
202            
203             $self->SUPER::validate(%configuration) ;
204             }
205              
206             #-------------------------------------------------------------------------------
207              
208             sub build
209             {
210              
211             =head2 build($self)
212              
213             Generate the lexer and calls Inline::C to compile it.
214              
215             I
216              
217             =over 2
218              
219             =item $self - Inline object
220              
221             =back
222              
223             I - Inline::C build result
224              
225             I - None
226              
227             =cut
228              
229             my ($self) = @_ ;
230            
231             $self->GenerateLexer() ;
232             $self->SUPER::build() ;
233             }
234              
235             #-------------------------------------------------------------------------------
236              
237             sub GenerateLexer
238             {
239              
240             =head2 GenerateLexer($self)
241              
242             Creates the C code Inline::C will compile by preprocessing the Inline::Flex input code with B.
243              
244             I
245              
246             =over 2
247              
248             =item * $self - the Inline object
249              
250             =back
251              
252             I - Nothing
253              
254             I - B command failures
255              
256             =cut
257              
258             my ($self) = @_ ;
259              
260             $self->mkpath($self->{API}{build_dir}) ;
261              
262             my $flex_file_base = "$self->{API}{build_dir}/$self->{API}{module}" ;
263             my $flex_file = "$flex_file_base.flex" ;
264             my $flex_generated_lexer = "$flex_file_base.flex.c" ;
265              
266             write_file $flex_file, $self->{API}{code} ;
267              
268             $self->{ILSM}{FLEX_COMMAND_LINE} =~ s/OUTPUT_FILE/$flex_generated_lexer/smxg ;
269             $self->{ILSM}{FLEX_COMMAND_LINE} =~ s/INPUT_FILE/$flex_file/smxg ;
270              
271             system($self->{ILSM}{FLEX_COMMAND_LINE}) == 0
272             or croak "Error: '$self->{ILSM}{FLEX_COMMAND_LINE}' failed: $? $! $@" ;
273              
274             $self->{API}{code} = read_file $flex_generated_lexer ;
275              
276             # name yylex so Inline::C can find it
277             $self->{API}{code} =~ s/YY_DECL\s+{/int yylex()\n{/smx ;
278              
279             # delete main so Inline::C does NOT find it
280             $self->{API}{code} =~ s/#if YY_MAIN.+?#endif//smx ;
281              
282             write_file $flex_generated_lexer, $self->{API}{code} ;
283              
284             return ;
285             }
286              
287             #-------------------------------------------------------------------------------
288              
289             1 ;
290              
291             =head1 BUGS AND LIMITATIONS
292              
293             None so far.
294              
295             =head1 AUTHOR
296              
297             Nadim ibn hamouda el Khemir
298             CPAN ID: NH
299             mailto: nadim@cpan.org
300              
301             =head1 LICENSE AND COPYRIGHT
302              
303             This program is free software; you can redistribute
304             it and/or modify it under the same terms as Perl itself.
305              
306             =head1 SUPPORT
307              
308             You can find documentation for this module with the perldoc command.
309              
310             perldoc Inline::Flex
311              
312             You can also look for information at:
313              
314             =over 4
315              
316             =item * AnnoCPAN: Annotated CPAN documentation
317              
318             L
319              
320             =item * RT: CPAN's request tracker
321              
322             Please report any bugs or feature requests to L .
323              
324             We will be notified, and then you'll automatically be notified of progress on
325             your bug as we make changes.
326              
327             =item * Search CPAN
328              
329             L
330              
331             =back
332              
333             =head1 SEE ALSO
334              
335             flex (1).
336              
337             =cut
338