[glibmm/gmmproc-refactor: 173/174] Beginings of Gir parser.
- From: Krzesimir Nowak <krnowak src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glibmm/gmmproc-refactor: 173/174] Beginings of Gir parser.
- Date: Thu, 1 Sep 2011 14:48:44 +0000 (UTC)
commit 90acf10bf6d24b71a7b8d62868785fa0e6a694ed
Author: Krzesimir Nowak <qdlacz gmail com>
Date: Thu Sep 1 16:29:47 2011 +0200
Beginings of Gir parser.
tools/pm/Gir/Handlers/TopLevel.pm | 18 +++
tools/pm/Gir/Parser.pm | 270 +++++++++++++++++++++++++++++++++++++
tools/pm/Gir/State.pm | 36 +++++
tools/pm/Gir/metadata | 65 +++++++++
4 files changed, 389 insertions(+), 0 deletions(-)
---
diff --git a/tools/pm/Gir/Handlers/TopLevel.pm b/tools/pm/Gir/Handlers/TopLevel.pm
new file mode 100644
index 0000000..7d984b2
--- /dev/null
+++ b/tools/pm/Gir/Handlers/TopLevel.pm
@@ -0,0 +1,18 @@
+package GirTopLevelHandlers;
+
+use strict;
+use warnings;
+use GirParser;
+
+sub _namespace_handler ($@)
+{
+ my ($self, $
+}
+
+sub get_handlers ()
+{
+ return
+ {
+ 'namespace' => \&_namespace_handler
+ }
+}
diff --git a/tools/pm/Gir/Parser.pm b/tools/pm/Gir/Parser.pm
new file mode 100644
index 0000000..fb57200
--- /dev/null
+++ b/tools/pm/Gir/Parser.pm
@@ -0,0 +1,270 @@
+package GirParser;
+
+use strict;
+use warnings;
+use XML::Parser;
+
+sub _extract_values($$)
+{
+ my ($keys, $attval) = @_;
+ my %params = ();
+ my %check = ();
+
+ foreach my $key (@keys)
+ {
+ $params{$key} = undef;
+ $check{$key} = undef;
+ }
+
+ my $att = undef;
+
+ foreach my $entry (@{$attval})
+ {
+ unless (defined ($att))
+ {
+ if (exists ($params{$entry}))
+ {
+ $att = $entry;
+ delete ($check{$att});
+ }
+ else
+ {
+ # TODO: unknown attribute, ignored.
+ }
+ }
+ else
+ {
+ $params{$att} = $entry;
+ $att = undef;
+ }
+ }
+
+ if (keys (%check) > 0)
+ {
+ # TODO: missing needed attribute.
+ }
+
+ return \%params;
+}
+
+sub _sub_start_include ($@)
+{
+ my ($self, @attval) = @_;
+ my $params = _extract_values (['name', 'version'], \ attval);
+
+ $self->parse_file ($params->{'name'} . '-' . $params->{'version'});
+}
+
+sub _sub_end_include ($)
+{
+ # NOTHING.
+}
+
+sub _sub_start_namespace ($@)
+{
+ my ($self, @attval) = @_;
+ my $params = _extract_values (['name'], @attval);
+ my $api = $self->{'api'};
+ my $name = $params->{'name'};
+
+ if ($api->has_namespace ($name))
+ {
+ # TODO: error?
+ }
+ $api->add_namespace ($name);
+}
+
+sub _sub_end_namespace ($)
+{
+ # NOTHING
+}
+
+sub _init ($)
+{
+ my $self = shift;
+ my $new_state = GirParserState->new ();
+ my $state_stack = $self->{'states_stack'};
+
+ push (@{$state_stack}, $new_state);
+ $self->{'state'} = $new_state;
+}
+
+sub _final ($)
+{
+ my $self = shift;
+ my $state_stack = $self->{'states_stack'};
+
+ pop (@{$state_stack});
+ $self->{'state'} = $state_stack->[-1];
+}
+
+sub _proof_of_concept_start ($$$@)
+{
+ my ($self, undef, $elem, @attval) = @_;
+ my $state = $self->{'current_state'};
+ my $handlers = $state->get_current_handlers ();
+ my $start_handlers = $handlers->get_start_handlers ();
+
+ if (exists ($start_handlers->{$elem}))
+ {
+ my $method = $start_handlers->{$elem};
+
+ $state->push_handlers ($handlers->get_subhandlers_for ($elem));
+ return $handlers->$method ($self, @attval);
+ }
+ # TODO: unknown elem?
+}
+
+sub _proof_of_concept_end ($$$)
+{
+ my ($self, undef, $elem) = @_;
+ my $state = $self->{'current_state'};
+
+ $state->pop_handlers ();
+
+ my $handlers = $state->get_current_handlers ();
+ my $end_handlers = $handlers->get_end_handlers ();
+
+ if (exists ($end_handlers->{$elem}))
+ {
+ my $method = $end_handlers->{$elem};
+
+ return $handlers->$method ($self);
+ }
+ # TODO: unknown elem?
+}
+
+sub _start ($$$@)
+{
+ my ($self, undef, $elem, @attval) = @_;
+ my $subhandlers = $self->{'start_subhandlers'};
+ my $ignored_tags = $self->{'ignored_tags'};
+
+ unless (exists ($ignored_tags->{$elem}))
+ {
+ if (exists ($subhandlers->{$elem}))
+ {
+ my $method = $subhandlers->{$elem};
+ my $state = $self->{'state'};
+
+ $state->push_tag ($elem);
+ return $self->$method (@attval);
+ }
+ # TODO: error - unknown element.
+ }
+}
+
+sub _end ($$$)
+{
+ my ($self, undef, $elem) = @_;
+ my $subhandlers = $self->{'end_subhandlers'};
+
+ if (exists ($subhandlers->{$elem}))
+ {
+ my $method = $subhandlers->{$elem};
+ my $state = $self->{'state'};
+
+ $state->pop_tag ();
+ return $self->$method ();
+ }
+}
+
+#
+## private functions
+#
+sub _get_ignored_tags ()
+{
+ return
+ {
+ 'repository' => 0,
+ 'package' => 1,
+ 'c:include' => 1,
+ 'alias' => 1,
+ 'constant' => 1,
+ 'doc' => 1 # TODO: docs are ignored temporarily - remove it later.
+ ''
+ }
+}
+
+sub _get_start_subhandlers ()
+{
+ return
+ {
+ 'include' => \&_sub_start_include,
+ 'namespace' => \&_sub_start_namespace
+ };
+}
+
+sub _get_end_subhandlers ()
+{
+ return
+ {
+ 'include' => \&_sub_end_include,
+ 'namespace' => \&_sub_end_namespace
+ };
+}
+
+sub new($)
+{
+ my $type = shift;
+ my $class = (ref ($type) or $type or 'GirParser');
+ my $self =
+ {
+ 'states_stack' => [],
+ 'top_level_start_subhandlers' => _get_top_level_start_subhandlers (),
+ 'top_level_end_subhandlers' => _get_top_level_end_subhandlers (),
+ 'repository_start_subhandlers' => _get_repository_start_subhandlers (),
+ 'repository_end_subhandlers' => _get_repository_end_subhandlers (),
+ 'namespace_start_subhandlers' => _get_namespace_start_subhandlers (),
+ 'namespace_end_subhandlers' => _get_namespace_end_subhandlers (),
+ 'parsed_girs' => {},
+ 'state' => undef,
+ 'api' => {} # TODO: replace with Gir::Api->new () or something like that.
+ };
+
+ return bless ($self, $class);
+}
+
+sub _create_xml_parser ($)
+{
+ my $self = shift;
+ my $xml_parser = XML::Parser->new ();
+
+ $xml_parser->setHandlers
+ (
+ Char => sub { $self->_char (@_); },
+ Comment => sub { $self->_comment (@_); },
+ Default => sub { $self->_default (@_); },
+ End => sub { $self->_end (@_); },
+ Final => sub { $self->_final (@_); },
+ Init => sub { $self->_init (@_); },
+ Start => sub { $self ->_start (@_); },
+ XMLDecl => sub { $self->_xmldecl (@_); }
+ );
+
+ return $xml_parser;
+}
+
+sub parse_file ($$)
+{
+ my ($self, $filename) = @_;
+ my $parsed_girs = $self->{'parsed_girs'};
+
+ unless (exists ($parsed_girs->{$filename}))
+ {
+ my $real_filename = File::Spec->catfile (GirConfig::get_girdir(), $filename);
+ my $xml_parser = $self->_create_xml_parser ();
+
+ $parsed_girs->{$filename} = undef;
+ $xml_parser->parsefile ($real_filename);
+ }
+}
+
+sub get_api ($)
+{
+ my $self = shift;
+
+ return $self->{'api'};
+}
+
+1;
diff --git a/tools/pm/Gir/State.pm b/tools/pm/Gir/State.pm
new file mode 100644
index 0000000..f65d42d
--- /dev/null
+++ b/tools/pm/Gir/State.pm
@@ -0,0 +1,36 @@
+package GirParserState;
+
+use strict;
+use warnings;
+use GirTopLevelHandlers;
+
+sub new ($)
+{
+ my $type = shift;
+ my $class = (ref ($type) or $type or 'GirParserState');
+ my $self =
+ {
+ 'tags_stack' => [],
+ 'current_handlers' => GirTopLevelHandlers::get_handlers ()
+ };
+
+ return bless ($self, $class);
+}
+
+sub push_tag ($$)
+{
+ my ($self, $name) = @_;
+ my $tags_stack = $self->{'tags_stack'};
+
+ push (@{$tags_stack}, $name);
+}
+
+sub pop_tag ($)
+{
+ my $self = shift;
+ my $tags_stack = $self->{'tags_stack'};
+
+ pop (@{$tags_stack});
+}
+
+1;
diff --git a/tools/pm/Gir/metadata b/tools/pm/Gir/metadata
new file mode 100644
index 0000000..46553f8
--- /dev/null
+++ b/tools/pm/Gir/metadata
@@ -0,0 +1,65 @@
+PARAM_COMMON
++-doc 1
+`-type|array 1
+ `-type 1
+
+FUNC_COMMON
++-doc 1
++-return-value 1
+| `-PARAM_COMMON 1
+`-parameters 1
+ `-parameter n
+ `-PARAM_COMMON 1
+
+RECORD_COMMON
++-doc 1
++-function n
+| `-FUNC_COMMON 1
++-method n
+| `-FUNC_COMMON 1
++-field n
+ `-type|callback 1
+ `-FUNC_COMMON 1
+
+TYPE_COMMON
++-doc 1
+`-type 1
+
+CLASS_COMMON
++-RECORD_COMMON 1
++-virtual-method n
+| `-FUNC_COMMON 1
++-glib:signal n
+| `-FUNC_COMMON 1
+`-property n
+ `-TYPE_COMMON 1
+
+ENUMBIT_COMMON
++-doc 1
+`-member n
+
+repository 1
++-namespace 1
+| +-class n
+| | +-CLASS_COMMON 1
+| | +-implements n
+| | +-constructor n
+| | | `-FUNC_COMMON 1
+| +-interface n
+| | +-CLASS_COMMON
+| | `-prerequisite 1?
+| +-enumeration n
+| | `-ENUMBIT_COMMON 1
+| +-bitfield n
+| | `-ENUMBIT_COMMON 1
+| +-record n
+| | `-RECORD_COMMON 1
+| +-function n
+| | `-FUNC_COMMON 1
+| +-callback n
+| | `-FUNC_COMMON 1
+| +-alias n
+| | `-TYPE_COMMON 1
+| `-constant n
+| `-TYPE_COMMON 1
+`-implementation 1 (lolwhut? ignore)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]