aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.PL4
-rw-r--r--lib/Config/Parser.pm153
2 files changed, 155 insertions, 2 deletions
diff --git a/Makefile.PL b/Makefile.PL
index cee8413..b832c66 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -24,8 +24,8 @@ WriteMakefile(NAME => 'Config::Parser',
resources => {
repository => {
type => 'git',
- url => 'git://git.gnu.org.ua/config-td.git',
- web => 'http://git.gnu.org.ua/cgit/config-td.git/',
+ url => 'git://git.gnu.org.ua/config-parser.git',
+ web => 'http://git.gnu.org.ua/cgit/config-parser.git/',
},
},
provides => Module::Metadata->provides(version => '1.4',
diff --git a/lib/Config/Parser.pm b/lib/Config/Parser.pm
index 0f0a1f0..7d20aa2 100644
--- a/lib/Config/Parser.pm
+++ b/lib/Config/Parser.pm
@@ -132,4 +132,157 @@ sub loadsynt {
1;
+=head1 NAME
+
+Config::Parser - base class for configuration file parsers
+
+=head1 DESCRIPTION
+
+B<Config::Parser> provides a framework for writing configuration file
+parsers. It is an intermediate layer between the abstract syntax tree
+(B<Config::AST>) and implementation of a parser for a particular
+configuration file format.
+
+It takes a I<define by example> approach. That means that the implementor
+creates a derived class that implements a parser on top of B<Config::Parser>.
+Application writers write an example of configuration file in the B<__DATA__>
+section of their application, which defines the statements that are allowed
+in a valid configuration. This example is then processed by the parser
+implementation to create an instance of the parser, which is then used to
+process the actual configuration file.
+
+Let's illustrate this on a practical example. Suppose you need a parser for
+a simple configuration file, which consists of keyword/value pairs. In each
+pair, the keyword is separated from the value by an equals sign. Pairs are
+delimited by newlines. Leading and trailing whitespace characters on a line
+are ignored as well as are empty lines. Comments begin with a hash sign and
+end with a newline.
+
+You create the class B<Config::Parser::KV> based on B<Config::Parser>. The
+method B<parser> in this class implements the actual parser.
+
+Application writer decides what keywords are allowed in a valid configuration
+file and what are their values and puts them forth in the B<__DATA__> section
+of his program (normally in a class derived from B<Config::Parser::KV>, in
+the same format as the actual configuration file. For example:
+
+ __DATA__
+ basedir = STRING :mandatory
+ mode = OCTAL
+ size = NUMBER :array
+
+This excerpt defines a configuration with three allowed statements. Uppercase
+values to the right of the equals sign are data types. Values starting with
+a colon are flags that define the semantics of the values. This section
+declares that three keywords are allowed. The B<basedir> keyword takes
+string as its argument and must be present in a valid configuration. The
+B<mode> expects octal number as its argument. The B<size> keyword takes
+a number. Multiple B<size> statements are collapsed into an array.
+
+To parse the actual configuration file, the programmer creates an instance
+of the B<Config::Parse::KV> class, passing it the name of the file as its
+argument:
+
+ $cf = new Config::Parse::KV($filename);
+
+This call first parses the B<__DATA__> section and builds validation rules,
+then it parses the actual configuration from B<$filename>. Finally, it
+applies the validation rules to the created syntax tree. If all rules pass,
+the configuration is correct and the constructor returns a valid object.
+Otherwise, it issues proper diagnostics and returns B<undef>.
+
+Upon successful return, the B<$cf> object is used to obtain the actual
+configuration values as needed.
+
+Notice that syntax declarations in the B<__DATA__> section always follow the
+actual configuration file format, that's why we call them I<definition by
+example>. For instance, the syntax definition for a configuration file in
+Apache-like format would look like
+
+ __DATA__
+ <section ANY>
+ basedir STRING :mandatory
+ mode OCTAL
+ size NUMBER :array
+ </section>
+
+=head1 CONSTRUCTOR
+
+=head2 $cfg = new Config::Parser(%hash)
+
+Creates a new parser object. Keyword arguments are:
+
+=over 4
+
+=item B<filename>
+
+Name of the file to parse. This keyword must be present.
+
+=item B<line>
+
+Optional line where the configuration starts in B<filename>. It is used to
+keep track of statement location in the file for correct diagnostics. If
+not supplied, B<1> is assumed.
+
+=item B<fh>
+
+File handle to read from. If it is not supplied, new handle will be
+created by using B<open> on the supplied filename.
+
+=item B<lexicon>
+
+Dictionary of allowed configuration statements in the file. You will not
+need this parameter. It is listed here for completeness sake. Refer to
+the B<Config::AST> constructor for details.
+
+=back
+
+=head1 USER HOOKS
+
+These are the methods provided for implementors to do any implementation-
+specific tasks. Default implementations are empty placeholders.
+
+=head2 $cfg->init
+
+Called after creation of the base object, when parsing of the syntax
+definition has finished. Implementors can use it to do any
+implementation-specific initialization.
+
+=head2 $cfg->mangle
+
+Called after successful parsing. It can be used to modify the created
+source tree.
+
+=head1 PARSER METHODS
+
+The following two methods are derived from B<Config::AST>. They are
+called internally by the constructor, if the file name is supplied.
+
+=head2 $cfg->parse($filename, %opts)
+
+Parses the configuration from B<$filename>. Optional arguments are:
+
+=over 4
+
+=item B<fh>
+
+File handle to read from. If it is not supplied, new handle will be
+created by using B<open> on the supplied filename.
+
+=item B<line>
+
+Line to start numbering of lines from. It is used to keep track of
+statement location in the file for correct diagnostics. If not supplied,
+B<1> is assumed.
+
+=back
+
+=head2 $cfg->commit
+
+Finalizes the syntax tree. Returns true on success, and false on errors.
+
+=head1 SYNTAX DEFINITION
+
+=cut
+

Return to:

Send suggestions and report system problems to the System administrator.