MarpaX::Grammar::Parser - Converts a Marpa grammar into a forest using Tree::DAG_Node
MarpaX::Grammar::Parser
use MarpaX::Grammar::Parser; my(%option) = ( # Inputs: marpa_bnf_file => 'share/metag.bnf', user_bnf_file => 'share/stringparser.bnf', # Outputs: cooked_tree_file => 'share/stringparser.cooked.tree', raw_tree_file => 'share/stringparser.raw.tree', ); MarpaX::Grammar::Parser -> new(%option) -> run;
See share/*.bnf for input files and share/*.tree for output files.
For more help, run:
shell> perl -Ilib scripts/bnf2tree.pl -h
Note: Installation includes copying all files from the share/ directory, into a dir chosen by File::ShareDir. Run scripts/find.grammars.pl to display the name of the latter dir.
Note: The cooked tree can be graphed with MarpaX::Grammar::GraphViz2. That module has its own demo page.
MarpaX::Grammar::Parser uses Marpa::R2 to convert a user's SLIF-DSL into a tree of Marpa-style attributes, (see "raw_tree()"), and then post-processes that (see "compress_tree()") to create another tree, this time containing just the original grammar (see "cooked_tree()").
So, currently, the forest contains just 2 trees, acessible via the methods "raw_tree()" and "cooked_tree()". The nature of these trees is discussed in the "FAQ".
These trees are managed by Tree::DAG_Node.
Lastly, the major purpose of the cooked tree is to serve as input to MarpaX::Grammar::GraphViz2.
Install MarpaX::Grammar::Parser as you would for any Perl module:
Perl
Run:
cpanm MarpaX::Grammar::Parser
or run:
sudo cpan MarpaX::Grammar::Parser
or unpack the distro, and then either:
perl Build.PL ./Build ./Build test sudo ./Build install
or:
perl Makefile.PL make (or dmake or nmake) make test make install
new() is called as my($parser) = MarpaX::Grammar::Parser -> new(k1 => v1, k2 => v2, ...).
new()
my($parser) = MarpaX::Grammar::Parser -> new(k1 => v1, k2 => v2, ...)
It returns a new object of type MarpaX::Grammar::Parser.
Key-value pairs accepted in the parameter list (see also the corresponding methods [e.g. "marpa_bnf_file([$bnf_file_name])"]):
Include (1) or exclude (0) attributes in the tree file(s) output.
Default: 0.
The name of the text file to write containing the grammar as a cooked tree.
If '', the file is not written.
Default: ''.
Note: The bind_attributes option/method affects the output.
By default, an object of type Log::Handler is created which prints to STDOUT, but in this version nothing is actually printed.
See maxlevel and minlevel below.
maxlevel
minlevel
Set logger to '' (the empty string) to stop a logger being created.
logger
Default: undef.
Specify the name of Marpa's own SLIF-DSL file. This file ships with Marpa::R2. It's name is metag.bnf.
A copy, as of Marpa::R2 V 2.068000, ships with MarpaX::Grammar::Parser. See share/metag.bnf.
This option is mandatory.
This option affects Log::Handler objects.
See the Log::Handler::Levels docs.
Default: 'info'.
This option affects Log::Handler object.
Default: 'error'.
No lower levels are used.
The name of the text file to write containing the grammar as a raw tree.
Specify the name of the file containing your Marpa::R2-style grammar.
See share/stringparser.bnf for a sample.
Here, the [] indicate an optional parameter.
Get or set the option which includes (1) or excludes (0) node attributes from the output cooked_tree_file and raw_tree_file.
cooked_tree_file
raw_tree_file
Note: bind_attributes is a parameter to new().
bind_attributes
Returns a list of 2 elements: ($name, $attributes).
$name is just the name of the token.
$attributes is a hashref with these keys:
Indicates the token's name is (1) or is not (0) of the form '<...>'.
Indicates the token is quantified. $char is one of '', '*' or '+'.
If $char is '' (the empty string), the token is not quantified.
The user-specified version of the name of the token, including leading '<' and trailing '>' if any.
Called by "compress_tree()".
Converts 1 sub-tree of the raw tree into one sub-tree of the cooked tree.
Called automatically by "run()".
Converts the raw tree into the cooked tree, calling "compress_branch($index, $node)" once for each daughter of the raw tree.
Output is the tree returned by "cooked_tree()".
Returns the root node, of type Tree::DAG_Node, of the cooked tree of items in the user's grammar.
By cooked tree, I mean as post-processed from the raw tree so as to include just the original user's SLIF-DSL tokens.
The cooked tree is optionally written to the file name given by "cooked_tree_file([$output_file_name])".
The nature of this tree is discussed in the "FAQ".
See also "raw_tree()".
Get or set the name of the file to which the cooked tree form of the user's grammar will be written.
If no output file is supplied, nothing is written.
See share/stringparser.cooked.tree for the output of post-processing Marpa's analysis of share/stringparser.bnf.
This latter file is the grammar used in MarpaX::Demo::StringParser.
Note: cooked_tree_file is a parameter to new().
Calls $self -> logger -> log($level => $s) if ($self -> logger).
Get or set the logger object.
To disable logging, just set logger to the empty string.
Note: logger is a parameter to new().
Get or set the name of the file to read Marpa's grammar from.
Note: marpa_bnf_file is a parameter to new().
marpa_bnf_file
Get or set the value used by the logger object.
This option is only used if an object of type Log::Handler is created. See Log::Handler::Levels.
Note: maxlevel is a parameter to new().
Note: minlevel is a parameter to new().
The constructor. See "Constructor and Initialization".
Returns the root node, of type Tree::DAG_Node, of the raw tree of items in the user's grammar.
By raw tree, I mean as derived directly from Marpa.
The raw tree is optionally written to the file name given by "raw_tree_file([$output_file_name])".
See also "cooked_tree()".
Get or set the name of the file to which the raw tree form of the user's grammar will be written.
See share/stringparser.raw.tree for the output of Marpa's analysis of share/stringparser.bnf.
Note: raw_tree_file is a parameter to new().
The method which does all the work.
See "Synopsis" and scripts/bnf2tree.pl for sample code.
Get or set the name of the file to read the user's grammar's SLIF-DSL from. The whole file is slurped in as a single string.
See share/stringparser.bnf for a sample. It is the grammar used in MarpaX::Demo::StringParser.
Note: user_bnf_file is a parameter to new().
user_bnf_file
This is part of MarpaX::Languages::C::AST, by Jean-Damien Durand. It's 1,565 lines long.
The outputs are share/c.ast.cooked.tree and share/c.ast.raw.tree.
This is the output from post-processing Marpa's analysis of share/c.ast.bnf.
The command to generate this file is:
shell> scripts/bnf2tree.sh c.ast
This is the output from processing Marpa's analysis of share/c.ast.bnf. It's 56,723 lines long, which indicates the complexity of Jean-Damien's grammar for C.
It is part of MarpaX::Demo::JSONParser, written as a gist by Peter Stuifzand.
See https://gist.github.com/pstuifzand/4447349.
The outputs are share/json.1.cooked.tree and share/json.1.raw.tree.
This is the output from post-processing Marpa's analysis of share/json.1.bnf.
shell> scripts/bnf2tree.sh json.1
This is the output from processing Marpa's analysis of share/json.1.bnf.
It also is part of MarpaX::Demo::JSONParser, written by Jeffrey Kegler as a reply to the gist above from Peter.
The outputs are share/json.2.cooked.tree and share/json.2.raw.tree.
This is the output from post-processing Marpa's analysis of share/json.2.bnf.
shell> scripts/bnf2tree.sh json.2
This is the output from processing Marpa's analysis of share/json.2.bnf.
This is a copy of Marpa::R2's SLIF-DSL, as of Marpa::R2 V 2.068000.
See "marpa_bnf_file([$bnf_file_name])" above.
This is a copy of MarpaX::Demo::StringParser's SLIF-DSL.
The outputs are share/stringparser.cooked.tree and share/stringparser.raw.tree.
See "user_bnf_file([$bnf_file_name])" above.
This is the output from post-processing Marpa's analysis of share/stringparser.bnf.
shell> scripts/bnf2tree.sh stringparser
This is the output from processing Marpa's analysis of share/stringparser.bnf.
See also the next item.
This is the output of running:
shell> perl scripts/metag.pl share/metag.bnf share/stringparser.bnf > share/stringparser.treedumper
That script, metag.pl, is discussed just below, and in the "FAQ".
It is part of MarpaX::Database::Terminfo, written by Jean-Damien Durand.
The outputs are share/termcap.cooked.tree and share/termcap.info.raw.tree.
This is the output from post-processing Marpa's analysis of share/termcap.info.bnf.
shell> scripts/bnf2tree.sh termcap.info
This is the output from processing Marpa's analysis of share/termcap.info.bnf.
This is a neat way of using this module. For help, run:
Of course you are also encouraged to include the module directly in your own code.
This is a quick way for me to run bnf2tree.pl.
This prints the path to a grammar file. After installation of the module, run it with:
shell> perl scripts/find.grammars.pl (Defaults to json.1.bnf) shell> perl scripts/find.grammars.pl c.ast.bnf shell> perl scripts/find.grammars.pl json.1.bnf shell> perl scripts/find.grammars.pl json.2.bnf shell> perl scripts/find.grammars.pl stringparser.bnf shell> perl scripts/find.grammars.pl termcap.inf.bnf
It will print the name of the path to given grammar file.
This is Jeffrey Kegler's code. See the "FAQ" for more.
This lets me quickly proof-read edits to the docs.
Marpa's grammars are written in what we call a SLIF-DSL. Here, SLIF stands for Marpa's Scanless Interface, and DSL is Domain-specific Language.
Many programmers will have heard of BNF. Well, Marpa's SLIF-DSL is an extended BNF. That is, it includes special tokens which only make sense within the context of a Marpa grammar. Hence the 'Domain Specific' part of the name.
In practice, this means you express your grammar in a string, and Marpa treats that as a set of rules as to how you want Marpa to process your input stream.
Marpa's docs for its SLIF-DSL are here.
The raw tree is generated by processing the output of Marpa's parse of the user's grammar file. It contains Marpa's view of that grammar.
The cooked tree is generated by post-processing the raw tree, to extract just the user's grammar's tokens. It contains the user's view of their grammar.
The cooked tree can be graphed with MarpaX::Grammar::GraphViz2. That module has its own demo page.
The following items explain this in more detail.
Under the root, there are a set of nodes:
The node's names are the left-hand side of each statement in the grammar.
Each node is the root of a subtree describing the statement.
Under those nodes are a set of nodes:
So, the node's name is one of: '=' '::=' or '~'.
The node's name is the token itself.
The attributes of each node are a hashref, with these keys:
Indicates the token's name is or is not of the form '<...>'.
If $char is ' ' (the empty string), the token is not quantified.
See share/stringparser.cooked.tree.
The node's name is the integer start offset.
The node's name is the integer end offset.
The node's names are either an item from the user's grammar (when the attribute 'type' is 'Grammar') or a Marpa-assigned token (when the attribute 'type' is 'Marpa').
See share/stringparser.raw.attributes.tree for a tree with attributes displayed (bind_attributes => 1), and share/stringparser.raw.tree for the same tree without attributes (bind_attributes => 0).
This indicates what type of node it is. Values:
The class name is for the form: $class_name::$node_name.
$class_name is a constant provided by this module, and is 'MarpaX::Grammar::Parser::Dummy'.
$class_name
See share/stringparser.treedumper, which will make this much clearer.
The technique used to generate this file is discussed above, under "Data Files".
Note: The file share/stringparser.treedumper shows some class names, but they are currently not stored in the tree returned by the method "raw_tree()".
See share/stringparser.raw.tree.
Because dot assigns a special meaning to labels which begin with '<' and '<<'.
Here's one way, using the node names as sort keys.
As an example, choose $root as either $self -> cooked_tree or $self -> raw_tree, and then:
@daughters = sort{$a -> name cmp $b -> name} $root -> daughters; $root -> set_daughters(@daughters);
Note: Since the original order of the daughters, in both the cooked and raw trees, is significant, sorting is contra-indicated.
Jeffrey Kegler wrote it, and posted it on the Google Group dedicated to Marpa, on 2013-07-22, in the thread 'Low-hanging fruit'. I modified it slightly for a module context.
The original code is shipped as scripts/metag.pl.
As you can see he uses a different way of reading the files, one which avoids loading a separate module. I've standardized on Perl6::Slurp, especially when I want utf8, and File::Slurp when I want to read a directory. Of course I try not to use both in the same module.
It offered the output which was most easily parsed of the modules I tested. The others were Data::Dumper, Data::TreeDraw, Data::TreeDumper and Data::Printer.
http://jeffreykegler.github.io/Ocean-of-Awareness-blog/.
Yes, many by its author, and several others. See Marpa's homepage, just above, and:
The Marpa Guide, (in progress, by Peter Stuifzand and Ron Savage).
Parsing a here doc, by Peter Stuifzand.
An update of parsing here docs, by Peter Stuifzand.
Conditional preservation of whitespace, by Ron Savage.
MarpaX::Demo::JSONParser.
MarpaX::Demo::StringParser.
MarpaX::Grammar::GraphViz2.
MarpaX::Languages::C::AST.
Data::TreeDumper.
Log::Handler.
The file Changes was converted into Changelog.ini by Module::Metadata::Changes.
Version numbers < 1.00 represent development versions. From 1.00 up, they are production versions.
Email the author, or log a bug on RT:
https://rt.cpan.org/Public/Dist/Display.html?Name=MarpaX::Grammar::Parser.
MarpaX::Grammar::Parser was written by Ron Savage <ron@savage.net.au> in 2013.
Home page: http://savage.net.au/.
Australian copyright (c) 2013, Ron Savage.
All Programs of mine are 'OSI Certified Open Source Software'; you can redistribute them and/or modify them under the terms of The Artistic License 2.0, a copy of which is available at: http://www.opensource.org/licenses/index.html
To install MarpaX::Grammar::Parser, copy and paste the appropriate command in to your terminal.
cpanm
CPAN shell
perl -MCPAN -e shell install MarpaX::Grammar::Parser
For more information on module installation, please visit the detailed CPAN module installation guide.