Provided by: libmarpa-r2-perl_2.086000~dfsg-5build1_amd64 bug

NAME

       Marpa::R2::Advanced::Thin - Direct access to Libmarpa

About this document

       Most Marpa users can ignore this document.  It describes Marpa's "thin" interface, which
       provides efficient access to Marpa's core library, Libmarpa.

       The "thin" interface is very low-level and is not designed to be convenient to use.  User-
       friendliness is expected to be provided by an upper layer.  The "thin" interface is
       intended for use in writing those upper layers.  Libmarpa is also intended for writing
       applications, when the programmer wants to eliminate the overhead of an upper layer, or
       wants the flexibility provided by direct access to Libmarpa, and is willing to go to some
       extra effort.

How this document is written

       This document assumes that the reader is familiar with the other Marpa::R2 documentation,
       as well as with the Libmarpa API document.  This means its reader will have to know some C
       language -- at least enough to understand a discussion written in terms of C functions,
       their parameters and return values, and C language macros.

       This document avoids duplicating the material in the Libmarpa API document.  Most Marpa
       thin interface functions correspond directly to a Libmarpa method, and their
       implementation follows a "general pattern".  This document describes that "general
       pattern".

       Methods that follow the general pattern are usually not mentioned specifically.  Methods
       that are exceptions to the general pattern are always mentioned, and behaviors which
       deviate from the general pattern are always described in detail.  This document also
       identifies those Libmarpa methods to which no Marpa thin interface method directly
       corresponds.

       This style of documentation is very efficient, which is one reason that it is the standard
       for C library interfaces to Perl.  Admittedly, however, it is also very terse.  As an aid
       to the reader, an example of a script using the Marpa thin interface is presented below.
       While small, the example is non-trival.  It is also full, in the sense it contains a
       complete logic flow, starting with the definition of the grammar and continuing all the
       way to the iteration of the values of an ambiguous parse.

Methods in the thin interface

       While the thin interface has a few methods of its own, most of its methods are wrappers
       for a method from the Libmarpa interface.  On the other hand, many Libmarpa methods do not
       have Marpa thin interface wrappers.  No internal Libmarpa method is part of the Marpa thin
       interface.

       Additionally, many of the external Libmarpa methods are omitted because their function is
       performed by the Marpa thin interface.  No thin interface method corresponds to the
       "marpa_check_version()" static method, because the Marpa thin interface interface handles
       its own version matching.

       No thin interface method corresponds to any of the Libmarpa configuration class methods.
       No Marpa thin interface object corresponds to Libmarpa's configuration objects.
       Configuration in the Marpa thin interface is done using Perl variables.

       No Marpa thin interface method corresponds to the "marpa_g_ref()" and "marpa_g_unref()"
       methods because the thin interface handles the reference counting of the Libmarpa objects
       it creates.  The application can rely on Libmarpa objects being cleaned up properly as
       part of Perl's usual garbage collection.  For the same reason, no Marpa thin interface
       method corresponds to the "ref" and "unref" methods of the other Libmarpa time classes.

       Whenever an external Libmarpa method is not mentioned in this document, the reader can
       assume that it has a wrapper that is implemented according to the general pattern, as
       described below.  Where the implementation of an external Libmarpa method is an exception
       to the general pattern, its implementation will be explicitly described and any
       corresponding Marpa thin interface method will have a section devoted to it and specifying
       its differences from the general pattern.

Libmarpa time objects and constructors

       As a reminder, Libmarpa's major classes are, in sequence, configuration, grammar,
       recognizer, bocage, ordering, tree and value.  The one-letter abbreviations for these are,
       respectively, "c", "g", "r", "b", "o", "t" and "v".

           Marpa_Config        Marpa::R2::Thin::C
           Marpa_Grammar       Marpa::R2::Thin::G
           Marpa_Recognizer    Marpa::R2::Thin::R
           Marpa_Bocage        Marpa::R2::Thin::B
           Marpa_Ordering      Marpa::R2::Thin::O
           Marpa_Tree          Marpa::R2::Thin::T
           Marpa_Value         Marpa::R2::Thin::V

       The thin interface implements a Perl class corresponding to each of Libmarpa time classes.
       The thin interface does not implement a Perl class corresponding to Libmarpa's
       configuration class.

       Objects in the thin Marpa classes should be treated as opaque scalars.  Applications must
       not define new methods, constants or variables in a thin Marpa classes.  Similarly,
       applications must not redefine, overload or remove existing elements.  Thin Marpa classes
       must not be subclassed.  Applications should restrict their operation on objects in the
       Marpa thin classes to assignments; calling methods of the class; and, in those cases where
       this document states that it is appropriate, passing them as arguments.

       Constructors for the time objects may be called using the "new" method of the
       corresponding Perl class.  For example,

           my $recce = Marpa::R2::Thin::R->new($grammar);

       Perl applications can destroy objects of the Marpa thin classes by undefining them, or by
       letting them go out of scope.  Application programmers do not need to concern themselves
       with the reference counting of Libmarpa objects.  The Marpa thin interface handles this.

The throw setting

       One of the most important functions of the Marpa thin interface to adapt Libmarpa's error
       reporting to Perl.  Perl allows two kinds of error reporting.  Perl methods can
       communicate failure via their return values, or they can throw exceptions.

       Each has its place.  Throwing failure as an exception is the default in the Marpa thin
       interface because it is safer, and because it is convenient for prototyping and the first
       cuts at a new application.  On the other hand, for Marpa thin applications to have access
       to the full flexibility and power of Libmarpa, they must be able to set the Marpa thin
       interface to return failure, instead of throwing failure as an exception.

       In choosing whether or not to throw a failure as an exception, almost every Marpa thin
       method obeys the throw setting.  If the throw setting is 1, failure is thrown.  If the
       throw setting is 0, failure is returned.

       The throw setting is 1 in newly created grammar objects.  Once created, the throw setting
       of a grammar object can be changed using the "throw_set()" method The throw setting of
       other objects is that of their base grammar.

       Nearly every Marpa thin method always obeys the throw setting.  Only three methods never
       obey the throw setting.  They are exceptions because their logic controls the throw
       setting, so that a problem with them suggests the throw setting itself may not be correct.
       The methods which never obey the throw setting, are "Marpa::R2::Thin::G->new()",
       "throw_set()" and "ruby_slippers_set()".  These methods throw all failures.

       One method allows the throw setting to be overriden.  For convenience in using the Ruby
       Slippers technique, the behavior of the "alternative()" method is also affected by a
       separate "Ruby Slippers" flag.  For details, see the description of that method.

Error codes, names and descriptions

       Errors in the Marpa thin interface come from two sources: Libmarpa, and the Marpa thin
       interface itself.  These will be called Libmarpa errors and thin interface errors,
       respectively.

       Internally, Marpa maintains two variables to track recent errors.  These are the error
       code and the error description.  For every defined error code, there is an error name.
       Together, the error code, the error name and the error descriptions are called the "error
       variables".

       When the most recent error was a Libmarpa error, the error code is the Libmarpa error
       code, as described in the Libmarpa API document.  A Libmarpa error code is a non-negative
       integer.  When the most recent error was a thin interface error, the error code is a Perl
       "undef".

       Libmarpa's integral error codes are rarely used directly, either in C or in Perl.  In C,
       the error codes are referred to using macros.  The macro names are available through the
       thin interface as error names.  For details see the section on error methods.  Thin
       interface errors do not have error names.

       In addition to error names, there are error descriptions.

       •   Error names are short mnemonics.  Error descriptions are typically longer.

       •   Error names and error codes have a one to one correspondence (bijection).  For a given
           error code, the error name will always be the same, and vice versa.  Error
           descriptions may contain text relating, not just to the error code, but to the
           specific error instance.

       •   The error name is defined if and only if the error code is defined.  Error
           descriptions always exist, whether or not there is an error code defined.

       •   A thin interface error will always have an error description.  A thin interface error
           will never have an error name.

       •   The programmer may expect error codes and error names to remain stable and may write
           code that relies on the numeric value of the error codes and the text of the error
           name.  Applications should treat the text of an error description as suitable for the
           purpose of passing it on to a human user, and should otherwise regard it as opaque.

       Error descriptions, while typically longer than error names, are intended for situations
       where it is most convenient if they fit into a single line, or at most two.  The Libmarpa
       API document contains a section on the Libmarpa error codes.  and there the descriptions
       are often longer and more detailed.

       Error codes and error descriptions should be considered valid only if the most recently
       called Marpa thin method indicated that it set the error code.  An application should
       assume that the error codes and error descriptions will be overwritten by the next call to
       any  thin interface method other than the "error()" method.

   Failure and the error variables
       A method indicates failure either by throwing an exception or by returning a value that
       indicates failure.  If a method follows the general pattern, it indicates failure if and
       only if its return value is less than or equal to -2.  Other methods indicate failure as
       stated in their descriptions in this document.

       Whenever a method indicates failure, that also indicates that it has set the error
       variables.  On Libmarpa failures, the error code is set to the Libmarpa error code.  On
       thin interface failure, the error code is set to a Perl "undef".  For both Libmarpa and
       thin interface failures, the error description is set to a text that describes the error.

   Success and the error variables
       On success, a method will take one of the following three actions with respect to the
       error variables:

       Reset the error code
           A successful method may set the error code to "MARPA_ERR_NONE", together with an error
           description that indicates there is no error.

       Leave the error code as is
           A successful method may leave the error code and error description as is.

       Set an informational error code
           A successful method may set a Libmarpa error code to a value other than
           "MARPA_ERR_NONE".  Error codes of this kind are called informational error codes.  The
           phrase "error code" in this context is something of a misnomer.  Informational error
           codes exist as a convenience for some applications, but typically are ignored.

       The Libmarpa API document sometimes specifies what a Libmarpa method does with the error
       code on success.  The Libmarpa API document always specifies if and when a method sets an
       informational error code.  If Libmarpa API document is silent, the application should
       regard it as unspecified whether the error code is reset or left as is.

The general pattern

       Most Marpa thin interface methods correspond directly to a Libmarpa method, and their
       behaviors are in most cases exactly the same.  These behaviors are called the "general
       pattern" in this document.  To avoid repetition, Marpa thin interface methods that follow
       the general pattern exactly are usually not described explicitly in this document.

   Method names
       The name of a general pattern method is that of its corresponding Libmarpa method, minus
       the 8-letter prefix which indicates its Libmarpa class.  For example, the Marpa thin
       interface method that corresponds to "marpa_g_start_symbol_set" is
       "$g->start_symbol_set()".  The class of the general pattern method will be the Marpa thin
       class corresponding to the time class of the Libmarpa method.  For example,
       "$g->start_symbol_set()" will be in the "Marpa::R2::Thin:G" Perl class.

   Arguments
       Libmarpa's class instance methods take an object of the their class as their first
       ("self") argument.  Zero or more non-self arguments follow the self argument.  The
       arguments of the corresponding general pattern Marpa thin method will be the same,
       converted from C types to Perl as described next.  (This discussion follows the convention
       used in perlobj, and considers the "self" object to be a Perl method's first argument.)

       In the general pattern, every argument whose type is one of Libmarpa's time classes is
       converted to the corresponding Marpa thin interface class.  Arguments which belong to
       Libmarpa's numbered classes ("Marpa_Earley_Set_ID", "Marpa_Rank", "Marpa_Rule_ID" and
       "Marpa_Symbol_ID") are converted to Perl scalar integers.  C language "int"'s are also
       converted to Perl scalar integers.

       The Marpa thin interface does not recognize booleans, either in C or in Perl.  For
       example, if a Perl true value is not a numeric 1, it will not be converted to a numeric 1
       in C, even in a situation where the Libmarpa method is clearly looking for a boolean.  The
       intent is to allow for future extensions to the Libmarpa interface that accept and
       interpret other numeric values.

   Return values
       In the general pattern, the return value from a Libmarpa method will always either belong
       to one of Libmarpa's numbered classes, or be a C language "int".  If the Libmarpa return
       value is a non-negative integer, the corresponding general pattern Marpa thin method will
       return a numeric Perl scalar.  If the Libmarpa method returns -1, its corresponding
       general pattern Marpa thin method will return a Perl "undef".

   General pattern failures
       General pattern methods consider failure to be a Libmarpa return value of -2 or less.
       Failure is thrown if the throw setting is 1.  On unthrown failure, the return value of the
       Libmarpa method will be returned by the Marpa thin method as a numeric Perl scalar.

   An example of a general pattern method
       Here is an example of a Libmarpa function whose corresponding Marpa thin method follows
       the general pattern.

         marpa_g_start_symbol_set (grammar, symbol_S);

       and here is the corresonding thin Marpa call:

           $grammar->start_symbol_set($symbol_S);

Error methods

       The thin interface to Libmarpa provides error methods more appropriate to the Perl
       environment than Libmarpa's own.

   "$g->error()"
           my ( $error_code, $error_description ) = $grammar->error();
           my @error_names = Marpa::R2::Thin::error_names();
           my $error_name = $error_names[$error_code];

       In scalar context, the "error()" method returns the error description.  In array context,
       it returns a 2-element array.  The first element of the array is the error code, and the
       second element is the error description.  Applications should assume that a call to any
       other Marpa thin method will overwrite the error code and error description.  For
       "error()" to successfully query the error code or error description of a method, "error()"
       should be the next Marpa thin interface method called.

   "$g->error_clear()"
       The "error_clear()" method follows the general pattern.

   "$g->error_names()"
       For a synopsis, see the section on the "$g->error()" method.  The "error_names()" method
       returns a reference to an array of error names, indexed by Libmarpa error code.

   "$g->throw_set()"
           $grammar->throw_set(0);

       The "throw_set()" method turns the throw flag for the grammar on or off, according to
       whether its argument is 1 or 0.  "throw_set()" fails if its argument is not a numeric 0 or
       1.  "throw_set()" itself never returns failure -- it always throws an exception.

   Omitted configuration methods
       All of the methods of Libmarpa's configuration class are omitted in the Marpa thin
       interface.  The functions performed by Libmarpa's configuration methods are handled in a
       more Perl-centric way by the Marpa thin interface.

Grammar methods

   "Marpa::R2::Thin::G->new()"
           my $grammar = Marpa::R2::Thin::G->new( { if => 1 } );

       The one argument to the Marpa thin interface's grammar constructor, is a reference to a
       hash of named arguments.  On success, the return value is a thin interface grammar object.
       "new()" does not obey the throw setting -- errors are always thrown.

       At present the only named argument allowed is "if", the interface number.  This argument
       is required and currently is required to have a value of 1, which specifies interface 1.
       The intent of the "if" argument is to provide for backward compatibility in the future.

       Although there is no error message or warning if the hash ref argument is omitted, new
       code should treat the hash ref argument as a required argument.  Calling "new()" without
       an argument is deprecated.  If the hash ref argument is omitted, the thin layer uses
       interface 0.  Interface 0 cannot be specified directly, and is deprecated.  The difference
       between interface 0 and interface 1 is that, in interface 0, the default throw setting of
       the newly created grammar object is unspecified.  (In fact, the interface 0 throw setting
       depends on an undocumented and deprecated global variable.)

   "$g->event()"
           my ( $event_type, $value ) = $grammar->event( $event_ix++ );

       The "event()" method returns a two-element array on success.  The first element is a
       string naming the event type, and the second is a scalar representing its value.  The
       string for an event type is its macro name, as given in the Libmarpa API document.

       Some event types have an event "value".  All event values are numeric Perl scalars.  The
       number is either a symbol ID or a count, as described in the Libmarpa API document.

       The permissible range of event indexes can be found with the Marpa thin interface's
       "event_count()" grammar method, which corresponds to Libmarpa's "marpa_g_event_count()"
       method.  The thin interface's "event_count()" method follows the general pattern.

       Since "event()" returns the event value whenever it exists, the Libmarpa
       "marpa_g_event_value()" method is unneeded.  The Libmarpa "marpa_g_event_value()" method
       has no corresponding Marpa thin interface method.

       "event()" obeys the throw setting.  On unthrown failure, "event()" returns a Perl "undef".

   "$g->rule_new()"
           my $start_rule_id = $grammar->rule_new( $symbol_S, [$symbol_E] );

       The "rule_new()" grammar method is the Libmarpa thin interface method corresponding to the
       "marpa_g_rule_new()" method.  It takes two arguments, both required.  The first argument
       is a symbol ID representing the rule's LHS, and the second argument is a reference to an
       array of symbol ID's.  The symbol ID's in the array represent the RHS.  On success, the
       return value is the ID of the new rule.

       "rule_new()" obeys the throw setting.  On unthrown failure, it returns -2.

   "$g->sequence_new()"
           my $sequence_rule_id = $grammar->sequence_new(
                   $symbol_S,
                   $symbol_a,
                   {   separator => $symbol_sep,
                       proper    => 0,
                       min       => 1
                   }
               );

       The "sequence_new()" grammar method is the Libmarpa thin interface method corresponding to
       the "marpa_g_sequence_new()" method.  It takes three arguments, all required.  The first
       argument is a symbol ID representing the sequence's LHS.  The second argument is a symbol
       ID representing the sequence's RHS.  The third argument is a reference to a hash of named
       arguments.

       The hash of named arguments may be empty.  If not empty, its keys, and their values, must
       be one of the following:

       "separator"
           The value of the "separator" named argument will be treated as an integer, and passed
           as the separator ID argument to the "marpa_g_sequence_new()" method.  It defaults to
           -1.

       "proper"
           If the value of "proper" named argument is a Perl true value, the
           "MARPA_PROPER_SEPARATION" flag will be set in the flags passed to the
           "marpa_g_sequence_new()" method.  Otherwise, the "MARPA_PROPER_SEPARATION" flag will
           not be set.

       "min"
           The value of the "min" named argument will be treated as an integer, and passed as the
           "min" argument to the "marpa_g_sequence_new()" method.  The "min" argument indicates
           the minimum number of repetitions of the sequence that are required.  It defaults to
           1.

       On success, the return value is the rule ID of the new sequence.

       Users should be aware that all sequences at the Marpa thin interface level are "keep
       separation".  This differs from the higher-level interface, which discards separators by
       default.  At the Marpa thin interface level, it is up to the programmer to discard
       separators, if that is what is wanted.

       "sequence_new()" obeys the throw setting.  On unthrown failure, it returns -2.

   "$g->precompute()"
           $grammar->precompute();

       The "precompute()" method follows the general pattern.  In addition to errors,
       "precompute()" also reports events.  Events are queried using the grammar's "event()"
       method.

       On success, "precompute()" returns an event count.  But, even when there is an error,
       "precompute()" often reports one or more events.  It is not safe to assume that no events
       occurred unless "precompute()" succeeds and reports an event count of zero.

   "$g->rule_rank()"
       The "rule_rank()" method is based on Libmarpa's "marpa_g_rule_rank()" method.  Its
       argument is the rule ID, and its return value is the rank, or a -2 to indicate an unthrown
       error.

       Note a return value of -2 is ambiguous -- it can indicate that the rank was -2, or that a
       failure occurred.  To distinguish the cases, the application can look at the error code.
       The error code will be "MARPA_ERR_NONE" if and only if the call was successful.  The error
       code can be found using the "error()" method.  Applications may find it more convenient to
       have "rule_rank()" always throw its errors.

   "$g->rule_rank_set()"
       The "rule_rank_set()" method is based on Libmarpa's "marpa_g_rule_rank_set()" method.  Its
       two arguments are the rule ID and a rule rank.  Its return value is the new value of the
       rank, or a -2 to indicate an unthrown error.

       Note a return value of -2 is ambiguous -- it can indicate that the rank was -2, or that a
       failure occurred.  To distinguish the cases, the application can look at the error code.
       The error code will be "MARPA_ERR_NONE" if and only if the call was successful.  The error
       code can be found using the "error()" method.  Applications may find it more convenient to
       have "rule_rank_set()" always throw its errors.

   Omitted grammar methods
       The "marpa_g_ref()" and "marpa_g_unref()" methods are omitted because the Marpa thin
       interface performs their function.  The "marpa_g_event_value()" method is omitted because
       its function is absorbed into the thin interface's "event()" grammar method.

   General pattern methods
       All grammar methods that are part of the Libmarpa external interface, but that are not
       mentioned explicitly in this document, are implemented following the general pattern, as
       described above.

Recognizer methods

   "Marpa::R2::Thin::R->new()"
           my $recce = Marpa::R2::Thin::R->new($grammar);

       The "new()" method takes a Marpa thin grammar object as its one argument.  On success, it
       returns a Marpa thin recognizer object.  "new()" obeys the throw setting.  On unthrown
       failure, it returns a Perl "undef".

   "$r->ruby_slippers_set()"
           $recce->ruby_slippers_set(1);

       With an argument of 1, the "ruby_slippers_set()" method enables "Ruby Slippers" mode.  An
       argument of 0 disables "Ruby Slippers" mode.  By default, Ruby Slippers mode is disabled.
       Note that this default (disabled) is the opposite of that in the higher level Marpa::R2
       interface.

       The "alternative()" method will only throw exceptions when "Ruby Slippers" mode is
       disabled and the throw flag is on.  One way of describing Ruby Slippers mode is as an
       override of the throw setting, one which only applies to the "alternative()" method.

       The "ruby_slippers_set()" method itself does not obey the throw setting.  All failures by
       "ruby_slippers_set()" are thrown as exceptions.

   "$r->alternative()"
           $recce->alternative( $symbol_number, 2, 1 );

       In the Libmarpa API the "alternative()" method returns an error code, with
       "MARPA_ERR_NONE" being the code returned if there was no error.  The "alternative()"
       method will throw the error code as an exception if and only if all three of the following
       are true:

       •   The base grammar's throw flag is on.

       •   The Ruby Slippers flag is off.

       •   The error code is not "MARPA_ERR_NONE".

       Of major interest is the error code "MARPA_ERR_UNEXPECTED_TOKEN_ID", which indicates that
       a token was not accepted because its token ID was not one of those expected.  Catching and
       recovering from this error is the basis of the Ruby Slippers parsing technique.  For more
       on the Ruby Slippers flag, see "ruby_slippers_set()".

   "$r->terminals_expected()"
           my @terminals = $recce->terminals_expected();

       The "terminals_expected()" method takes no arguments.  On success, it returns an array
       containing the symbol ID's of the expected terminals.  Note that the array of expected
       terminal ID's may be empty, so that an empty array is NOT a failure indicator.
       "terminals_expected()" obeys the throw setting.  On unthrown failure,
       "terminals_expected()" returns a Perl "undef".

   "$r->progress_item()"
           my $ordinal = $recce->latest_earley_set();
           $recce->progress_report_start($ordinal);
           ITEM: while (1) {
               my ($rule_id, $dot_position, $origin) = $recce->progress_item();
               last ITEM if not defined $rule_id;
               push @{$report}, [$rule_id, $dot_position, $origin];
           }
           $recce->progress_report_finish();

       The "progress_item()" method takes no arguments.  On success, it returns an array of 3
       elements: the rule ID, the dot position, and the earley set ID of the origin.  If there
       are no more items, "progress_item()" returns a Perl "undef".

       "progress_item()" obeys the throw setting.  On unthrown failure, the rule ID element in
       the array returned by "progress_item()" will have a value of -2.

   Omitted recognizer methods
       Because the Marpa thin interface handles reference counting internally, it does not
       implement methods directly corresponding to Libmarpa's "marpa_r_ref()" and
       "marpa_r_unref()" methods.

       There are Marpa thin methods corresponding to Libmarpa's "marpa_r_earley_set_value()" and
       "marpa_r_earley_set_value_set()" methods, but not to Libmarpa's
       "marpa_r_earley_set_values()" and "marpa_r_earley_set_values_set()" methods.  The
       difference between these is that the "values" form allows an integer and a pointer value
       to be set, while the "value" form allows only an integer to be set.  Perl applications
       which want to associate non-integer data with an Earley set should create an array, and
       use the integer to index the array.  The elements of the array can contain arbitrary data.

       The thin interface does not implement a way to set the Earley set pointer value, because
       to do so would not add value.  The thin interface would have to track the reference count
       of a pointer, and this can done as easily and efficiently, and with more flexibility, at
       the Perl level.

   Methods not mentioned
       All recognizer methods that are part of the Libmarpa external interface, but that are not
       mentioned explicitly in this document, are implemented following the general pattern, as
       described above.

Bocage methods

   "Marpa::R2::Thin::B->new()"
           my $latest_earley_set_ID = $recce->latest_earley_set();
           my $bocage = Marpa::R2::Thin::B->new( $recce, $latest_earley_set_ID );

       The "new()" method takes a Marpa thin recognizer object as its one argument.  On success,
       it returns a Marpa thin bocage object.  "new()" obeys the throw setting.  On unthrown
       failure, it returns a Perl "undef".

   Omitted bocage methods
       Because the Marpa thin interface handles reference counting internally, it does not
       implement methods directly corresponding to Libmarpa's "marpa_b_ref()" and
       "marpa_b_unref()" methods.

   Methods not mentioned
       All bocage methods that are part of the Libmarpa external interface, but that are not
       mentioned explicitly in this document, are implemented following the general pattern, as
       described above.

Ordering methods

   "Marpa::R2::Thin::O->new()"
           my $order = Marpa::R2::Thin::O->new($bocage);

       The "new()" method takes a Marpa thin bocage object as its one argument.  On success, it
       returns a Marpa thin ordering object.  "new()" obeys the throw setting.  On unthrown
       failure, it returns a Perl "undef".

   Omitted ordering methods
       Because the Marpa thin interface handles reference counting internally, it does not
       implement methods directly corresponding to Libmarpa's "marpa_o_ref()" and
       "marpa_o_unref()" methods.

   Methods not mentioned
       All ordering methods that are part of the Libmarpa external interface, but that are not
       mentioned explicitly in this document, are implemented following the general pattern, as
       described above.

Tree methods

   "Marpa::R2::Thin::T->new()"
           my $tree = Marpa::R2::Thin::T->new($order);

       The "new()" method takes a Marpa thin ordering object as its one argument.  On success, it
       returns a Marpa thin tree object.  "new()" obeys the throw setting.  On unthrown failure,
       it returns a Perl "undef".

   Omitted tree methods
       Because the Marpa thin interface handles reference counting internally, it does not
       implement methods directly corresponding to Libmarpa's "marpa_t_ref()" and
       "marpa_t_unref()" methods.

   Methods not mentioned
       All tree methods that are part of the Libmarpa external interface, but that are not
       mentioned explicitly in this document, are implemented following the general pattern, as
       described above.

Value methods

   "Marpa::R2::Thin::V->new()"
           my $valuator = Marpa::R2::Thin::V->new($tree);

       The "new()" method takes a Marpa thin tree object as its one argument.  On success, it
       returns a Marpa thin value object.  "new()" obeys the throw setting.  On unthrown failure,
       it returns a Perl "undef".

   "$v->location()"
           $type = $valuator->step_type();
           my ( $start, $end ) = $valuator->location();
           if ( $type eq 'MARPA_STEP_RULE' ) {
               my ($rule_id) = @step_data;
               $locations_report .= "Rule $rule_id is from $start to $end\n";
           }
           if ( $type eq 'MARPA_STEP_TOKEN' ) {
               my ($token_id) = @step_data;
               $locations_report .= "Token $token_id is from $start to $end\n";
           }
           if ( $type eq 'MARPA_STEP_NULLING_SYMBOL' ) {
               my ($symbol_id) = @step_data;
               $locations_report
                   .= "Nulling symbol $symbol_id is from $start to $end\n";
           }

       The "location()" method takes no arguments.  The "location()" method always succeeds,
       returning either an empty array or an array of two elements.

       •   If the last step was "MARPA_STEP_RULE", the array contains the locations where the
           rule starts and ends, as returned by the Libmarpa methods "marpa_v_rule_start_es_id()"
           and "marpa_v_es_id()".

       •   It the last step was "MARPA_STEP_TOKEN", the array contains the locations where the
           token starts and ends, as returned by the Libmarpa methods
           "marpa_v_token_start_es_id()" and "marpa_v_es_id()".

       •   It the last step was "MARPA_STEP_NULLING_SYMBOL", the array contains the locations
           where the token starts and ends, as returned by the Libmarpa methods
           "marpa_v_token_start_es_id()" and "marpa_v_es_id()".

       •   In any other case, the array is empty.

   "$v->step()"
           my ( $type, @step_data ) = $valuator->step();

       The "step()" method takes no arguments.  On success, "step()" returns an array, whose
       contents are as follows:

       "MARPA_STEP_RULE"
           If the step type is "MARPA_STEP_RULE", "step()" returns an array of 4 elements.  These
           will be, in order:

           •   The string ""MARPA_STEP_RULE"".

           •   The rule id, as returned by the Libmarpa method "marpa_v_rule_id()".

           •   The stack location where the child values of the rule begin, as returned by the
               Libmarpa method "marpa_v_token_arg_0()".  This is also the stack location to which
               the result should be written.

           •   The stack location where the child values of the rule end, as returned by the
               Libmarpa method "marpa_v_token_arg_n()".

       "MARPA_STEP_TOKEN"
           If the step type is "MARPA_STEP_TOKEN", "step()" returns an array of 4 elements.
           These will be, in order:

           •   The string ""MARPA_STEP_TOKEN"".

           •   The token id, as returned by the Libmarpa method "marpa_v_token()".

           •   The token value, as returned by the Libmarpa method "marpa_v_token_value()".

           •   The stack location to which the token's value should be written, as returned by
               the Libmarpa method "marpa_v_result()".

           As a reminder, Libmarpa's token values are always integers.  Applications will often
           have a richer or different semantics for token values.  One approach such applications
           can take is to use Libmarpa's token values as indexes into an array.

       "MARPA_STEP_NULLING_SYMBOL"
           If the step type is "MARPA_STEP_NULLING_SYMBOL", "step()" returns an array of 3
           elements.  These will be, in order:

           •   The string ""MARPA_STEP_NULLING_SYMBOL"".

           •   The ID of the nulling symbol, as returned by the Libmarpa method
               "marpa_v_symbol()".

           •   The stack location to which the nulling symbol's value should be written, as
               returned by the Libmarpa method "marpa_v_result()".

       "MARPA_STEP_INACTIVE"
           If the step type is "MARPA_STEP_INACTIVE", "step()" returns an empty array.

       "step()" obeys the throw setting.  On unthrown failure, "step()" returns an array whose
       only element is a string not reserved by Libmarpa.  A string is not reserved by Libmarpa
       if it does not begin with ""MARPA_"" in one of its capitalization variants.  The string
       will usually be a description of the error.

   "$v->step_type()"
           $type = $valuator->step_type();

       The "step_type()" method takes no arguments.  On success, "step_type()" returns the string
       indicating the type of the last Libmarpa valuator step.  If the last call of the "step()"
       method succeeded, the string returned by "step_type()" will be the same as the one that
       was the first element of the array returned by "step()".

       "step_type()" obeys the throw setting.  On unthrown failure, "step()" returns an array
       whose only element is a string not reserved by Libmarpa.  A string is not reserved by
       Libmarpa if it does not begin with ""MARPA_"" in one of its capitalization variants.  The
       string will usually be a description of the error.

   Omitted value methods
       Because the Marpa thin interface handles reference counting internally, it does not
       implement methods directly corresponding to Libmarpa's "marpa_v_ref()" and
       "marpa_v_unref()" methods.  The step accessor macros are folded into the thin interface's
       "$v->step()" and "$v->location()" methods.  For this reason, no thin interface macro
       corresponds directly to most of the individual step accessors.

   Methods not mentioned
       All value methods that are part of the Libmarpa external interface, but that are not
       mentioned explicitly in this document, are implemented following the general pattern, as
       described above.

Example

           my $grammar = Marpa::R2::Thin::G->new( { if => 1 } );
           $grammar->force_valued();
           my $symbol_S = $grammar->symbol_new();
           my $symbol_E = $grammar->symbol_new();
           $grammar->start_symbol_set($symbol_S);
           my $symbol_op     = $grammar->symbol_new();
           my $symbol_number = $grammar->symbol_new();
           my $start_rule_id = $grammar->rule_new( $symbol_S, [$symbol_E] );
           my $op_rule_id =
               $grammar->rule_new( $symbol_E, [ $symbol_E, $symbol_op, $symbol_E ] );
           my $number_rule_id = $grammar->rule_new( $symbol_E, [$symbol_number] );
           $grammar->precompute();

           my $recce = Marpa::R2::Thin::R->new($grammar);
           $recce->start_input();

           # The numbers from 1 to 3 are themselves --
           # that is, they index their own token value.
           # Important: zero cannot be itself!

           my @token_values         = ( 0 .. 3 );
           my $zero                 = -1 + push @token_values, 0;
           my $minus_token_value    = -1 + push @token_values, q{-};
           my $plus_token_value     = -1 + push @token_values, q{+};
           my $multiply_token_value = -1 + push @token_values, q{*};

           $recce->alternative( $symbol_number, 2, 1 );
           $recce->earleme_complete();
           $recce->alternative( $symbol_op, $minus_token_value, 1 );
           $recce->earleme_complete();
           $recce->alternative( $symbol_number, $zero, 1 );
           $recce->earleme_complete();
           $recce->alternative( $symbol_op, $multiply_token_value, 1 );
           $recce->earleme_complete();
           $recce->alternative( $symbol_number, 3, 1 );
           $recce->earleme_complete();
           $recce->alternative( $symbol_op, $plus_token_value, 1 );
           $recce->earleme_complete();
           $recce->alternative( $symbol_number, 1, 1 );
           $recce->earleme_complete();

           my $latest_earley_set_ID = $recce->latest_earley_set();
           my $bocage        = Marpa::R2::Thin::B->new( $recce, $latest_earley_set_ID );
           my $order         = Marpa::R2::Thin::O->new($bocage);
           my $tree          = Marpa::R2::Thin::T->new($order);
           my @actual_values = ();
           while ( $tree->next() ) {
               my $valuator = Marpa::R2::Thin::V->new($tree);
               my @stack = ();
               STEP: while ( 1 ) {
                   my ( $type, @step_data ) = $valuator->step();
                   last STEP if not defined $type;
                   if ( $type eq 'MARPA_STEP_TOKEN' ) {
                       my ( undef, $token_value_ix, $arg_n ) = @step_data;
                       $stack[$arg_n] = $token_values[$token_value_ix];
                       next STEP;
                   }
                   if ( $type eq 'MARPA_STEP_RULE' ) {
                       my ( $rule_id, $arg_0, $arg_n ) = @step_data;
                       if ( $rule_id == $start_rule_id ) {
                           my ( $string, $value ) = @{ $stack[$arg_n] };
                           $stack[$arg_0] = "$string == $value";
                           next STEP;
                       }
                       if ( $rule_id == $number_rule_id ) {
                           my $number = $stack[$arg_0];
                           $stack[$arg_0] = [ $number, $number ];
                           next STEP;
                       }
                       if ( $rule_id == $op_rule_id ) {
                           my $op = $stack[ $arg_0 + 1 ];
                           my ( $right_string, $right_value ) = @{ $stack[$arg_n] };
                           my ( $left_string,  $left_value )  = @{ $stack[$arg_0] };
                           my $value;
                           my $text = '(' . $left_string . $op . $right_string . ')';
                           if ( $op eq q{+} ) {
                               $stack[$arg_0] = [ $text, $left_value + $right_value ];
                               next STEP;
                           }
                           if ( $op eq q{-} ) {
                               $stack[$arg_0] = [ $text, $left_value - $right_value ];
                               next STEP;
                           }
                           if ( $op eq q{*} ) {
                               $stack[$arg_0] = [ $text, $left_value * $right_value ];
                               next STEP;
                           }
                           die "Unknown op: $op";
                       } ## end if ( $rule_id == $op_rule_id )
                       die "Unknown rule $rule_id";
                   } ## end if ( $type eq 'MARPA_STEP_RULE' )
                   die "Unexpected step type: $type";
               } ## end while ( my ( $type, @step_data ) = $valuator->step() )
               push @actual_values, $stack[0];
           } ## end while ( $tree->next() )

Copyright and License

         Copyright 2014 Jeffrey Kegler
         This file is part of Marpa::R2.  Marpa::R2 is free software: you can
         redistribute it and/or modify it under the terms of the GNU Lesser
         General Public License as published by the Free Software Foundation,
         either version 3 of the License, or (at your option) any later version.

         Marpa::R2 is distributed in the hope that it will be useful,
         but WITHOUT ANY WARRANTY; without even the implied warranty of
         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
         Lesser General Public License for more details.

         You should have received a copy of the GNU Lesser
         General Public License along with Marpa::R2.  If not, see
         http://www.gnu.org/licenses/.