#!/usr/bin/perl
####################################################################
#
#    This file was generated using Parse::Yapp version 1.05.
#
#        Don't edit this file, use source file instead.
#
#             ANY CHANGE MADE HERE WILL BE LOST !
#
####################################################################
package W3C::Rdf::_N3Parser;
use vars qw ( @ISA );
use strict;

@ISA= qw ( Parse::Yapp::Driver );
# use Parse::Yapp::Driver; @@ replaced by W3C::Util::YappDriver

#line 9 "N3Parser.yp"

    #BEGIN {unshift@INC,('../..');}
    use W3C::Util::YappDriver;
    @ISA= qw (W3C::Util::YappDriver);

    use W3C::Rdf::AlgaeCompileTree;


sub new {
        my($class)=shift;
        ref($class)
    and $class=ref($class);

    my($self)=$class->SUPER::new( yyversion => '1.05',
                                  yystates =>
[
	{#State 0
		ACTIONS => {
			'' => -1
		},
		DEFAULT => -2,
		GOTOS => {
			'@1-0' => 1,
			'document' => 2
		}
	},
	{#State 1
		ACTIONS => {
			'URI' => 12,
			'NAME' => 11,
			"bind" => 3,
			"{" => 14,
			"this" => 4,
			'NODEID' => 17,
			"(" => 18,
			"[" => 8,
			"\@prefix" => 9
		},
		DEFAULT => -47,
		GOTOS => {
			'subject' => 13,
			'node' => 5,
			'nprefix' => 16,
			'uri_ref2' => 15,
			'statement' => 6,
			'statementlist' => 7,
			'qname' => 19,
			'directive' => 20,
			'anonnode' => 10
		}
	},
	{#State 2
		ACTIONS => {
			'' => 21
		}
	},
	{#State 3
		ACTIONS => {
			'NAME' => 11
		},
		DEFAULT => -47,
		GOTOS => {
			'nprefix' => 22
		}
	},
	{#State 4
		DEFAULT => -22
	},
	{#State 5
		DEFAULT => -11
	},
	{#State 6
		ACTIONS => {
			"." => 23
		},
		DEFAULT => -7
	},
	{#State 7
		ACTIONS => {
			":" => -47,
			'URI' => 12,
			'NAME' => 11,
			"bind" => 3,
			"{" => 14,
			"this" => 4,
			'NODEID' => 17,
			"(" => 18,
			"[" => 8,
			"\@prefix" => 9
		},
		DEFAULT => -3,
		GOTOS => {
			'statement' => 24,
			'subject' => 13,
			'qname' => 19,
			'directive' => 20,
			'anonnode' => 10,
			'node' => 5,
			'uri_ref2' => 15,
			'nprefix' => 16
		}
	},
	{#State 8
		ACTIONS => {
			"this" => 4,
			"a" => 27,
			">-" => 29,
			"[" => 8,
			"]" => 30,
			'NAME' => 11,
			'URI' => 12,
			"has" => 31,
			"{" => 14,
			"is" => 32,
			"=" => 33,
			'NODEID' => 17,
			"(" => 18,
			"<-" => 35
		},
		DEFAULT => -47,
		GOTOS => {
			'prop' => 34,
			'verb' => 28,
			'qname' => 19,
			'anonnode' => 10,
			'node' => 25,
			'uri_ref2' => 15,
			'nprefix' => 16,
			'property_list' => 26
		}
	},
	{#State 9
		ACTIONS => {
			'NAME' => 11
		},
		DEFAULT => -47,
		GOTOS => {
			'nprefix' => 36
		}
	},
	{#State 10
		DEFAULT => -21
	},
	{#State 11
		DEFAULT => -48
	},
	{#State 12
		DEFAULT => -37
	},
	{#State 13
		ACTIONS => {
			"this" => 4,
			"a" => 27,
			">-" => 29,
			"[" => 8,
			'NAME' => 11,
			'URI' => 12,
			"has" => 31,
			"{" => 14,
			"is" => 32,
			"=" => 33,
			'NODEID' => 17,
			"(" => 18,
			"<-" => 35,
			"." => 38
		},
		DEFAULT => -47,
		GOTOS => {
			'prop' => 34,
			'verb' => 28,
			'qname' => 19,
			'anonnode' => 10,
			'node' => 25,
			'uri_ref2' => 15,
			'nprefix' => 16,
			'property_list' => 37
		}
	},
	{#State 14
		ACTIONS => {
			'URI' => 12,
			'NAME' => 11,
			"bind" => 3,
			"{" => 14,
			"this" => 4,
			'NODEID' => 17,
			"(" => 18,
			"[" => 8,
			"\@prefix" => 9
		},
		DEFAULT => -47,
		GOTOS => {
			'subject' => 13,
			'node' => 5,
			'uri_ref2' => 15,
			'nprefix' => 16,
			'statement' => 6,
			'statementlist' => 39,
			'qname' => 19,
			'directive' => 20,
			'anonnode' => 10
		}
	},
	{#State 15
		DEFAULT => -20
	},
	{#State 16
		ACTIONS => {
			":" => 40
		}
	},
	{#State 17
		DEFAULT => -36
	},
	{#State 18
		ACTIONS => {
			":" => -47,
			'URI' => 12,
			'NAME' => 11,
			"{" => 14,
			"this" => 4,
			'NODEID' => 17,
			"(" => 18,
			"[" => 8
		},
		DEFAULT => -23,
		GOTOS => {
			'qname' => 19,
			'nodelist' => 42,
			'anonnode' => 10,
			'node' => 41,
			'uri_ref2' => 15,
			'nprefix' => 16
		}
	},
	{#State 19
		DEFAULT => -35
	},
	{#State 20
		DEFAULT => -6
	},
	{#State 21
		DEFAULT => 0
	},
	{#State 22
		ACTIONS => {
			":" => 43
		}
	},
	{#State 23
		DEFAULT => -8
	},
	{#State 24
		ACTIONS => {
			"." => 44
		},
		DEFAULT => -9
	},
	{#State 25
		DEFAULT => -19
	},
	{#State 26
		ACTIONS => {
			";" => 45,
			"]" => 46
		}
	},
	{#State 27
		DEFAULT => -17
	},
	{#State 28
		ACTIONS => {
			'INTEGER' => 51,
			'URI' => 12,
			'DOUBLE' => 52,
			'NAME' => 11,
			'STRING1' => 53,
			"{" => 14,
			"this" => 4,
			'NODEID' => 17,
			"(" => 18,
			'STRING2' => 49,
			'DECIMAL' => 50,
			"[" => 8
		},
		DEFAULT => -47,
		GOTOS => {
			'object_list' => 47,
			'object' => 48,
			'subject' => 54,
			'qname' => 19,
			'anonnode' => 10,
			'node' => 5,
			'uri_ref2' => 15,
			'nprefix' => 16
		}
	},
	{#State 29
		ACTIONS => {
			'URI' => 12,
			'NAME' => 11,
			"{" => 14,
			"this" => 4,
			'NODEID' => 17,
			"(" => 18,
			"[" => 8
		},
		DEFAULT => -47,
		GOTOS => {
			'prop' => 55,
			'qname' => 19,
			'anonnode' => 10,
			'node' => 25,
			'uri_ref2' => 15,
			'nprefix' => 16
		}
	},
	{#State 30
		DEFAULT => -27
	},
	{#State 31
		ACTIONS => {
			'URI' => 12,
			'NAME' => 11,
			"{" => 14,
			"this" => 4,
			'NODEID' => 17,
			"(" => 18,
			"[" => 8
		},
		DEFAULT => -47,
		GOTOS => {
			'prop' => 56,
			'qname' => 19,
			'anonnode' => 10,
			'node' => 25,
			'uri_ref2' => 15,
			'nprefix' => 16
		}
	},
	{#State 32
		ACTIONS => {
			'URI' => 12,
			'NAME' => 11,
			"{" => 14,
			"this" => 4,
			'NODEID' => 17,
			"(" => 18,
			"[" => 8
		},
		DEFAULT => -47,
		GOTOS => {
			'prop' => 57,
			'qname' => 19,
			'anonnode' => 10,
			'node' => 25,
			'uri_ref2' => 15,
			'nprefix' => 16
		}
	},
	{#State 33
		DEFAULT => -18
	},
	{#State 34
		DEFAULT => -14
	},
	{#State 35
		ACTIONS => {
			'URI' => 12,
			'NAME' => 11,
			"{" => 14,
			"this" => 4,
			'NODEID' => 17,
			"(" => 18,
			"[" => 8
		},
		DEFAULT => -47,
		GOTOS => {
			'prop' => 58,
			'qname' => 19,
			'anonnode' => 10,
			'node' => 25,
			'uri_ref2' => 15,
			'nprefix' => 16
		}
	},
	{#State 36
		ACTIONS => {
			":" => 59
		}
	},
	{#State 37
		ACTIONS => {
			";" => 45
		},
		DEFAULT => -4
	},
	{#State 38
		DEFAULT => -5
	},
	{#State 39
		ACTIONS => {
			"}" => 60,
			'URI' => 12,
			'NAME' => 11,
			"bind" => 3,
			"{" => 14,
			"this" => 4,
			'NODEID' => 17,
			"(" => 18,
			"[" => 8,
			"\@prefix" => 9
		},
		DEFAULT => -47,
		GOTOS => {
			'statement' => 24,
			'subject' => 13,
			'qname' => 19,
			'directive' => 20,
			'anonnode' => 10,
			'node' => 5,
			'uri_ref2' => 15,
			'nprefix' => 16
		}
	},
	{#State 40
		DEFAULT => -49,
		GOTOS => {
			'@2-0' => 62,
			'localname' => 61
		}
	},
	{#State 41
		ACTIONS => {
			":" => -47,
			'URI' => 12,
			'NAME' => 11,
			"{" => 14,
			"this" => 4,
			'NODEID' => 17,
			"(" => 18,
			"[" => 8
		},
		DEFAULT => -23,
		GOTOS => {
			'qname' => 19,
			'nodelist' => 63,
			'anonnode' => 10,
			'node' => 41,
			'uri_ref2' => 15,
			'nprefix' => 16
		}
	},
	{#State 42
		ACTIONS => {
			")" => 64
		}
	},
	{#State 43
		ACTIONS => {
			'NODEID' => 17,
			'URI' => 12,
			'NAME' => 11
		},
		DEFAULT => -47,
		GOTOS => {
			'qname' => 19,
			'uri_ref2' => 65,
			'nprefix' => 16
		}
	},
	{#State 44
		DEFAULT => -10
	},
	{#State 45
		ACTIONS => {
			'URI' => 12,
			'NAME' => 11,
			"has" => 31,
			"is" => 32,
			"{" => 14,
			"this" => 4,
			"=" => 33,
			'NODEID' => 17,
			"<-" => 35,
			"(" => 18,
			"a" => 27,
			">-" => 29,
			"[" => 8
		},
		DEFAULT => -47,
		GOTOS => {
			'prop' => 34,
			'verb' => 66,
			'qname' => 19,
			'anonnode' => 10,
			'node' => 25,
			'uri_ref2' => 15,
			'nprefix' => 16
		}
	},
	{#State 46
		DEFAULT => -26
	},
	{#State 47
		ACTIONS => {
			"," => 67
		},
		DEFAULT => -30
	},
	{#State 48
		DEFAULT => -33
	},
	{#State 49
		ACTIONS => {
			"\@" => 68
		},
		DEFAULT => -55,
		GOTOS => {
			'langOpt' => 69
		}
	},
	{#State 50
		DEFAULT => -44
	},
	{#State 51
		DEFAULT => -42
	},
	{#State 52
		DEFAULT => -43
	},
	{#State 53
		ACTIONS => {
			"\@" => 68
		},
		DEFAULT => -55,
		GOTOS => {
			'langOpt' => 70
		}
	},
	{#State 54
		DEFAULT => -39
	},
	{#State 55
		ACTIONS => {
			"->" => 71
		}
	},
	{#State 56
		DEFAULT => -15
	},
	{#State 57
		ACTIONS => {
			"of" => 72
		}
	},
	{#State 58
		ACTIONS => {
			"<-" => 73
		}
	},
	{#State 59
		ACTIONS => {
			'NODEID' => 17,
			'URI' => 12,
			'NAME' => 11
		},
		DEFAULT => -47,
		GOTOS => {
			'qname' => 19,
			'uri_ref2' => 74,
			'nprefix' => 16
		}
	},
	{#State 60
		DEFAULT => -28
	},
	{#State 61
		DEFAULT => -38
	},
	{#State 62
		ACTIONS => {
			'FRAGID' => 75
		}
	},
	{#State 63
		DEFAULT => -25
	},
	{#State 64
		DEFAULT => -29
	},
	{#State 65
		ACTIONS => {
			"." => 76
		}
	},
	{#State 66
		ACTIONS => {
			'INTEGER' => 51,
			'URI' => 12,
			'DOUBLE' => 52,
			'NAME' => 11,
			'STRING1' => 53,
			"{" => 14,
			"this" => 4,
			'NODEID' => 17,
			"(" => 18,
			'STRING2' => 49,
			'DECIMAL' => 50,
			"[" => 8
		},
		DEFAULT => -47,
		GOTOS => {
			'object_list' => 77,
			'object' => 48,
			'subject' => 54,
			'qname' => 19,
			'anonnode' => 10,
			'node' => 5,
			'uri_ref2' => 15,
			'nprefix' => 16
		}
	},
	{#State 67
		ACTIONS => {
			'INTEGER' => 51,
			'URI' => 12,
			'DOUBLE' => 52,
			'NAME' => 11,
			'STRING1' => 53,
			"{" => 14,
			"this" => 4,
			'NODEID' => 17,
			"(" => 18,
			'STRING2' => 49,
			'DECIMAL' => 50,
			"[" => 8
		},
		DEFAULT => -47,
		GOTOS => {
			'object' => 78,
			'subject' => 54,
			'qname' => 19,
			'anonnode' => 10,
			'node' => 5,
			'uri_ref2' => 15,
			'nprefix' => 16
		}
	},
	{#State 68
		DEFAULT => -56,
		GOTOS => {
			'@4-1' => 79
		}
	},
	{#State 69
		ACTIONS => {
			"^" => 80
		},
		DEFAULT => -52,
		GOTOS => {
			'dTypeOpt' => 81
		}
	},
	{#State 70
		ACTIONS => {
			"^" => 80
		},
		DEFAULT => -52,
		GOTOS => {
			'dTypeOpt' => 82
		}
	},
	{#State 71
		DEFAULT => -12
	},
	{#State 72
		DEFAULT => -16
	},
	{#State 73
		DEFAULT => -13
	},
	{#State 74
		ACTIONS => {
			"." => 83
		}
	},
	{#State 75
		DEFAULT => -50,
		GOTOS => {
			'@3-2' => 84
		}
	},
	{#State 76
		DEFAULT => -45
	},
	{#State 77
		ACTIONS => {
			"," => 67
		},
		DEFAULT => -31
	},
	{#State 78
		DEFAULT => -34
	},
	{#State 79
		ACTIONS => {
			'LANGID' => 86
		}
	},
	{#State 80
		ACTIONS => {
			"^" => 87
		}
	},
	{#State 81
		DEFAULT => -41
	},
	{#State 82
		DEFAULT => -40
	},
	{#State 83
		DEFAULT => -46
	},
	{#State 84
		DEFAULT => -51
	},
	{#State 85
		DEFAULT => -32
	},
	{#State 86
		DEFAULT => -57,
		GOTOS => {
			'@5-3' => 88
		}
	},
	{#State 87
		ACTIONS => {
			'URI' => 89,
			'NAME' => 11
		},
		DEFAULT => -47,
		GOTOS => {
			'qname' => 90,
			'nprefix' => 16
		}
	},
	{#State 88
		DEFAULT => -58
	},
	{#State 89
		DEFAULT => -54
	},
	{#State 90
		DEFAULT => -53
	}
],
                                  yyrules  =>
[
	[#Rule 0
		 '$start', 2, undef
	],
	[#Rule 1
		 'document', 0, undef
	],
	[#Rule 2
		 '@1-0', 0,
sub
#line 39 "N3Parser.yp"
{my ($self) = @_;
    my $url = 'http://www.w3.org/2004/06/20-rules/#assert';
    my $atom = new W3C::Rdf::AlgaeCompileTree::Url($url, undef, $self);
    return $_[0]->YYData->{ALGAE2}->require($atom);
}
	],
	[#Rule 3
		 'document', 2,
sub
#line 44 "N3Parser.yp"
{    my ($self, $require, $statements) = @_;
    return [$require, @$statements];
}
	],
	[#Rule 4
		 'statement', 2,
sub
#line 54 "N3Parser.yp"
{
    $_[0]->YYData->{ALGAE2}->assert($_[0]->newDecl([[$_[1], $_[2]]]), undef);
}
	],
	[#Rule 5
		 'statement', 2,
sub
#line 58 "N3Parser.yp"
{
    $_[0]->YYData->{ALGAE2}->assert($_[0]->YYData->{L}, undef);
}
	],
	[#Rule 6
		 'statement', 1, undef
	],
	[#Rule 7
		 'statementlist', 1,
sub
#line 65 "N3Parser.yp"
{[$_[1]]}
	],
	[#Rule 8
		 'statementlist', 2,
sub
#line 67 "N3Parser.yp"
{[$_[1]]}
	],
	[#Rule 9
		 'statementlist', 2,
sub
#line 69 "N3Parser.yp"
{push (@{$_[1]}, $_[2]); $_[1]}
	],
	[#Rule 10
		 'statementlist', 3,
sub
#line 71 "N3Parser.yp"
{push (@{$_[1]}, $_[2]); $_[1]}
	],
	[#Rule 11
		 'subject', 1, undef
	],
	[#Rule 12
		 'verb', 3, undef
	],
	[#Rule 13
		 'verb', 3, undef
	],
	[#Rule 14
		 'verb', 1, undef
	],
	[#Rule 15
		 'verb', 2, undef
	],
	[#Rule 16
		 'verb', 3, undef
	],
	[#Rule 17
		 'verb', 1,
sub
#line 83 "N3Parser.yp"
{
    new W3C::Rdf::AlgaeCompileTree::Url('http://www.w3.org/1999/02/22-rdf-syntax-ns#type', $_[0]->YYData->{BaseUri}, $_[0]);
}
	],
	[#Rule 18
		 'verb', 1, undef
	],
	[#Rule 19
		 'prop', 1, undef
	],
	[#Rule 20
		 'node', 1, undef
	],
	[#Rule 21
		 'node', 1, undef
	],
	[#Rule 22
		 'node', 1, undef
	],
	[#Rule 23
		 'nodelist', 0,
sub
#line 98 "N3Parser.yp"
{[]}
	],
	[#Rule 24
		 'nodelist', 1,
sub
#line 100 "N3Parser.yp"
{[$_[1]]}
	],
	[#Rule 25
		 'nodelist', 2,
sub
#line 102 "N3Parser.yp"
{[$_[1], @{$_[2]}]}
	],
	[#Rule 26
		 'anonnode', 3,
sub
#line 106 "N3Parser.yp"
{    my ($self, undef, $list, undef) = @_;
    my $node = new W3C::Rdf::AlgaeCompileTree::BNode($self);
    $self->newDecl([[$node, $list]]);
    $node;
}
	],
	[#Rule 27
		 'anonnode', 2,
sub
#line 112 "N3Parser.yp"
{    my ($self, undef, $list, undef) = @_;
    my $node = new W3C::Rdf::AlgaeCompileTree::BNode($self);
    $node;
}
	],
	[#Rule 28
		 'anonnode', 3,
sub
#line 117 "N3Parser.yp"
{   my ($self, undef, $list, undef) = @_;
    &throw(new W3C::Util::Exception(-message => ""));
}
	],
	[#Rule 29
		 'anonnode', 3,
sub
#line 121 "N3Parser.yp"
{   my ($self, undef, $list, undef) = @_;
    $_[0]->_makeList($list);
}
	],
	[#Rule 30
		 'property_list', 2,
sub
#line 128 "N3Parser.yp"
{[[$_[1], $_[2]]]}
	],
	[#Rule 31
		 'property_list', 4,
sub
#line 130 "N3Parser.yp"
{push (@{$_[1]}, [$_[3], $_[4]]); $_[1]}
	],
	[#Rule 32
		 'property_list', 5,
sub
#line 132 "N3Parser.yp"
{push (@{$_[1]}, [$_[3], $_[4]]); $_[1]}
	],
	[#Rule 33
		 'object_list', 1,
sub
#line 138 "N3Parser.yp"
{[[$_[1], undef]]
}
	],
	[#Rule 34
		 'object_list', 3,
sub
#line 141 "N3Parser.yp"
{push (@{$_[1]}, [$_[3], undef]); $_[1]}
	],
	[#Rule 35
		 'uri_ref2', 1, undef
	],
	[#Rule 36
		 'uri_ref2', 1,
sub
#line 146 "N3Parser.yp"
{
    my $ret = $_[0]->YYData->{BNODES_BY_NAME}{$_[1]};
    if (!$ret) {
	$ret = $_[0]->YYData->{BNODES_BY_NAME}{$_[1]} = new W3C::Rdf::AlgaeCompileTree::BNode($_[0]);
    }
    return $ret;
}
	],
	[#Rule 37
		 'uri_ref2', 1,
sub
#line 154 "N3Parser.yp"
{
    new W3C::Rdf::AlgaeCompileTree::Url($_[1], $_[0]->YYData->{BaseUri}, $_[0]);
}
	],
	[#Rule 38
		 'qname', 3,
sub
#line 160 "N3Parser.yp"
{
    new W3C::Rdf::AlgaeCompileTree::QName($_[1], $_[3], $_[0]);
}
	],
	[#Rule 39
		 'object', 1, undef
	],
	[#Rule 40
		 'object', 3,
sub
#line 167 "N3Parser.yp"
{
    new W3C::Rdf::AlgaeCompileTree::Literal($_[1], $_[3], $_[2], $_[0]);
}
	],
	[#Rule 41
		 'object', 3,
sub
#line 171 "N3Parser.yp"
{
    new W3C::Rdf::AlgaeCompileTree::Literal($_[1], $_[3], $_[2], $_[0]);
}
	],
	[#Rule 42
		 'object', 1,
sub
#line 175 "N3Parser.yp"
{
    new W3C::Rdf::AlgaeCompileTree::Int($_[1], $_[0]);
}
	],
	[#Rule 43
		 'object', 1,
sub
#line 179 "N3Parser.yp"
{
    new W3C::Rdf::AlgaeCompileTree::Double($_[1], $_[0]);
}
	],
	[#Rule 44
		 'object', 1,
sub
#line 183 "N3Parser.yp"
{
    new W3C::Rdf::AlgaeCompileTree::Decimal($_[1], $_[0]);
}
	],
	[#Rule 45
		 'directive', 5,
sub
#line 190 "N3Parser.yp"
{
    $_[0]->addNamespace($_[2], $_[4]);
    $_[0]->YYData->{ALGAE2}->namespace($_[2], $_[4]);
}
	],
	[#Rule 46
		 'directive', 5,
sub
#line 195 "N3Parser.yp"
{
    $_[0]->addNamespace($_[2], $_[4]);
    $_[0]->YYData->{ALGAE2}->namespace($_[2], $_[4]);
}
	],
	[#Rule 47
		 'nprefix', 0, undef
	],
	[#Rule 48
		 'nprefix', 1, undef
	],
	[#Rule 49
		 '@2-0', 0,
sub
#line 210 "N3Parser.yp"
{&FRAGID}
	],
	[#Rule 50
		 '@3-2', 0,
sub
#line 210 "N3Parser.yp"
{&TOKEN}
	],
	[#Rule 51
		 'localname', 3,
sub
#line 211 "N3Parser.yp"
{$_[2]}
	],
	[#Rule 52
		 'dTypeOpt', 0, undef
	],
	[#Rule 53
		 'dTypeOpt', 3,
sub
#line 216 "N3Parser.yp"
{
    $_[3];
}
	],
	[#Rule 54
		 'dTypeOpt', 3,
sub
#line 220 "N3Parser.yp"
{
    new W3C::Rdf::AlgaeCompileTree::Url($_[3], $_[0]->YYData->{BaseUri}, $_[0]);
}
	],
	[#Rule 55
		 'langOpt', 0, undef
	],
	[#Rule 56
		 '@4-1', 0,
sub
#line 226 "N3Parser.yp"
{&LANGID}
	],
	[#Rule 57
		 '@5-3', 0,
sub
#line 226 "N3Parser.yp"
{&TOKEN}
	],
	[#Rule 58
		 'langOpt', 4,
sub
#line 227 "N3Parser.yp"
{
    new W3C::Rdf::AlgaeCompileTree::Literal($_[3], undef, undef, $_[0]);
}
	]
],
                                  @_);
    bless($self,$class);
}

#line 233 "N3Parser.yp"


#BEGIN {unshift@INC,('../..');}
use W3C::Util::Exception qw(&throw &catch);

use vars qw($TOKEN $FRAGID $LANGID);
($TOKEN, $FRAGID, $LANGID) = (\ "TOKEN", \ "FRAGID", \ "LANGID");

sub TOKEN {$_[0]->YYData->{NEXT} = $TOKEN}
sub FRAGID {$_[0]->YYData->{NEXT} = $FRAGID}
sub LANGID {$_[0]->YYData->{NEXT} = $LANGID}

sub _Error {
    my ($self) = @_;
    if (exists $self->YYData->{EXCEPTION}) {
	&throw($self->YYData->{EXCEPTION});
    }
    if (exists $self->YYData->{ERRMSG}) {
	&throw(new W3C::Util::YappDriver::GrammarException(-message => $self->YYData->{ERRMSG}, 
							   -location => $self->YYData->{LOCATION}));
        delete $self->YYData->{ERRMSG};
        return;
    }
    foreach my $entry (@{$self->{STACK}}) {
	print join (' | ', @$entry),"\n";
    }
    &throw(new W3C::Util::YappDriver::MesgYappContextException($self, -location => $self->YYData->{LOCATION}));
    my $trimmed = $self->YYData->{INPUT};
    $trimmed =~ s/[\r\n]*\Z//m;

    my ($token, $value, $expect, $data) = ($self->YYCurtok(), $self->YYCurval(), $self->YYExpect(), $self->YYData);
    my $tokenStr = defined $token && $token ne $value ? "$token " : '';
    my $valueStr = defined $value ? "'$value'" : 'EOF';
    my $dataStr = ref $data eq 'HASH' ? join ("\n", map {"$_: $data->{$_}"} keys %$data) : $data;
    $dataStr = substr($trimmed, $self->YYData->{my_LASTPOS}, 20);
    print "expected '$expect', got $tokenStr$valueStr at \"$dataStr\"\n";

    my $before = substr($trimmed, 0, $self->YYData->{my_LASTPOS}+1);
    $before =~ m/([^\r\n]*)\Z/m;
    my $column = length ($1) - 1;
    my $after = substr($trimmed, $self->YYData->{my_LASTPOS}+1);

    $after =~ m/([^\r\n]*)[\r\n]?(.*)/s;
    my ($line, $last) = ($1, $2);
    print "$before$line\n";
    print '=' x $column, "^\n";
    print "$last\n" if ($last);
    foreach my $entry (@{$self->{STACK}}) {
	print join (' | ', @$entry),"\n";
    }
}

sub _Lexer {
    my($self)=shift;

    if (defined $self->YYData->{INPUT} && pos $self->YYData->{INPUT} < length ($self->YYData->{INPUT})) {
    } else {
	if ($self->YYData->{my_DONE}) {
	    return ('', undef);
	}
	if (0) {
	if (!($self->YYData->{INPUT} = $self->nextChunk())) {
	    undef $self->YYData->{INPUT};
	    return ('', undef);
	}
	} else {
	my $pos = pos $self->YYData->{INPUT};
	my $chunk = $self->nextChunk();
	#print "\nchunk: $chunk\n";
	if (!$chunk) {
	    undef $self->YYData->{INPUT};
	    return ('', undef);
	}
	$self->YYData->{INPUT} .= $chunk;
	pos $self->YYData->{INPUT} = $pos;
	}
	#my $txt = $self->YYData->{INPUT};
	#print "\ntxt: $txt\n";
    }

    my ($token, $value) = ('', undef);
    while ($self->YYData->{INPUT} =~ m/\G\s*\#[^\n]*\n/gc) {}
    $self->YYData->{INPUT} =~ m/\G\s*/gc;
    $self->YYData->{my_LASTPOS} = pos $self->YYData->{INPUT};
    my $expect = $self->YYData->{NEXT};
    if ($expect == $FRAGID) {
    #FRAGID:		alpha alphanumeric ;
    #alphanumeric:	alpha | [0-9] | '_';
	if ($self->YYData->{INPUT} =~ m/\G([a-zA-Z][a-zA-Z0-9_\-]*)/gc) {
	    ($token, $value) = ('FRAGID',$1);
	} else {
	    &throw(new W3C::Util::YappDriver::MesgYappContextException($self, 
					       -location => $self->YYData->{LOCATION}, 
					       -message => "expected an FRAGID"));
	}
    } elsif ($expect == $LANGID) {
    #FRAGID:		alpha alphanumeric ;
    #alphanumeric:	alpha | [0-9] | '_';
	if ($self->YYData->{INPUT} =~ m/\G([a-zA-Z][a-zA-Z0-9_\-]*)/gc) {
	    ($token, $value) = ('LANGID',$1);
	} else {
	    &throw(new W3C::Util::YappDriver::MesgYappContextException($self, 
					       -location => $self->YYData->{LOCATION}, 
					       -message => "expected an LANGID"));
	}
    } elsif ($expect == $TOKEN) {
    #a:
	if ($self->YYData->{INPUT} =~ m/\Ga(?![a-zA-Z0-9_\-:])/gc) {
	    ($token, $value) = ('a','a');
    #URI:		"<" URI_Reference ">"
    #URI_Reference:	[^{}<>]*;    # short version
	} elsif ($self->YYData->{INPUT} =~ m/\G<([^\{\}\<\>]*)>/gc) {
	    ($token, $value) = ('URI',$1);
    #URI:		"<" URI_Reference ">"
    #URI_Reference:	[^{}<>]*;    # short version
	} elsif ($self->YYData->{INPUT} =~ m/\G_:([a-zA-Z0-9_\-]*)/gc) {
	    ($token, $value) = ('NODEID',$1);

    #NAME:		((alpha | "_") alphanumeric)
    #alpha:		[a-zA-Z];
    #alphanumeric:	alpha | [0-9] | '_';
	} elsif ($self->YYData->{INPUT} =~ m/\G([a-zA-Z_][a-zA-Z0-9_\-]*)/gc) {
	    ($token, $value) = ('NAME',$1);

    #exponent	 	[eE] ('-' | '+')? [0-9]+
    #double:		('-' | '+') ? ( [0-9]+ '.' [0-9]* exponent | '.' ([0-9])+ exponent | ([0-9])+ exponent )
	} elsif ($self->YYData->{INPUT} =~ m/\G((?:[+-])?(?:[0-9]+\.[0-9]|\.[0-9]+|[0-9]+)(?:[eE](?:[+-])?[0-9]+))/gc) {
	    ($token, $value) = ('DOUBLE',$1);

    #decimal:		('-' | '+')? ( [0-9]+ '.' [0-9]* | '.' ([0-9])+ | ([0-9])+ )
	} elsif ($self->YYData->{INPUT} =~ m/\G((?:[+-])?(?:[0-9]+\.[0-9]*|\.[0-9]+)+)/gc) {
	    ($token, $value) = ('DECIMAL',$1);

    #integer:		('-' | '+') ? [0-9]+
	} elsif ($self->YYData->{INPUT} =~ m/\G((?:[+-])?[0-9]+)/gc) {
	    ($token, $value) = ('INTEGER',$1);

    #STRING1:	'"' string1_char* '"';
    #string1_char:	'\\"' | [^\"] ;           # should disallow some other characters, etc.
	} elsif ($self->YYData->{INPUT} =~ m/\G\"([^\"]*)\"/gc) {
	    my $str = $1;
	    while (substr($str, length($str) - 1, 1) eq '\\') {
		if ($self->YYData->{INPUT} =~ m/\G([^\"]*)\"/gc) {
		    $str = substr($str, 0, length($str) - 1).$1;
		} else {
		    &throw(new W3C::Util::YappDriver::MesgYappContextException($self, 
					       -location => $self->YYData->{LOCATION}
					       -message => "string terminator '\"' not found"));
		}
	    }
	    ($token, $value) = ('STRING1', $str);

    #STRING2:	'"""' string2_char* '"""';
    #string2_char:	[^"] | ([^] [^] [^"]);    # something like this; need to think about it some more
	} elsif ($self->YYData->{INPUT} =~ m/\G(\@prefix)/gc) {
	    ($token, $value) = ($1,$1);
	} elsif ($self->YYData->{INPUT} =~ m/\G(==|\!=|<=|>=|\|\||\|\&|\|\-|\&\&)/gc) {
	    ($token, $value) = ($1,$1);
	} elsif ($self->YYData->{INPUT} =~ m/\G(.)/gc) {
	    ($token, $value) = ($1,$1);
	}
    } else {
	my $state = $expect;
	eval {$state = $$expect;};
	&throw(new W3C::Util::Exception(-message => "unknown state \"$state\""));
    }
    my $pos = pos $self->YYData->{INPUT};
    #print "\n$pos,$token,$value\n";
    return ($token, $value);
}

sub addNamespace {
    my ($self, $prefix, $namespace) = @_;
    $self->YYData->{-namespaceHandler}->addNamespace($prefix, $namespace->getUrl());
}

sub mapNamespace {
    my ($self, $qnameStr) = @_;
    return $self->YYData->{-namespaceHandler}->mapNamespace($qnameStr);
}

sub parse {
    my ($self, @args) = @_;
    $self->YYData->{NEXT} = $TOKEN;
    return $self->SUPER::parse(@args);
}

# Provide (one) chunk of text to parse.
sub nextChunk {
    my ($self) = @_;
    #return shift (@{$self->YYData->{my_CHUNKS}});
    #return shift (@ARGV);
    return <STDIN>;
}

# Handy debugging wrapper for calling semantics actions.
sub _wrap {
    my ($self, $obj, $method, @args) = @_;
    my @ret;
    eval {
	@ret = $obj->$method(@args);
    }; if ($@) {if (my $ex = &catch('W3C::Util::CachedContextException')) {
	&throw($ex);;
    } elsif ($ex = &catch('W3C::Util::Exception')) {
	my $newEx = new W3C::Util::CachedContextException(-str => $self->YYData->{INPUT}, 
							  -pos => $self->YYData->{my_LASTPOS}+1, 
							  -errorMessage => $ex->toString);
	$newEx->assumeStackTrace($ex);
	&throw($newEx);
    } else {
	my $newEx = new W3C::Util::CachedContextException(-str => $self->YYData->{INPUT}, 
							  -pos => $self->YYData->{my_LASTPOS}+1, 
							  -errorMessage => "$obj->$method: $@");
	&throw($newEx);
    }}
    return wantarray ? @ret : $ret[-1];
}

sub printArgs {
    return;
    print ':';
    foreach my $arg (@_) {
	print " $arg";
    }
    print ' Curtok:',$_[0]->YYCurtok;
    print ' Curval:',$_[0]->YYCurval;
    print ' Expect:',$_[0]->YYExpect;
    print ' Lexer:',$_[0]->YYLexer;
    print ' Data:',$_[0]->YYData;
    print "\n";
}

# Used by -M invocation:
#   perl -MW3C::Rdf::N3Parser -e '(new W3C::Rdf::RLN3Parser())->Run' '...'
sub main {
    my ($self) = @_;
    $self->Run();
}

# <parser state support>
sub newDecl {
    my ($self, $parm) = @_;
    my $ret = $self->YYData->{L};
    foreach my $decl (@$parm) {
	my ($subject, $propValList) = @$decl;
	foreach my $propVal (@$propValList) {
	    my ($property, $valueList) = @$propVal;
	    foreach my $valuePair (@$valueList) {
		my ($value, $constraints) = @$valuePair;
		# print $subject->toString.' '.$property->toString.' '.$value->toString."\n";
		my $toAdd = [];
		if (ref $value eq 'ARRAY') {
		    # we've got an object and a bunch of Decls about that object.
		    $toAdd = [$value->[1]];
		    $value = $value->[0];
		}
		my $newTerm = new W3C::Rdf::AlgaeCompileTree::Decl([$property, $subject, $value], 
								 $constraints, $self);
		#my $newTerm = W3C::Rdf::AlgaeCompileTree::Decl::new('W3C::Rdf::AlgaeCompileTree::Decl', 
		#						 [$property, $subject, $value], 
		#						 $constraints, $self);
		foreach my $term ($newTerm, @$toAdd) {
		    if ($ret) {
			$ret = new W3C::Rdf::AlgaeCompileTree::Conjunction($ret, $term, $self);
			#$ret = &W3C::Rdf::AlgaeCompileTree::Conjunction::new('W3C::Rdf::AlgaeCompileTree::Conjunction', 
			#						     $ret, $term, $self);
		    } else {
			$ret = $term;
		    }
		}
	    }
	}
    }
    $self->YYData->{L} = $ret;
    return $ret;
}

sub _makeList {
    my ($self, $list) = @_;
    my $RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';

    my $pType = new W3C::Rdf::AlgaeCompileTree::Url("${RDF}type", undef, $self);
    my $tList = new W3C::Rdf::AlgaeCompileTree::Url("${RDF}List", undef, $self);
    my $pFirst = new W3C::Rdf::AlgaeCompileTree::Url("${RDF}first", undef, $self);
    my $pRest = new W3C::Rdf::AlgaeCompileTree::Url("${RDF}rest", undef, $self);
    my $oNil = new W3C::Rdf::AlgaeCompileTree::Url("${RDF}nil", undef, $self);

    my $head = new W3C::Rdf::AlgaeCompileTree::BNode($self);
    my $tail = $head;
    my $t = $self->YYData->{L};
    my $arc;

    for (my $i = 0; $i < @$list; $i++) {
	my $node = $list->[$i];

	$arc = new W3C::Rdf::AlgaeCompileTree::Decl([$pType, $tail, $tList], undef, $self);
	$t = $t ? new W3C::Rdf::AlgaeCompileTree::Conjunction($t, $arc, $self) : $arc;

	$arc = new W3C::Rdf::AlgaeCompileTree::Decl([$pFirst, $tail, $node], undef, $self);
	$t = $t ? new W3C::Rdf::AlgaeCompileTree::Conjunction($t, $arc, $self) : $arc;

	my $next = $i == @$list - 1 ? $oNil : new W3C::Rdf::AlgaeCompileTree::BNode($self);
	$arc = new W3C::Rdf::AlgaeCompileTree::Decl([$pRest, $tail, $next], undef, $self);
	$t = $t ? new W3C::Rdf::AlgaeCompileTree::Conjunction($t, $arc, $self) : $arc;

	$tail = $next;
    }

    $self->YYData->{L} = $t;
    return $head;
}

# </parser state support>

package W3C::Rdf::N3Parser;
@W3C::Rdf::N3Parser::ISA = qw(W3C::Rdf::_N3Parser);
sub new {
    my ($proto, $n3String, $algae2, $location, @yappParms) = @_;
    my $class = ref($proto) || $proto;
    my $self = $class->SUPER::new(@yappParms);
    $self->YYData->{N3_STRING} = $n3String;
    $self->YYData->{LOCATION} = $location;
    $self->YYData->{BNODES_BY_NAME} = {};
    $self->YYData->{ALGAE2} = $algae2;
    $self->YYData->{BaseUri} = new W3C::Rdf::AlgaeCompileTree::Url($location, undef, $self);
    return $self;
}

sub nextChunk {
    my ($self) = @_;
    my $ret = $self->YYData->{N3_STRING};
    $self->YYData->{N3_STRING} = undef;
    return $ret;
}

# Interactive ReadLine parser -- under development
package W3C::Rdf::RLN3Parser;
use W3C::Util::Exception;
@W3C::Rdf::RLN3Parser::ISA = qw(W3C::Rdf::N3Parser);
sub new {
    my ($proto, @parms) = @_;
    my $class = ref($proto) || $proto;

    # Change the parser driver to the readline driver.
    @W3C::Rdf::_N3Parser::ISA = qw (W3C::Util::rlDriver);

    my $self = $class->SUPER::new(@parms);
    $self->YYData->{ACTIONS} = [];
    return $self;
}

sub nextChunk {
    my ($self) = @_;
    my $ret = undef;
    if ($self->{rl_COMPLETE_MODE}) {
	if ($self->{rl_SO_FAR}) {
	    $ret = $self->{rl_SO_FAR};
	    $self->{rl_SO_FAR} = undef;
	    #print "nextChunk: $ret\n";
	}
    } else {
	if (@{$self->YYData->{my_CHUNKS}}) {
	    $ret = shift (@{$self->YYData->{my_CHUNKS}});
	} else {
	    #return shift (@ARGV);
	    $ret = $self->readline('')."\n";
	    #print "ret: $ret";
	}
    }
    return $ret;
}

# perl -MW3C::Rdf::N3Parser -e '(new W3C::Rdf::RLN3Parser())->Run' 'asdf'
# b /usr/share/perl5/Parse/Yapp/Driver.pm:343

##!/usr/bin/perl
#BEGIN {unshift@INC,('../..');}
#use W3C::Rdf::N3Parser;
#$p = new W3C::Rdf::RLN3Parser();
#$p->main;

#./N3Parser "(ask '(<ab:cd> (?asdf ?s ?o)) assert '(ef:gh (?a ?b ?c)))"

1;

__END__

=head1 NAME

W3C::Rdf::N3Parser - parse the N3 language

=head1 SYNOPSIS

  use W3C::Rdf::N3Parser;
  my $p = new W3C::Rdf::N3Parser($n3String, $algae2, "n3.txt");
  my $actions = $p->parse($debug);
  foreach my $action (@$actions) {
    $action->delayedEvaluate($self->{RESULT_SET});
  }
  return $self->getReport();

=head1 DESCRIPTION

The N3Parser module binds a yapp grammar to semantic actions that build an
AlgaeCompileTree. In general, client applicatiosn have no direct interaction
with N3Parser. Devlopers wishing to extend the N3 query language
  http://www.w3.org/DesignIssues/N3

will need the perl yapp modules. The Makefile included with the W3C::Rdf CPAN
module has a target to re-compile the N3Parser grammar. Invoke this with
  make N3Parser.pm
It is likely that someone extending the N3Parser grammar will also want to
extended AlgaeCompileTree.

This module is part of the W3C::Rdf CPAN module.

=head1 AUTHOR

Eric Prud\'hommeaux <eric@w3.org>

=head1 SEE ALSO

W3C::Rdf::Algae2(3) W3C::Rdf::AlgaeCompileTree(3) perl(1).

=cut

1;
