File Coverage

blib/lib/ODO/Parser/N3.pm
Criterion Covered Total %
statement 42 42 100.0
branch 6 8 75.0
condition n/a
subroutine 11 11 100.0
pod 3 3 100.0
total 62 64 96.8


line stmt bran cond sub pod time code
1             #
2             # Copyright (c) 2007 IBM Corporation.
3             #
4             # All rights reserved. This program and the accompanying materials
5             # are made available under the terms of the Eclipse Public License v1.0
6             # which accompanies this distribution, and is available at
7             # http://www.eclipse.org/legal/epl-v10.html
8             #
9             # File: $Source: /var/lib/cvs/ODO/lib/ODO/Parser/N3.pm,v $
10             # Created by: Stephen Evanchik( evanchik@us.ibm.com )
11             # Created on: 01/05/2007
12             # Revision: $Id: N3.pm,v 1.2 2009-11-25 17:54:26 ubuntu Exp $
13             #
14             # Contributors:
15             # IBM Corporation - initial API and implementation
16             #
17             package ODO::Parser::N3;
18              
19 1     1   31025 use strict;
  1         3  
  1         35  
20 1     1   6 use warnings;
  1         2  
  1         27  
21              
22 1     1   525 use ODO::Exception;
  1         3  
  1         55  
23              
24 1     1   564 use ODO::Node;
  1         2  
  1         48  
25 1     1   487 use ODO::Statement;
  1         5  
  1         65  
26 1     1   8 use vars qw /$VERSION/;
  1         3  
  1         85  
27             $VERSION = sprintf "%d.%02d", q$Revision: 1.2 $ =~ /: (\d+)\.(\d+)/;
28 1     1   1880 use Parse::RecDescent;
  1         48651  
  1         8  
29              
30 1     1   56 use base qw/ODO::Parser/;
  1         1  
  1         821  
31              
32             __PACKAGE__->mk_accessors(qw/base_uri statements/);
33              
34             our $PARSER = undef;
35              
36             # $::RD_ERRORS =1; # unless undefined, report fatal errors
37             # $::RD_WARN =1; # unless undefined, also report non-fatal problems
38             # $::RD_HINT =1; # if defined, also suggestion remedies
39             # $::RD_TRACE =1; # if defined, also trace parsers' behaviour
40              
41             our $GRAMMAR = q(
42              
43            
44              
45             {
46             use Data::Dumper;
47             use ODO::Node;
48             use ODO::Statement;
49            
50             my $prefix;
51             my $frag;
52              
53             my $subject;
54             my $predicate;
55              
56             my $predicate_list;
57             my $object_list;
58             }
59              
60             start_parse:{ $::Prefixes = {}; $::Statements = [] } document { $return = { prefixes=> $::Prefixes, 'statements'=> $::Statements }; }
61              
62             barename: /([a-zA-Z_][a-zA-Z0-9_]*)/ { $return = $item{'__PATTERN1__'}; }
63              
64             declaration: '@prefix' prefix explicituri { $::Prefixes->{ $item[2] } = $item[3]; }
65              
66             document: statements_optional
67              
68             dtlang: '@' langcode { $return = [$item[2], undef]; }
69             | '^^' symbol { $return = [undef, $item[2]]; }
70             | { $return = []; } # void
71              
72             explicituri: /<([^>]*)>/ { $return = $item{'__PATTERN1__'}; ($return) = $return =~ m/<(.*)>/; }
73              
74             existential: explicituri { $return = $item[1]; }
75              
76             formulacontent: statementlist
77              
78             langcode: /([a-z]+(-[a-z0-9]+)*)/ { $return = $item{'__PATTERN1__'}; }
79              
80             literal: string dtlang { $return = ODO::Node::Literal->new($item[1], @{ $item[2] }); }
81              
82             node: literal { $return = $item[1]; }
83             | numericliteral { $return = $item[1]; }
84             | symbol { $return = $item[1]; }
85             | variable { $return = $item[1]; }
86             | '(' pathlist ')' { $return = $item[2]; }
87             | '@this'
88             | '[' propertylist ']' { $return = $item[2]; }
89             | '{' formulacontent '}' { $return = $item[2]; }
90              
91             numericliteral: /([-+]?[0-9]+(\.[0-9]+)?(e[-+]?[0-9]+)?)/ { $return = $item{'__PATTERN1__'}; }
92              
93             object: path { $return = $item[1]; }
94              
95             objecttail: ',' object objecttail { $return = [ $item[2], @{ $item[3] } ]; }
96             | { $return = []; } # void
97              
98             path: node pathtail { $return = [ $item[1], @{ $item[2] } ]; }
99              
100             pathlist: path pathlist
101             | # void
102              
103             pathtail: '!' path
104             | '^' path
105             | { $return = []; } # void
106              
107             prefix: /([a-zA-Z_][a-zA-Z0-9_]*)?:/ { $return = $item{'__PATTERN1__'}; chomp($return); chop($return); }
108              
109             propertylist: verb object objecttail propertylisttail
110             {
111             $return = [
112             [ $item[1], ($item[2], @{ $item[3] }) ],
113             @{ $item[4] }
114             ];
115             }
116             | { $return = []; } # void
117              
118             propertylisttail: ';' propertylist { $return = $item[2]; }
119             | { $return = []; } # void
120              
121             qname: /(([a-zA-Z_][a-zA-Z0-9_]*)?:)?[a-zA-Z_][a-zA-Z0-9_]*/
122             {
123             ($prefix, $frag) = $item{'__PATTERN1__'} =~ m/^([a-zA-Z_][a-zA-Z0-9_]*):([a-zA-Z_][a-zA-Z0-9_]*)$/;
124             $return = { prefix=> $prefix, frag=> $frag }
125             }
126              
127             simpleStatement: subject propertylist
128             {
129             $subject = $item[1]->[0];
130            
131             # Format is predicate = arr[0], object_list = arr[1...N]
132             foreach my $property_group (@{ $item[2] }) {
133            
134             $predicate = $property_group->[0]->[0];
135             shift @{ $property_group };
136            
137             foreach my $object (@{ $property_group }) {
138             push @{ $::Statements }, ODO::Statement->new($subject, $predicate, $object->[0]);
139             }
140             }
141             }
142              
143             statement: declaration
144             | simpleStatement
145             | existential
146             | universal
147              
148             statementlist: statement statementtail
149             | # void
150              
151             statements_optional: statement '.' statements_optional
152             | # void
153              
154             statementtail: '.' statementlist
155             | # void
156              
157             string: /("""[^"\\\\]*(?:(?:\\.|"(?!""))[^"\\\\]*)*""")|("[^"\\\\]*(?:\\.[^"\\\\]*)*")/ { $return = $item{'__PATTERN1__'}; $return =~ s/^"//g; chomp($return); chop($return); 1; }
158              
159             subject: path { $return = $item[1]; }
160              
161             symbol: explicituri { $return = ODO::Node::Resource->new($item[1]); }
162             | qname { $return = ODO::Node::Resource->new($::Prefixes->{ $item[1]->{'prefix'} } . $item[1]->{'frag'}); }
163              
164             universal: variable { $return = $item[1]; }
165              
166             variable: /(\?[a-zA-Z_][a-zA-Z0-9_]*)/ { $return = $item{'__PATTERN1__'}; }
167              
168             verb: path { $return = $item[1] }
169             | '@'
170             | '@has' path
171             | '@is' path '@of'
172             | '='
173             | '<='
174             | '>='
175            
176             );
177              
178             =head1 NAME
179              
180             ODO::Parser::N3 - Parser for statements serialized in Notation3 format.
181              
182             =head1 SYNOPSIS
183              
184             use ODO::Parser::N3;
185            
186             my $statements = ODO::Parser::N3->parse_file('some/path/to/data.n3');
187            
188             my $rdf = ' ... n3 format here ... ';
189             my $other_statements = ODO::Parser::N3->parse(\$rdf);
190              
191             =head1 DESCRIPTION
192              
193             =head1 CONSTRUCTOR
194              
195             =head1 METHODS
196              
197             =over
198              
199             =item parse( $rdf, [ base_uri=> $base_uri ] )
200              
201             =cut
202              
203             sub parse {
204 2     2 1 139 my ( $self, $rdf, %parameters ) = @_;
205            
206 2 100       32 $self = ODO::Parser::N3->new(%parameters)
207             unless(ref $self);
208              
209 2         35 my $parse_results = $PARSER->start_parse($rdf);
210 2         9813 return $parse_results->{'statements'};
211             }
212              
213              
214             =item parse_file( $filename, [ base_uri=> $base_uri ] )
215              
216             =cut
217              
218             sub parse_file {
219 1     1 1 1220 my ($self, $filename, %parameters) = @_;
220            
221 1 50       16 $self = ODO::Parser::N3->new(%parameters)
222             unless(ref $self);
223            
224 1 50       57 throw ODO::Exception::File::Missing(error=> "Could not locate file: $filename")
225             unless(-e $filename);
226              
227 1         7 local $/ = undef;
228 1         57 open(RDF_FILE, $filename);
229 1         47 my $rdf = ;
230 1         42 close(RDF_FILE);
231            
232 1         8 return $self->parse($rdf, %parameters);
233             }
234              
235              
236              
237             sub init {
238 2     2 1 71 my ($self, $config) = @_;
239 2         12 $self->base_uri( $config->{'base_uri'} );
240 2         37 $self->statements( [] );
241              
242 2 100       18 unless(UNIVERSAL::isa($PARSER, 'Parse::RecDescent')) {
243 1         9 $PARSER = Parse::RecDescent->new($GRAMMAR);
244             }
245              
246 2         281897 return $self;
247             }
248              
249              
250             =back
251              
252             =head1 COPYRIGHT
253              
254             Copyright (c) 2007 IBM Corporation.
255              
256             All rights reserved. This program and the accompanying materials
257             are made available under the terms of the Eclipse Public License v1.0
258             which accompanies this distribution, and is available at
259             http://www.eclipse.org/legal/epl-v10.html
260              
261             =cut
262              
263             1;
264              
265             __END__