Provided by: libmarpa-r2-perl_12.000000-1_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.  and very
       familiar wth the Libmarpa API document.  Must of the terminology in this document is adopted from the
       Libmarpa API document.  The reader will also 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 is 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 recovery

       Error  recovery  is  as  in  the Libmarpa API, with changes appropriate to adopt it to a Perl module.  We
       recall the concepts of application behavior and diagnostic behavior from the  Libmarpa  API:  Application
       behaviors  are  those  that  normal  applications  may  expect, as specified in this and the Libmarpa API
       document.  Diagnostic behaviors are a subset of the  application  behaviors.   Diagnostic  behaviors  are
       those  that  diagnostic or testing code may reasonably attempt after an irrecoverable error.  Informally,
       application behaviors are promised, while diagnostic behaviors are hoped for.  For a full  discussion  of
       application and diagnostic behaviors, refer back to the Libmarpa API document.

       Analogously  to  the Libmarpa API, we call the object which caused a failure, the failure object.  If the
       failure object is a time object, its base grammar object is the  grammar  object  it  was  created  from,
       whether  directly,  indirectly or trivially.  A grammar object is considered to be created trivially from
       itself.  If the failure object is a time object, the failure grammar is the base grammar  object  of  the
       failure object.

       In  the  following  sections, we adopted the definitions of library-recoverable, ancestry-recoverable and
       fully recoverable failure to make them analogous to the Libmarpa API's definitions of these terms.

   Library-recoverable failure
       In the thin interface, "library-recoverable failure" might be more properly be called "module-recoverable
       failure".  We retain the term "library-recoverable failure" for convenience  in  referring  back  to  the
       Libmarpa API document.

       When  a  thin  wrapper corresponding to a Libmarpa method has a library-recoverable failure the following
       application behaviors are no longer available:

       •   Thin interface mutator and constructor method calls on objects whose  base  grammar  is  the  failure
           grammar.

       The following application behaviors remain available:

       •   All behaviors not in the thin interface, including the Perl environment itself, and all modules other
           than the thin interface.

       •   All thin interface static method calls.

       •   All thin interface accessor method calls, and thin interface object destruction.

       •   All  thin  interface  constructor  and mutator method calls for objects whose base grammar is not the
           failure grammar.

       For more details on library-recoverability, refer to the Libmarpa API document.

   Ancestry-recoverable failure
       When a thin wrapper corresponding to a Libmarpa method has a ancestry-recoverable failure  the  following
       application behaviors are no longer available:

       •   Thin  interface  mutator  and  constructor  method  calls  on on the failure object, or on one of the
           descendants of the failure object.

       The following application behaviors remain available:

       •   All behaviors not in the thin interface, including the Perl  environment  itself,  and  all  packages
           other than the thin interface.

       •   All thin interface static method calls.

       •   All thin interface accessor method calls, and thin interface object destruction.

       •   All  thin interface constructor and mutator method calls for objects that are not the failure object,
           or one of its descendants.

       For more details on ancestry-recoverability, refer to the Libmarpa API document.

   Fully recoverable failure
       After a fully recoverable failure, all application behaviors remain available.  For more details on fully
       recoverable failure, refer to the Libmarpa API document.

Error methods

       The thin interface to Libmarpa provides error methods more  appropriate  to  the  Perl  environment  than
       Libmarpa's own.  Calls to these methods are diagnostic behaviors.

   "$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.

       Most applications should call  the  force_valued()  method  immediately  after  the  call  of  the  new()
       constructor.   Not  doing  so  enables unvalued terminals, which is a deprecated feature both in the thin
       interface and the Libmarpa API.

       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->force_valued()"
           $grammar->force_valued();

       The  force_valued() follows the general pattern.  Most applications should call the force_valued() method
       immediately after the grammar's new() constructor.  Not doing so enables unvalued terminals, which  is  a
       deprecated feature both in the thin interface and the Libmarpa API.

   "$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.

       As   in   the   Libmarpa   API,   parsing   with   cycles   is   deprecated.   This  mean  that  treating
       "MARPA_ERR_GRAMMAR_HAS_CYCLE"   as   a   fully   recoverable    failure    is    deprecated.     Instead,
       "MARPA_ERR_GRAMMAR_HAS_CYCLE" should be treated as as a library-recoverable failure.

       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.

   "$g->symbol_is_terminal_set()"
           $grammar->symbol_is_terminal_set( $symbol_seq, 1 );

       The symbol_is_terminal_set() method is deprecated.  It  enables  the  LHS  terminals  feature,  which  is
       deprecated  in both the thin interface and the Libmarpa API.  The symbol_is_terminal_set() method follows
       the general pattern.

   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 2022 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/.

perl v5.40.1                                       2025-06-25                     Marpa::R2::Advanced::Thin(3pm)