The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Parse::Marpa::Grammar - A Marpa Grammar Object

DESCRIPTION

Grammar objects are created with the new constructor. Rules and options may be specified when the grammar is created, or later using the set method. Rules are most conveniently added with the mdl_source named argument, which takes a reference to a string containing an MDL grammar description as its value. MDL (the Marpa Description Language) is detailed in another document.

MDL indirectly uses another interface, the plumbing interface. Users who want the last word in control can use the plumbing directly, but they will lose a lot of convenience and maintainability. Those who need the ultimate in efficiency can get the best of both worlds by using MDL to create a grammar, then compiling that grammar, as described below. The plumbing is described in a document of its own. The MDL parser itself uses a compiled MDL file.

Marpa needs to do extensive precompution on grammars before they can be passed on to a recognizer or an evaluator. The user rarely needs to perform this precomputation explicitly. The methods which require precomputed grammars (compile and Parse::Marpa::Recognizer::new), do the precomputation themselves on a just-in-time basis.

For situations where the user needs to control the state of the grammar precisely, such as debugging or tracing, there is a method that explicitly precomputes a grammar: precompute. Once a grammar has been precomputed, it is frozen against many kinds of changes. For example, you cannot add rules to a precomputed grammar.

For their private use, Marpa recognizers make a deep copy of the the grammar used to create them. The deep copy is done by compiling the grammar, then decompiling the grammar.

Grammar compilation in Marpa means turning the grammar into a string with Marpa's compile method. Since a compiled grammar is a string, it can be handled as one. It can, for instance, be written to a file.

Marpa's decompile static method takes a compiled grammar, eval's it, then tweaks it a bit to create a properly set-up grammar object. A subsequent Marpa process can read this file, decompile the string, and continue the parse. This would eliminate the overhead both of parsing MDL and of precomputation. As mentioned, where efficiency is a major consideration, this will usually be better than using the plumbing interface.

METHODS

new

    my $grammar = Parse::Marpa::Grammar::new({ trace_rules => 1 });

    my $grammar = new Parse::Marpa::Grammar({});

    my $grammar = new Parse::Marpa::Grammar({
        mdl_source => \$mdl_source,
        ambiguous_lex => 0
    });

Parse::Marpa::Recognizer::new has one, required, argument -- a reference to a hash of named arguments. It returns a new grammar object or throws an exception.

Named arguments can be Marpa options. For these see "OPTIONS" in Parse::Marpa. In addition to the Marpa options, the mdl_source named argument and the named arguments of the plumbing interface are allowed. For details of the plumbing and its named arguments, see Parse::Marpa::Doc::Plumbing.

The value of the mdl_source named argument should be a reference to a string containing a description of the grammar in the Marpa Demonstration Language. Either the mdl_source named argument or the plumbing arguments may be used to build a grammar, but both cannot be used to build the same grammar object.

In the new and set methods, a Marpa option can be specified both directly, as a named argument to the method, and indirectly, in the MDL grammar description supplied as the value of an mdl_source argument. When that happens, the value in the MDL description is applied first, and value supplied with the method's named argument is applied after the MDL is processed. This fits the usual intent, which is for named arguments to override MDL settings. However, this also means that trace settings won't be in effect until after the grammar description is processed, and that can be too late for some of the traces. For a way around this, see the set method.

set

    Parse::Marpa::Grammar::set($grammar, { trace_lex => 1 });

    $g->set({ mdl_source => \$source });

The set method takes as its one, required, argument a reference to a hash of named arguments. It allows Marpa options, plumbing arguments and the mdl_source named argument to be specified for an already existing grammar object. It can be used to control the order in which the named arguments are applied.

In particular, some tracing options need to be turned on prior to specifying the grammar. To do this, an new grammar object can be created with the trace options set, but without a grammar specification. At this point, tracing will be in effect, and the set method can be used to specify the grammar, using either the mdl_source named argument or the plumbing arguments.

precompute

    $grammar->precompute();

    Parse::Marpa::Grammar::precompute($grammar);

The precompute method performs Marpa's precomputations on a grammar. It returns the grammar object or throws an exception.

It is usually not necessary for the user to call precompute. The methods which require a precomputed grammar (compile and Parse::Marpa::Recognizer::new), if passed a grammar on which the precomputations have not been done, perform the precomputation themselves on a "just in time" basis. But precompute can be useful in debugging and tracing, as a way to control precisely when precomputation takes place.

compile

    my $compiled_grammar = $grammar->compile();

    my $compiled_grammar = Parse::Marpa::Grammar::compile($grammar);

The compile method takes as its single argument a grammar object, and "compiles" it. It returns a reference to the compiled grammar. The compiled grammar is a string which was created using Data::Dumper. On failure, compile throws an exception.

decompile

    $grammar = Parse::Marpa::Grammar::decompile($compiled_grammar, $trace_fh);

    $grammar = Parse::Marpa::Grammar::decompile($compiled_grammar);

The decompile static method takes a reference to a compiled grammar as its first argument. Its second, optional, argument is a file handle. The file handle argument will be used both as the decompiled grammar's trace file handle, and for any trace messages produced by decompile itself. decompile returns the decompiled grammar object unless it throws an exception.

If the trace file handle argument is omitted, it defaults to STDERR and the decompiled grammar's trace file handle reverts to the default for a new grammar, which is also STDERR. The trace file handle argument is necessary because in the course of compilation, the grammar's original trace file handle may have been lost. For example, a compiled grammar can be written to a file and emailed. Marpa cannot rely on finding the original trace file handle available and open when a compiled grammar is decompiled.

When Marpa deep copies grammars internally, it uses the compile and decompile methods. To preserve the trace file handle of the original grammar, Marpa first copies the handle to a temporary, then restores the handle using the trace_file_handle argument of decompile.

SUPPORT

See the support section in the main module.

AUTHOR

Jeffrey Kegler

COPYRIGHT

Copyright 2007 - 2008 Jeffrey Kegler

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.