—use
strict;
use
Moo;
# ABSTRACT: Parsing of a ClassFile
our
$VERSION
=
'0.009'
;
# VERSION
our
$AUTHORITY
=
'cpan:JDDPAUSE'
;
# AUTHORITY
use
Data::Section -setup;
#
# require because we do not import ANYTHING from these module, just require they are loaded
#
require
Marpa::R2;
has
_nonweak_constant_pool
=> (
is
=>
'rwp'
, prod_isa(ArrayRef),
default
=>
sub
{ [] } );
my
$_data
= ${ __PACKAGE__->section_data(
'bnf'
) };
my
$_grammar
= Marpa::R2::Scanless::G->new( {
source
=> \__PACKAGE__->bnf(
$_data
) } );
# --------------------------------------------------------
# What role MarpaX::Java::ClassFile::Role::Parser requires
# --------------------------------------------------------
sub
grammar {
$_grammar
}
sub
callbacks {
return
{
#
# Size of constant pool array is constant_pool_count - 1 as per the spec.
# Implicitely from the spec, indices in constant pool start at 1:
# - The final action on Constant pool will insert a fake undef entry at position 0
#
'constant_pool_count$'
=>
sub
{
$_
[0]->constant_pool_count(
$_
[0]->literalU2(
'constant_pool_count'
));
my
$constant_pool
=
$_
[0]->inner(
'ConstantPoolArray'
,
size
=>
$_
[0]->constant_pool_count - 1);
#
# Keep the version with references. This will go in the structure.
# C.f. call to MarpaX::Java::ClassFile::Struct::ClassFile->new().
#
$_
[0]->_set__nonweak_constant_pool([ @{
$constant_pool
} ]);
#
# The default constant_pool attribute is weakened.
# Thus this can be propagated to any other subgrammar, thus any other
# sub structure -;
#
$_
[0]->arrayRefWeakenisator(
$constant_pool
);
$_
[0]->constant_pool(
$constant_pool
);
#
# Pass this information to any child, weakened, so that they can pass it
# to their child as well, and so on.
#
foreach
(@{
$constant_pool
}) {
$_
->_constant_pool(
$constant_pool
)
if
(blessed(
$_
) && (
$_
->can(
'_constant_pool'
)))
}
},
'interfaces_count$'
=>
sub
{
$_
[0]->inner(
'InterfacesArray'
,
size
=>
$_
[0]->literalU2(
'interfaces_count'
)) },
'fields_count$'
=>
sub
{
$_
[0]->inner(
'FieldsArray'
,
size
=>
$_
[0]->literalU2(
'fields_count'
)) },
'methods_count$'
=>
sub
{
$_
[0]->inner(
'MethodsArray'
,
size
=>
$_
[0]->literalU2(
'methods_count'
)) },
'attributes_count$'
=>
sub
{
$_
[0]->inner(
'AttributesArray'
,
size
=>
$_
[0]->literalU2(
'attributes_count'
)) }
}
}
# ---------------
# Grammar actions
# ---------------
sub
_ClassFile {
my
(
$self
,
$magic
,
$minor_version
,
$major_version
,
$constant_pool_count
,
# $constant_pool,
$access_flags
,
$this_class
,
$super_class
,
$interfaces_count
,
$interfaces
,
$fields_count
,
$fields
,
$methods_count
,
$methods
,
$attributes_count
,
$attributes
) =
@_
;
MarpaX::Java::ClassFile::Struct::ClassFile->new(
magic
=>
$magic
,
minor_version
=>
$minor_version
,
major_version
=>
$major_version
,
constant_pool_count
=>
$constant_pool_count
,
constant_pool
=>
$_
[0]->_nonweak_constant_pool,
access_flags
=>
$access_flags
,
this_class
=>
$this_class
,
super_class
=>
$super_class
,
interfaces_count
=>
$interfaces_count
,
interfaces
=>
$interfaces
,
fields_count
=>
$fields_count
,
fields
=>
$fields
,
methods_count
=>
$methods_count
,
methods
=>
$methods
,
attributes_count
=>
$attributes_count
,
attributes
=>
$attributes
)
}
#
# We want to say that exhaustion is definitely fatal
#
has
'+exhaustion'
=> (
default
=>
sub
{
'fatal'
});
#
# We want to take control over constant_pool count and content in this class (and only here btw)
#
has
'+constant_pool_count'
=> (
is
=>
'rw'
);
has
'+constant_pool'
=> (
is
=>
'rw'
);
1;
=pod
=encoding UTF-8
=head1 NAME
MarpaX::Java::ClassFile::BNF::ClassFile - Parsing of a ClassFile
=head1 VERSION
version 0.009
=head1 AUTHOR
Jean-Damien Durand <jeandamiendurand@free.fr>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2016 by Jean-Damien Durand.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut
__DATA__
__[ bnf ]__
:default ::= action => ::first
event 'constant_pool_count$' = completed constant_pool_count
event 'interfaces_count$' = completed interfaces_count
event 'fields_count$' = completed fields_count
event 'methods_count$' = completed methods_count
event 'attributes_count$' = completed attributes_count
ClassFile ::=
magic
minor_version
major_version
constant_pool_count
(constant_pool) # C.f. in the constant_pool_count$ event
access_flags
this_class
super_class
interfaces_count
interfaces
fields_count
fields
methods_count
methods
attributes_count
attributes
action => _ClassFile
magic ::= U4 action => u4
minor_version ::= U2 action => u2
major_version ::= U2 action => u2
constant_pool_count ::= U2 action => u2
constant_pool ::= MANAGED action => ::first
access_flags ::= U2 action => u2
this_class ::= U2 action => u2
super_class ::= U2 action => u2
interfaces_count ::= U2 action => u2
interfaces ::= MANAGED action => ::first
fields_count ::= U2 action => u2
fields ::= MANAGED action => ::first
methods_count ::= U2 action => u2
methods ::= MANAGED action => ::first
attributes_count ::= U2 action => u2
attributes ::= MANAGED action => ::first