[glibmm/gmmproc-refactor: 173/174] Beginings of Gir parser.



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]