summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorJed Barber <jjbarber@y7mail.com>2021-01-19 02:25:44 +1100
committerJed Barber <jjbarber@y7mail.com>2021-01-19 02:25:44 +1100
commitda389927ddf9240bbba10b819eb782e80a5d6bf7 (patch)
tree88b167b892de8c419151ca9a02c16f8d4ed96bec /doc
parent901c7e61278f16dc5c08cbebf74c2a816cd4b4b6 (diff)
Basic HTML documentation added
Diffstat (limited to 'doc')
-rw-r--r--doc/blank_template.html21
-rw-r--r--doc/credits.html30
-rw-r--r--doc/default.css29
-rw-r--r--doc/depends.html29
-rw-r--r--doc/errors.html33
-rw-r--r--doc/example_overview.html40
-rw-r--r--doc/features.html46
-rw-r--r--doc/index.html48
-rw-r--r--doc/lexer_comb.html347
-rw-r--r--doc/license.html53
-rw-r--r--doc/limits.html49
-rw-r--r--doc/parse_graph_op.html424
-rw-r--r--doc/parser_comb.html589
-rw-r--r--doc/quickstart.html65
-rw-r--r--doc/src_overview.html74
-rw-r--r--doc/test_overview.html51
-rw-r--r--doc/util_func.html148
17 files changed, 2076 insertions, 0 deletions
diff --git a/doc/blank_template.html b/doc/blank_template.html
new file mode 100644
index 0000000..0f1fcee
--- /dev/null
+++ b/doc/blank_template.html
@@ -0,0 +1,21 @@
+
+<!DOCTYPE html>
+
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>REPLACE THIS - Packrat Docs</title>
+ <link href="default.css" rel="stylesheet">
+ </head>
+
+ <body>
+
+
+ <h2>REPLACE THIS</h2>
+
+ <a href="index.html">Return to Contents</a>
+
+
+ </body>
+</html>
+
diff --git a/doc/credits.html b/doc/credits.html
new file mode 100644
index 0000000..74cb19b
--- /dev/null
+++ b/doc/credits.html
@@ -0,0 +1,30 @@
+
+<!DOCTYPE html>
+
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>Credits and Further Reading - Packrat Docs</title>
+ <link href="default.css" rel="stylesheet">
+ </head>
+
+ <body>
+
+
+ <h2>Credits and Further Reading</h2>
+
+ <a href="index.html">Return to Contents</a>
+
+
+ <p>The Packrat parser combinator library was programmed by
+ <a href="http://jedbarber.id.au/">Jedidiah Barber</a>.</p>
+
+ <p>Most of the ideas for the library were obtained from
+ <a href="http://richard.myweb.cs.uwindsor.ca/PUBLICATIONS/PADL_08.pdf">Parser
+ Combinators for Ambiguous Left-Recursive Grammars</a> (Frost, Hafiz, Callaghan, 2008)
+ with the notable exception of handling indirect left recursion.</p>
+
+
+ </body>
+</html>
+
diff --git a/doc/default.css b/doc/default.css
new file mode 100644
index 0000000..d7fe1b6
--- /dev/null
+++ b/doc/default.css
@@ -0,0 +1,29 @@
+
+body {
+ width: 90%;
+ margin-left: 2em;
+ margin-right: 2em;
+}
+
+
+table {
+ margin-top: 2em;
+ margin-bottom: 2em;
+ border: 1px solid black;
+}
+
+
+th {
+ padding-top: 0.5em;
+ padding-bottom: 0.5em;
+ border: 1px solid black;
+}
+
+
+td {
+ width: 50%;
+ padding: 0.5em 0.5em 0.5em 0.5em;
+ border: 1px solid black;
+}
+
+
diff --git a/doc/depends.html b/doc/depends.html
new file mode 100644
index 0000000..91ee096
--- /dev/null
+++ b/doc/depends.html
@@ -0,0 +1,29 @@
+
+<!DOCTYPE html>
+
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>Dependencies - Packrat Docs</title>
+ <link href="default.css" rel="stylesheet">
+ </head>
+
+ <body>
+
+
+ <h2>Dependencies</h2>
+
+ <a href="index.html">Return to Contents</a>
+
+
+ <p>
+ Aside from Ada standard libraries, Packrat relies on the following other packages:<br>
+ <br>
+ <a href="http://jedbarber.id.au/cgit/cgit.cgi/directed-graph/">directed-graph</a><br>
+ <a href="http://jedbarber.id.au/cgit/cgit.cgi/basic-unit-test/">basic-unit-test</a> (Only if using unit tests.)
+ </p>
+
+
+ </body>
+</html>
+
diff --git a/doc/errors.html b/doc/errors.html
new file mode 100644
index 0000000..e0f12c0
--- /dev/null
+++ b/doc/errors.html
@@ -0,0 +1,33 @@
+
+<!DOCTYPE html>
+
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>Handling Errors - Packrat Docs</title>
+ <link href="default.css" rel="stylesheet">
+ </head>
+
+ <body>
+
+
+ <h2>Handling Errors</h2>
+
+ <a href="index.html">Return to Contents</a>
+
+
+ <p>Whenever a <em>Lexer_Error</em> or <em>Parser_Error</em> is raised it is always accompanied
+ with a string that contains encoded information about where in the input the error occurred.</p>
+
+ <p>Such strings should not be examined directly, but if the <em>Decode</em> function from
+ <em>Packrat.Errors</em> is used then an array of symbol/position pairs is obtained. Each of those
+ pairs describes a point in the input where, if the given symbol was successfully found, a more
+ successful parse would have resulted.</p>
+
+ <p>Unfortunately at this time no resumption of lexing or parsing can be done once an error has
+ occurred.</p>
+
+
+ </body>
+</html>
+
diff --git a/doc/example_overview.html b/doc/example_overview.html
new file mode 100644
index 0000000..88d15a3
--- /dev/null
+++ b/doc/example_overview.html
@@ -0,0 +1,40 @@
+
+<!DOCTYPE html>
+
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>/example Overview - Packrat Docs</title>
+ <link href="default.css" rel="stylesheet">
+ </head>
+
+ <body>
+
+
+ <h2>/example Overview</h2>
+
+ <a href="index.html">Return to Contents</a>
+
+
+ <table>
+ <tr>
+ <td>calc.adb</td>
+ <td>Implements a basic expression calculator using lexer and parser combinators.
+ Can handle <em>+ - * / ^ ()</em> operators. Run with the <em>--help</em> switch for more info.</td>
+ </tr>
+ <tr>
+ <td>sentence.adb</td>
+ <td>Implements the sentence grammar used as an example in the reference paper on pages 2-3.</td>
+ </tr>
+ <tr>
+ <td>ssss.adb</td>
+ <td>Implements the highly ambiguous <em>s</em> grammar used in the reference paper on pages 5 and 12-13.
+ Length of input can be adjusted by command line argument and is therefore good for experiments on
+ complexity of the library. Also responds to the <em>--help</em> switch.</td>
+ </tr>
+ </table>
+
+
+ </body>
+</html>
+
diff --git a/doc/features.html b/doc/features.html
new file mode 100644
index 0000000..7ebad19
--- /dev/null
+++ b/doc/features.html
@@ -0,0 +1,46 @@
+
+<!DOCTYPE html>
+
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>Features - Packrat Docs</title>
+ <link href="default.css" rel="stylesheet">
+ </head>
+
+ <body>
+
+
+ <h2>Features</h2>
+
+ <a href="index.html">Return to Contents</a>
+
+
+ <h4>Lexing and Parsing</h4>
+ <p>Combinators are provided to build both lexers and parsers. Lexing is less flexible
+ as it does not need to incorporate choices, left recursion, or ambiguity.</p>
+
+ <h4>Left Recursion</h4>
+ <p>Any form of left recursive grammar will be parsed correctly, without infinite loops.</p>
+
+ <h4>Ambiguity</h4>
+ <p>All possible valid parses of the input by a constructed grammar will be followed
+ and incorporated into the resulting parse graph.</p>
+
+ <h4>Polynomial Complexity</h4>
+ <p>As per the paper that this library draws most of its ideas from, the worst case complexity
+ involved for both time and space should be polynomial. This has been experimentally confirmed
+ but as of yet no analysis has been done to determine specifics.</p>
+
+ <h4>Error Messages</h4>
+ <p>If there is a lexer or parser error then a message will be sent with the exception that
+ records what symbols were expected and where they were expected.</p>
+
+ <h4>Piecewise Parsing</h4>
+ <p>Both lexers and parsers can have their input fed to them piece by piece instead of all
+ at once.</p>
+
+
+ </body>
+</html>
+
diff --git a/doc/index.html b/doc/index.html
new file mode 100644
index 0000000..8b26b6e
--- /dev/null
+++ b/doc/index.html
@@ -0,0 +1,48 @@
+
+<!DOCTYPE html>
+
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>Table of Contents - Packrat Docs</title>
+ <link href="default.css" rel="stylesheet">
+ </head>
+
+ <body>
+
+
+ <h2>Table of Contents</h2>
+
+
+ <p>This is documentation for the Packrat parser combinator library.</p>
+
+
+ <ol>
+ <li><a href="license.html">License</a></li>
+ <li><a href="depends.html">Dependencies</a></li>
+ <li><a href="quickstart.html">Quickstart Guide</a></li>
+ <li><a href="features.html">Features</a></li>
+ <li><a href="limits.html">Limitations</a></li>
+ <li>File Overview<br>
+ <ol>
+ <li><a href="src_overview.html">/src</a></li>
+ <li><a href="example_overview.html">/example</a></li>
+ <li><a href="test_overview.html">/test</a></li>
+ </ol>
+ </li>
+ <li>Subprogram Listings<br>
+ <ol>
+ <li><a href="lexer_comb.html">Lexer Components</a></li>
+ <li><a href="parser_comb.html">Parser Components</a></li>
+ <li><a href="parse_graph_op.html">Parse Graph Operations</a></li>
+ <li><a href="util_func.html">Utility Functions</a></li>
+ </ol>
+ </li>
+ <li><a href="errors.html">Handling Errors</a></li>
+ <li><a href="credits.html">Credits and Further Reading</a></li>
+ </ol>
+
+
+ </body>
+</html>
+
diff --git a/doc/lexer_comb.html b/doc/lexer_comb.html
new file mode 100644
index 0000000..eef5c04
--- /dev/null
+++ b/doc/lexer_comb.html
@@ -0,0 +1,347 @@
+
+<!DOCTYPE html>
+
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>Lexer Components - Packrat Docs</title>
+ <link href="default.css" rel="stylesheet">
+ </head>
+
+ <body>
+
+
+ <h2>Lexer Components</h2>
+
+ <a href="index.html">Return to Contents</a>
+
+
+ <p>Lexers are a much simplified version of the parsers. They operate like one giant
+ <em>Choice</em> combinator, the other combinators that you can combine with are more
+ limited, all combinators operate in the more usual greedy consume-as-much-as-possible
+ fashion, and the output is a sequence of tokens instead of a parse graph.<br>
+ <br>
+ Think of it like grouping items of input together and labelling the groups, instead of
+ trying to create any complex parses.<br>
+ <br>
+ Usage of lexers is optional.</p>
+
+ <table>
+ <tr>
+<td><pre>
+generic
+ Components : in Component_Array;
+package Scan_Parts is
+
+ function Scan
+ (Input : in Traits.Element_Array)
+ return Traits.Tokens.Token_Array;
+
+ procedure Reset;
+
+end Scan_Parts;
+</pre></td>
+<td>The scanner version that allows for piecewise scanning. The <em>Scan</em> function can be
+called repeatedly with new input until it is supplied with an empty array, at which point it
+is assumed that the end of input has been reached.<br>
+<br>
+The <em>Reset</em> procedure reverts the scanner to a clean state the same as if it was just
+declared, with no partial results stored internally.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ Components : in Component_Array;
+package Scan_Once is
+
+ function Scan
+ (Input : in Traits.Element_Array)
+ return Traits.Tokens.Token_Array;
+
+ procedure Reset;
+
+end Scan_Once;
+</pre></td>
+<td>This scanner version assumes that the input supplied is the only input available.<br>
+<br>
+The <em>Reset</em> procedure reverts the scanner to a clean state the same as if it was just
+declared.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ Components : in Component_Array;
+package Scan_With is
+
+ function Scan
+ (Input : in With_Input)
+ return Traits.Tokens.Token_Array;
+
+ procedure Reset;
+
+end Scan_With;
+</pre></td>
+<td>This scanner uses the supplied function to retrieve input to be lexed. Like the <em>Scan_Parts</em>
+scanner it will continue to call the function until an empty array is returned, at which point it is
+assumed that the end of input has been reached.<br>
+<br>
+The <em>Reset</em> procedure reverts the scanner to a clean state the same as if it was just
+declared.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ Components : in Component_Array;
+ Pad_In : in Traits.Element_Type;
+ Pad_Out : in Traits.Tokens.Token_Type;
+package Scan_Set is
+
+ procedure Scan
+ (Input : in Traits.Element_Array;
+ Output : out Traits.Tokens.Token_Array);
+
+ procedure Reset;
+
+end Scan_Set;
+</pre></td>
+<td>This scanner allows the use of constant length input and output arrays. Scanning is done piecewise
+until the input array begins with the supplied <em>Pad_In</em> character, upon which it is assumed that
+the end of input has been reached. Any unused space in the output array is padded with the <em>Pad_Out</em>
+character.<br>
+<br>
+The <em>Reset</em> procedure reverts the scanner to a clean state the same as if it was just declared.<br>
+<br>
+Note that the input and output array lengths do not have to remain the same between successive calls to
+<em>Scan</em>.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ Components : in Component_Array;
+ Pad_In : in Traits.Element_Type;
+ Pad_Out : in Traits.Tokens.Token_Type;
+package Scan_Set_With is
+
+ procedure Scan
+ (Input : in With_Input;
+ Output : out Traits.Tokens.Token_Array);
+
+ procedure Reset;
+
+end Scan_Set_With;
+</pre></td>
+<td>A combination of <em>Scan_With</em> and <em>Scan_Set</em>, this scanner uses the supplied function
+to retrieve input to be lexed, but uses padding characters in the same manner as <em>Scan_Set</em>.<br>
+<br>
+The <em>Reset</em> procedure reverts the scanner to a clean state the same as if it was just declared.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ Label : in Traits.Label_Enum;
+ with function Combo
+ (Input : in Traits.Element_Array;
+ Start : in Positive)
+ return Combinator_Result;
+function Stamp
+ (Input : in Traits.Element_Array;
+ Context : in out Lexer_Context)
+ return Component_Result;
+</pre></td>
+<td>Runs the supplied combinator, and if successful converts the result into a token with the supplied
+label that then gets added to the output. Scanning then proceeds from just after the input covered by
+the token.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ Label : in Traits.Label_Enum;
+ with function Combo
+ (Input : in Traits.Element_Array;
+ Start : in Positive)
+ return Combinator_Result;
+function Discard
+ (Input : in Traits.Element_Array;
+ Context : in out Lexer_Context)
+ return Component_Result;
+</pre></td>
+<td>Does the same thing as <em>Stamp</em>, however rather than adding the token to the output it instead
+discards it. Scanning still proceeds from just after the input covered by the token.<br>
+<br>
+Even though the result is ultimately discarded it is nonetheless important that a label is used here so
+that informative error messages can be generated.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ Params : in Combinator_Array;
+function Sequence
+ (Input : in Traits.Element_Array;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Lexes the supplied combinator <em>Params</em> in order. If they are all successful then the joined
+successful result is returned, otherwise the combinator fails.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ with function Param
+ (Input : in Traits.Element_Array;
+ Start : in Positive)
+ return Combinator_Result;
+ Number : in Positive;
+function Count
+ (Input : in Traits.Element_Array;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Lexes the supplied combinator <em>Param</em> the supplied <em>Number</em> of times one after another.
+If it is all successful then the joined successful result is returned, otherwise the combinator fails.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ with function Param
+ (Input : in Traits.Element_Array;
+ Start : in Positive)
+ return Combinator_Result;
+ Minimum : in Natural := 0;
+function Many
+ (Input : in Traits.Element_Array;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Lexes the supplied combinator <em>Param</em> as many times as it can. Succeeds if it manages to do
+so at least <em>Minimum</em> number of times.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ with function Param
+ (Input : in Traits.Element_Array;
+ Start : in Positive)
+ return Combinator_Result;
+ with function Test
+ (Item : in Traits.Element_Type)
+ return Boolean;
+ Minimum : in Natural := 0;
+function Many_Until
+ (Input : in Traits.Element_Array;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Lexes the supplied combinator <em>Param</em> over and over until <em>Test</em> succeeds on the next
+available item in the input. Succeeds if it manages to lex <em>Param</em> at least <em>Minimum</em> times.
+Fails if <em>Param</em> fails before <em>Test</em> succeeds on the next available item of input.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ with function Test
+ (Item : in Traits.Element_Type)
+ return Boolean;
+function Satisfy
+ (Input : in Traits.Element_Array;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Lexes one item of input if the supplied <em>Test</em> function succeeds on that item, otherwise fails.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ with function Test
+ (Item : in Traits.Element_Type)
+ return Boolean;
+ with function Change
+ (From : in Traits.Element_Type)
+ return Traits.Element_Type;
+function Satisfy_With
+ (Input : in Traits.Element_Array;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>First uses the supplied <em>Change</em> function on the first item of input, then acts as in <em>Satisfy</em>
+on the changed item. Upon success the item lexed is the original item.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ Item : in Traits.Element_Type;
+function Match
+ (Input : in Traits.Element_Array;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Lexes one item of input if it matches <em>Item</em>.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ Item : in Traits.Element_Type;
+ with function Change
+ (From : in Traits.Element_Type)
+ return Traits.Element_Type;
+function Match_With
+ (Input : in Traits.Element_Array;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Lexes one item of input if, after applying the supplied <em>Change</em> function to it, it
+matches <em>Item</em>.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ Items : in Traits.Element_Array;
+function Multimatch
+ (Input : in Traits.Element_Array;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Lexes the next <em>Items'Length</em> items of input if they match <em>Items</em>.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ Number : in Positive := 1;
+function Take
+ (Input : in Traits.Element_Array;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Lexes the next <em>Number</em> items of input.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ with function Test
+ (Item : in Traits.Element_Type)
+ return Boolean;
+function Take_While
+ (Input : in Traits.Element_Array;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Lexes successive items of input as long as they satisfy the supplied <em>Test</em> function.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ with function Test
+ (Item : in Traits.Element_Type)
+ return Boolean;
+function Take_Until
+ (Input : in Traits.Element_Array;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Lexes items of input until the next available item satisfies the supplied <em>Test</em> function.</td>
+ </tr>
+ </table>
+
+
+ </body>
+</html>
+
diff --git a/doc/license.html b/doc/license.html
new file mode 100644
index 0000000..33b1631
--- /dev/null
+++ b/doc/license.html
@@ -0,0 +1,53 @@
+
+<!DOCTYPE html>
+
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>Licensing Information - Packrat Docs</title>
+ <link href="default.css" rel="stylesheet">
+ </head>
+
+ <body>
+
+
+ <h2>Licensing Information</h2>
+
+ <a href="index.html">Return to Contents</a>
+
+
+ <p>The Packrat parser combinator library is licensed under the Sunset License v1.0.<br>
+ The full text of this license is as follows:</p>
+
+ <pre>
+
+SUNSET LICENSE
+Version 1.0, June 2017
+
+
+1. You may copy, modify, use, sell, or distribute this work, verbatim or
+modified, for any purpose.
+
+2. If you sell or distribute this work, whether verbatim or modified, you must
+include a copy of this license, and you must make the source code available for
+no extra charge.
+
+3. A modified version of this work must be clearly labeled as such.
+
+4. Derivative works must also be licensed under this license or a license of
+equivalent terms. As an exception, linking this work with another, whether
+statically or dynamically, does not impose any license requirements on the
+other work.
+
+5. If a minimum of 15 years have passed since the date of first publishing for
+a part of this work, then that part is placed into the public domain and you
+may do whatever you want with it, regardless of all other clauses.
+
+ </pre>
+
+ <p>This text can also be found in license.txt in the main directory of this repo.</p>
+
+
+ </body>
+</html>
+
diff --git a/doc/limits.html b/doc/limits.html
new file mode 100644
index 0000000..d09fe5b
--- /dev/null
+++ b/doc/limits.html
@@ -0,0 +1,49 @@
+
+<!DOCTYPE html>
+
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>Limitations - Packrat Docs</title>
+ <link href="default.css" rel="stylesheet">
+ </head>
+
+ <body>
+
+
+ <h2>Limitations</h2>
+
+ <a href="index.html">Return to Contents</a>
+
+
+ <h4>Recognisers</h4>
+ <p>While this package can be used to construct recognisers easily, this would likely
+ not be very efficient compared to a library more specialised for that purpose.</p>
+
+ <h4>Cyclic Grammars</h4>
+ <p>Grammars that have cycles in them will be treated as any other form of left recursion
+ and eventually be curtailed. This means that the resulting parse graph will not have
+ any cycles. If you want a cyclic grammar to result in a cyclic result, then this library
+ is not what you are after.</p>
+
+ <h4>Generics</h4>
+ <p>This library makes very heavy use of generics. If your Ada compiler has any issues
+ handling generics then you may experience suboptimal performance.</p>
+
+ <h4>Parse Graph Data Structure</h4>
+ <p>In order to keep the parse graph to polynomial space complexity, it is a specialised
+ data structure and is not the same thing as a more standard directed graph.</p>
+
+ <h4>Piecewise Parsing</h4>
+ <p>Due to the possibility of incomplete parses, in the worst case using piecewise parsing
+ can result in the lexer or parser holding the entire input in memory before returning a
+ result.</p>
+
+ <h4>Error Recovery</h4>
+ <p>While error messages can be informative, there is currently no consideration given to
+ being able to recover from an error and continue parsing.</p>
+
+
+ </body>
+</html>
+
diff --git a/doc/parse_graph_op.html b/doc/parse_graph_op.html
new file mode 100644
index 0000000..2cc3591
--- /dev/null
+++ b/doc/parse_graph_op.html
@@ -0,0 +1,424 @@
+
+<!DOCTYPE html>
+
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>Parse Graph Operations - Packrat Docs</title>
+ <link href="default.css" rel="stylesheet">
+ </head>
+
+ <body>
+
+
+ <h2>Parse Graph Operations</h2>
+
+ <a href="index.html">Return to Contents</a>
+
+
+ <p>While this uses a directed graph library with node and edge labels internally, it is rather
+ different from a usage point of view. A parse graph is designed around tokens (from
+ <em>Packrat.Tokens</em>) that can each have more tokens as children.</p>
+
+ <table>
+ <tr>
+<td><pre>
+procedure Assign
+ (Target : in out Parse_Graph;
+ Source : in Parse_Graph);
+
+function Copy
+ (Source : in Parse_Graph)
+ return Parse_Graph;
+
+procedure Move
+ (Target, Source : in out Parse_Graph);
+</pre></td>
+<td>Standard assignment operations that are common to most things in the Ada standard Container library.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Is_Empty
+ (Container : in Parse_Graph)
+ return Boolean;
+</pre></td>
+<td>Tests whether a graph is empty.</td>
+ </tr>
+ <tr>
+<td><pre>
+procedure Clear
+ (Container : in out Parse_Graph);
+</pre></td>
+<td>Completely clears a graph, leaving it empty afterwards.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Debug_String
+ (Container : in Parse_Graph)
+ return String;
+</pre></td>
+<td>Generate a string that shows a pretty printed structure of the graph in a similar way to page three of
+the paper referenced in <a href="credits.html">Further Reading</a>.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Contains
+ (Container : in Parse_Graph;
+ Token : in Traits.Tokens.Token_Type)
+ return Boolean;
+
+function Contains
+ (Container : in Parse_Graph;
+ Position : in Traits.Tokens.Finished_Token_Type)
+ return Boolean;
+
+function Contains
+ (Container : in Parse_Graph;
+ Grouping : in Token_Group)
+ return Boolean;
+
+function Contains
+ (Container : in Parse_Graph;
+ Parent : in Traits.Tokens.Finished_Token_Type;
+ Subtokens : in Traits.Tokens.Finished_Token_Array)
+ return Boolean;
+</pre></td>
+<td>Tests for whether a graph contains various things.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Reachable
+ (Container : in Parse_Graph;
+ Position : in Traits.Tokens.Finished_Token_Type)
+ return Boolean
+with Pre => Container.Has_Root;
+</pre></td>
+<td>Checks whether a given finished token is reachable somehow from one or more of the root tokens of
+the graph.</td>
+ </tr>
+ <tr>
+<td><pre>
+function All_Reachable
+ (Container : in Parse_Graph)
+ return Boolean
+with Pre => Container.Has_Root;
+</pre></td>
+<td>Checks whether all tokens in the graph are reachable from one or more of the root tokens.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Valid_Token
+ (Fin_Token : in Traits.Tokens.Finished_Token_Type)
+ return Boolean;
+</pre></td>
+<td>Checks whether the start and finish values of a token make sense, or in other words that the finish
+value is no more than one less than the start value..</td>
+ </tr>
+ <tr>
+<td><pre>
+function Valid_Starts_Finishes
+ (Parent : in Traits.Tokens.Finished_Token_Type;
+ Subtokens : in Traits.Tokens.Finished_Token_Array)
+ return Boolean
+with Pre => Subtokens'Length > 0;
+</pre></td>
+<td>Checks whether the various start and finish values of all the tokens make sense for being a parent
+and a list of children. All the starts and finishes of individual tokens must make sense as in
+<em>Valid_Token</em>, all the children tokens must be in order, the parent start and finish range must
+fully cover all the children start and finish ranges, and none of the children start and finish ranges
+can overlap each other.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Loops_Introduced
+ (Container : in Parse_Graph;
+ Parent : in Traits.Tokens.Finished_Token_Type;
+ Subtokens : in Traits.Tokens.Finished_Token_Array)
+ return Boolean
+with Pre => Subtokens'Length > 0 and
+ Valid_Starts_Finishes (Parent, Subtokens);
+</pre></td>
+<td>Checks whether adding the given parent and children group connection would introduce a loop into
+the graph.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Is_Sorted
+ (Finishes : in Traits.Tokens.Finish_Array)
+ return Boolean;
+
+function Is_Sorted
+ (Positions : in Traits.Tokens.Finished_Token_Array)
+ return Boolean;
+
+function Is_Sorted
+ (Groupings : in Token_Group_Array)
+ return Boolean;
+</pre></td>
+<td>Checks whether various sorts of arrays are sorted.</td>
+ </tr>
+ <tr>
+<td><pre>
+function No_Duplicates
+ (Finishes : in Traits.Tokens.Finish_Array)
+ return Boolean;
+
+function No_Duplicates
+ (Positions : in Traits.Tokens.Finished_Token_Array)
+ return Boolean;
+
+function No_Duplicates
+ (Groupings : in Token_Group_Array)
+ return Boolean;
+</pre></td>
+<td>Checks whether there are any duplicates in various sorts of arrays.</td>
+ </tr>
+ <tr>
+<td><pre>
+procedure Include
+ (Container : in out Parse_Graph;
+ Token : in Traits.Tokens.Token_Type)
+with Post => Container.Contains (Token);
+</pre></td>
+<td>Adds a token to the graph. If the graph already contains the token, this does nothing.</td>
+ </tr>
+ <tr>
+<td><pre>
+procedure Connect
+ (Container : in out Parse_Graph;
+ Parent : in Traits.Tokens.Finished_Token_Type;
+ Subtokens : in Traits.Tokens.Finished_Token_Array)
+with Pre => Subtokens'Length > 0 and
+ Valid_Starts_Finishes (Parent, Subtokens) and
+ not Container.Loops_Introduced (Parent, Subtokens);
+</pre></td>
+<td>Adds a connection group between a parent token and some children tokens in the graph. If
+any of the tokens involved is not in the graph already they are first added. If the connection
+already exists in the graph, this does nothing.</td>
+ </tr>
+ <tr>
+<td><pre>
+procedure Prune
+ (Container : in out Parse_Graph;
+ Token : in Traits.Tokens.Token_Type)
+with Post => not Container.Contains (Token);
+
+procedure Prune
+ (Container : in out Parse_Graph;
+ Position : in Traits.Tokens.Finished_Token_Type)
+with Post => not Container.Contains (Position);
+
+procedure Prune
+ (Container : in out Parse_Graph;
+ Grouping : in Token_Group)
+with Post => not Container.Contains (Grouping);
+</pre></td>
+<td>Removes various things from a graph. No effort is made to remove anything made unreachable
+by these operations.</td>
+ </tr>
+ <tr>
+<td><pre>
+procedure Delete_Unreachable
+ (Container : in out Parse_Graph)
+with Pre => Container.Has_Root,
+ Post => Container.All_Reachable;
+</pre></td>
+<td>Removes all unreachable tokens, edges, and otherwise from a graph. Note that if the graph has
+no root tokens then this will become equivalent to <em>Clear</em>.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Has_Root
+ (Container : in Parse_Graph)
+ return Boolean;
+</pre></td>
+<td>Checks whether a graph contains a root token.</td>
+ </tr>
+ <tr>
+<td><pre>
+procedure Set_Root
+ (Container : in out Parse_Graph;
+ Tokens : in Traits.Tokens.Finished_Token_Array)
+with Pre => (for all F of Tokens => Container.Contains (F.Token)),
+ Post => Container.Has_Root;
+</pre></td>
+<td>Sets one or more root tokens for a graph.</td>
+ </tr>
+ <tr>
+<td><pre>
+procedure Clear_Root
+ (Container : in out Parse_Graph)
+with Post => not Container.Has_Root;
+</pre></td>
+<td>Removes all root tokens from the graph. Note that the graph will still contain the tokens,
+they just won't be considered root tokens anymore.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Root_Elements
+ (Container : in Parse_Graph)
+ return Traits.Tokens.Finished_Token_Array
+with Pre => Container.Has_Root;
+</pre></td>
+<td>Retrieves all the root tokens for a given graph.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Finish_List
+ (Container : in Parse_Graph;
+ Token : in Traits.Tokens.Token_Type)
+ return Traits.Tokens.Finish_Array
+with Pre => Container.Contains (Token),
+ Post => Is_Sorted (Finish_List'Result) and
+ No_Duplicates (Finish_List'Result);
+</pre></td>
+<td>For a given unfinished token and a graph, returns all valid finishes that the token could take
+such that the finished token is in the graph.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Is_Leaf
+ (Container : in Parse_Graph;
+ Position : in Traits.Tokens.Finished_Token_Type)
+ return Boolean
+with Pre => Container.Contains (Position);
+</pre></td>
+<td>Predicate to check whether a finished token is a leaf node in the graph. That is, whether it
+has no children.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Is_Branch
+ (Container : in Parse_Graph;
+ Position : in Traits.Tokens.Finished_Token_Type)
+ return Boolean
+with Pre => Container.Contains (Position);
+</pre></td>
+<td>Predicate to check whether a finished token is a branch node in the graph. That is, whether it
+has children.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Subgroups
+ (Container : in Parse_Graph;
+ Position : in Traits.Tokens.Finished_Token_Type)
+ return Token_Group_Array
+with Pre => Container.Contains (Position),
+ Post => Is_Sorted (Subgroups'Result) and
+ No_Duplicates (Subgroups'Result) and
+ (for all G of Subgroups'Result => Finish (G) = Position.Finish);
+</pre></td>
+<td>Returns an array of all the groups of children of a particular token in the graph. There will only
+be multiple groups if the graph is ambiguous at this point.</td>
+ </tr>
+ <tr>
+<td><pre>
+function First_Index
+ (Grouping : in Token_Group)
+ return Positive;
+
+function Last_Index
+ (Grouping : in Token_Group)
+ return Positive;
+
+function Length
+ (Grouping : in Token_Group)
+ return Ada.Containers.Count_Type;
+
+function Element
+ (Grouping : in Token_Group;
+ Index : in Positive)
+ return Traits.Tokens.Finished_Token_Type
+with Pre => Index in First_Index (Grouping) .. Last_Index (Grouping);
+</pre></td>
+<td>These work as you would expect on an array/vector. <em>Element</em> returns a particular
+child token in the given group.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Elements
+ (Grouping : in Token_Group)
+ return Traits.Tokens.Finished_Token_Array
+with Post => Is_Sorted (Elements'Result) and
+ Valid_Starts_Finishes (Parent (Grouping), Elements'Result);
+</pre></td>
+<td>Returns all the children tokens in the group as an array instead of a <em>Token_Group</em>.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Parent
+ (Grouping : in Token_Group)
+ return Traits.Tokens.Finished_Token_Type;
+</pre></td>
+<td>Returns the parent token of the group.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Finish
+ (Grouping : in Token_Group)
+ return Traits.Tokens.Finish_Type;
+</pre></td>
+<td>Returns the finishing position of the group, which is the same as the finish of the parent token.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Is_Root_Ambiguous
+ (Container : in Parse_Graph)
+ return Boolean
+with Pre => Container.Has_Root;
+</pre></td>
+<td>Checks whether the root tokens for a graph are ambiguous. The root is ambiguous if there are multiple
+root tokens, or if there are multiple child groups attached to a root token.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Is_Ambiguous
+ (Container : in Parse_Graph)
+ return Boolean;
+</pre></td>
+<td>Checks if the graph is ambiguous. That is, checks whether there are multiple root tokens or if
+any token in the graph has multiple child groups attached to it.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Ambiguities
+ (Container : in Parse_Graph;
+ Ambiguous_Root : out Boolean)
+ return Traits.Tokens.Finished_Token_Array
+with Post => Is_Sorted (Ambiguities'Result) and
+ No_Duplicates (Ambiguities'Result);
+</pre></td>
+<td>Gives the parent tokens of all ambiguities in the graph.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Isomorphic
+ (Left, Right : in Parse_Graph)
+ return Boolean
+with Pre => Left.Has_Root and Right.Has_Root;
+</pre></td>
+<td>Checks whether the two graphs are isomorphic in structure. This means that the tokens and groups
+are all the same except for any consistent offset in the start and finish values.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Isomorphic_Subgraph
+ (Left_Graph : in Parse_Graph;
+ Left_Position : in Traits.Tokens.Finished_Token_Type;
+ Right_Graph : in Parse_Graph;
+ Right_Position : in Traits.Tokens.Finished_Token_Type)
+ return Boolean
+with Pre => Left_Graph.Contains (Left_Position) and
+ Right_Graph.Contains (Right_Position);
+</pre></td>
+<td>Checks whether the subgraphs formed by the respective positions in each graph and all their connected
+children are isomorphic. This means that all the tokens and groups in those subgraphs are all the same
+except for any consistent offset in the start and finish values. Note that it is possible to check
+for isomorphism between two subgraphs in the same graph.</td>
+ </tr>
+ </table>
+
+
+ </body>
+</html>
+
diff --git a/doc/parser_comb.html b/doc/parser_comb.html
new file mode 100644
index 0000000..c6fd63c
--- /dev/null
+++ b/doc/parser_comb.html
@@ -0,0 +1,589 @@
+
+<!DOCTYPE html>
+
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>Parser Components - Packrat Docs</title>
+ <link href="default.css" rel="stylesheet">
+ </head>
+
+ <body>
+
+
+ <h2>Parser Components</h2>
+
+ <a href="index.html">Return to Contents</a>
+
+
+ <p>Several of the combinators were inspired from Haskell's Parsec library.</p>
+
+ <table>
+ <tr>
+<td><pre>
+generic
+ with function Root
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+package Parse_Parts is
+
+ procedure Parse
+ (Input : in Traits.Element_Array;
+ Result : out Graphs.Parse_Graph);
+
+ procedure Reset;
+
+end Parse_Parts;
+</pre></td>
+<td>The parser that allows for piecewise parsing. It will continue to accept more input until an empty
+input array is supplied, at which point it is assumed that the end of input has been reached. No result
+will be given until end of input.<br>
+<br>
+The <em>Reset</em> procedure returns the parser to a clean state as if it had just been declared.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ with function Root
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+package Parse_Once is
+
+ function Parse
+ (Input : in Traits.Element_Array)
+ return Graphs.Parse_Graph;
+
+ procedure Reset;
+
+end Parse_Once;
+</pre></td>
+<td>Parser that only accepts input all in one go, returning the result after one call of the <em>Parse</em>
+function.<br>
+<br>
+The <em>Reset</em> procedure returns the parser to a clean state as if it had just been declared.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ with function Root
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+package Parse_With is
+
+ function Parse
+ (Input : in With_Input)
+ return Graphs.Parse_Graph;
+
+ procedure Reset;
+
+end Parse_With;
+</pre></td>
+<td>Piecewise parsing, but uses the supplied input function to retrieve further pieces of input as
+needed, until the function return an empty array upon which end of input is assumed.<br>
+<br>
+The <em>Reset</em> procedure returns the parser to a clean state as if it had just been declared.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ Label : in Traits.Label_Enum;
+ with function Combo
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+function Stamp
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Runs the supplied <em>Combo</em> combinator. If the result is successful, generates a node in the
+parse graph with label of <em>Label</em>. Any nodes generated by <em>Combo</em> are made into children of
+the new node. Any non-node input parsed by <em>Combo</em> is made into the value of the new node.<br>
+<br>
+If the <em>Combo</em> combinator is not successful, stores the error result in case a <em>Parser_Error</em>
+needs to be raised.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ Label : in Traits.Label_Enum;
+ with function Combo
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+function Discard
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Operates similar to <em>Stamp</em> but discards any successful result of <em>Combo</em> instead of
+adding it to the parse graph. Any error result is still stored in case of a <em>Parser_Error</em> needing
+to be raised.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ with function Combo
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+function Ignore
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Operates similar to <em>Discard</em> but no error result is stored. Any result of <em>Combo</em> is
+ultimately discarded regardless of success or failure.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+package Redirect is
+
+ procedure Set
+ (Target : in Combinator);
+
+ function Call
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+
+end Redirect;
+</pre></td>
+<td>Use this whenever you need to refer to a combinator that you haven't declared yet in a combinator
+instantiation. This generally happens when there is some form of recursion in the grammar. Instantiate
+<em>Redirect</em>, use <em>Call</em> in the instantiation of other combinators, then set the actual
+target of the redirect with <em>Set</em> before you call the parser. If the redirect is not set when
+the parser is called then a <em>Constraint_Error</em> is raised.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ Params : in Combinator_Array;
+function Sequence
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Attempts to parse all the combinators in <em>Params</em> one after the other. Only succeeds if
+all combinators succeed.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ with function Part_One
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+ with function Part_Two
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+function Sequence_2
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Parses <em>Part_One</em>, then <em>Part_Two</em> directly after. Only succeeds if both succeed. This
+combinator exists because <em>Sequence</em> can have instantiation issues due to access level restrictions.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ Params : in Combinator_Array;
+function Choice
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Parses all the combinators in <em>Params</em> all starting from the current starting point, then combines
+all the results. In this way all possible valid parse choices are taken.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ with function Choice_One
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+ with function Choice_Two
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+function Choice_2
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Parses <em>Choice_One</em> and <em>Choice_Two</em> both starting at the current starting point, then
+combines the results. In other words it takes both possible parse choices. Like <em>Sequence_2</em>, this
+exists because the <em>Choice</em> can have instantiation issues due to access level restrictions.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ with function Param
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+ Number : in Positive;
+function Count
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Parses the supplied <em>Param</em> combinator <em>Number</em> of times sequentially.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ with function Param
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+ Minimum : in Natural := 0;
+function Many
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Parses the supplied <em>Param</em> combinator as many times as it can, one after the other, until it
+fails. If at least <em>Minimum</em> number of parses are successful then the whole result is successful.<br>
+<br>
+The result includes every possible valid number of times that <em>Param</em> could be parsed. For example,
+if <em>Param</em> could be parsed 0-6 times and <em>Minimum</em> is 3, then the result will include cases
+where <em>Param</em> was parsed 3, 4, 5, 6 times.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ with function Param
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+function Followed_By
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Checks whether <em>Param</em> succeeds at the given point in the input and succeeds if <em>Param</em>
+succeeds. Does not actually progress the input, regardless of what <em>Param</em> does.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ with function Param
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+function Not_Followed_By
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Checks whether <em>Param</em> succeeds at the given point in the input and succeeds if <em>Param</em>
+fails. Does not actually progress the input, regardless of what <em>Param</em> does.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ with function Param
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+ with function Test
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+ Minimum : in Natural := 0;
+function Many_Until
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Parses the supplied <em>Param</em> combinator as many times as it can until a point is reached when
+<em>Test</em> would succeed. The overall result succeeds if <em>Param</em> was successfully parsed at least
+<em>Minimum</em> number of times.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ with function Param
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+function Optional
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Combines the result of parsing <em>Param</em> with the result of not parsing it.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ with function Item
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+ with function Separator
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+ Minimum : in Natural := 0;
+function Separate_By
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Parses as many of <em>Item</em> as it can, separated by <em>Separator</em> and requiring a minimum of
+<em>Minimum</em> items parsed. The separators are ignored in the final result. Combines different length
+results in the same way that <em>Many</em> does.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ with function Item
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+ with function Separator
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+ with function Ender
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+ Minimum : in Natural := 0;
+function Separate_End_By
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Works the same way as <em>Separate_By</em> in sequence with <em>Ender</em>. The ender is ignored in
+the final result.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ with function Starter
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+ with function Item
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+ with function Ender
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+function Between
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Parses <em>Starter</em> then <em>Item</em> then <em>Ender</em> in sequence. The results of
+<em>Starter</em> and <em>Ender</em> are discarded.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ with function Test
+ (Item : in Traits.Element_Type)
+ return Boolean;
+function Satisfy
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Parses the next item of input if the supplied <em>Test</em> function succeeds on it.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ with function Test
+ (Item : in Traits.Element_Type)
+ return Boolean;
+ with function Change
+ (From : in Traits.Element_Type)
+ return Traits.Element_Type;
+function Satisfy_With
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Parses the next item of input if the supplied <em>Test</em> function succeeds on it after it has
+been transformed by the <em>Change</em> function. The original unchanged item is what is parsed.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ Item : in Traits.Element_Type;
+function Match
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Parses the next item of input if it matches <em>Item</em>.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ Item : in Traits.Element_Type;
+ with function Change
+ (From : in Traits.Element_Type)
+ return Traits.Element_Type;
+function Match_With
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Parses the next item of input if it matches <em>Item</em> after the input item has been transformed
+by the <em>Change</em> function. The original unchanged item is what is parsed.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ Items : in Traits.Element_Array;
+function Multimatch
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Parses the next <em>Items'Length</em> items of input if they match <em>Items</em>.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ Number : in Positive := 1;
+function Take
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Parses the next <em>Number</em> items of input.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ with function Test
+ (Item : in Traits.Element_Type)
+ return Boolean;
+function Take_While
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Parses items of input as long as the supplied <em>Test</em> function succeeds on them.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ with function Test
+ (Item : in Traits.Element_Type)
+ return Boolean;
+function Take_Until
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Parses items of input until the supplied <em>Test</em> function succeeds on the next item of input.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Empty
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Does not parse any input but returns an empty, yet successful, result.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ with function Combo
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+function Not_Empty
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>Parses the supplied <em>Combo</em> combinator as normal but excludes any empty results.</td>
+ </tr>
+ <tr>
+<td><pre>
+function End_Of_Input
+ (Input : in Traits.Element_Array;
+ Context : in out Parser_Context;
+ Start : in Positive)
+ return Combinator_Result;
+</pre></td>
+<td>A combinator that only succeeds if the end of input has been reached and there is nothing more
+to parse, at which point it will return an empty yet successful result.</td>
+ </tr>
+ </table>
+
+
+ </body>
+</html>
+
diff --git a/doc/quickstart.html b/doc/quickstart.html
new file mode 100644
index 0000000..b525f8f
--- /dev/null
+++ b/doc/quickstart.html
@@ -0,0 +1,65 @@
+
+<!DOCTYPE html>
+
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>Quickstart Guide - Packrat Docs</title>
+ <link href="default.css" rel="stylesheet">
+ </head>
+
+ <body>
+
+
+ <h2>Quickstart Guide</h2>
+
+ <a href="index.html">Return to Contents</a>
+
+
+ <h4>Lexing and Parsing</h4>
+
+ <p>The package that you will need is <em>Packrat.Standard</em>. If you are parsing
+ ordinary strings then <em>Packrat.Utilities</em> may also be useful.<br>
+ <br>
+ Define enumeration types for all the lexer token labels and parse graph node labels
+ you need, then use them to instantiate <em>Packrat.Standard</em>.<br>
+ <br>
+ Instantiate subprograms from the nested <em>Lexers</em> package to create your lexer,
+ and subprograms from the nested <em>Parsers</em> package to create your parser.<br>
+ <br>
+ Take special care when using any redirects from <em>Parsers</em>. They are used to
+ allow for self-referential instantiation of parser combinators and must be set properly
+ before using any parsers built with them. Otherwise an exception will be raised.<br>
+ <br>
+ Feed your input through the lexer, then the results of that through the parser to
+ obtain a parse graph.<br>
+ <br>
+ Use subprograms from the nested <em>Parse_Graphs</em> package to inspect and manipulate
+ the resulting graph.
+ </p>
+
+
+ <h4>Parsing Only</h4>
+
+ <p>The package that you will need is <em>Packrat.No_Lex</em>. If you are parsing
+ ordinary strings then <em>Packrat.Utilities</em> may also be useful.<br>
+ <br>
+ Define an enumeration type for all the parse graph node labels you need, then use it
+ to instantiate <em>Packrat.No_Lex</em>.<br>
+ <br>
+ Instantiate subprograms from the nested <em>Parsers</em> package to create your parser.<br>
+ <br>
+ Take special care when using any redirects. They are used to allow for self-referential
+ instantiation of parser combinators and must be set properly before using any parsers
+ built with them. Otherwise an exception will be raised.<br>
+ <br>
+ Feed your input through the parser to obtain a parse graph.<br>
+ <br>
+ Use subprograms from the nested <em>Parse_Graphs</em> package to inspect and manipulate
+ the resulting graph.
+ </p>
+
+
+ </body>
+</html>
+
diff --git a/doc/src_overview.html b/doc/src_overview.html
new file mode 100644
index 0000000..a0f4341
--- /dev/null
+++ b/doc/src_overview.html
@@ -0,0 +1,74 @@
+
+<!DOCTYPE html>
+
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>/src Overview - Packrat Docs</title>
+ <link href="default.css" rel="stylesheet">
+ </head>
+
+ <body>
+
+
+ <h2>/src Overview</h2>
+
+ <a href="index.html">Return to Contents</a>
+
+
+ <table>
+ <tr>
+ <td>packrat.adb<br>packrat.ads</td>
+ <td>The main Packrat package.</td>
+ </tr>
+ <tr>
+ <td>packrat-errors.adb<br>packrat-errors.ads<br>packrat-errors-parts.adb</td>
+ <td>Error handling functionality. Use this if you need to handle <em>Lexer_Error</em> or
+ <em>Parser_Error</em> exception messages.</td>
+ </tr>
+ <tr>
+ <td>packrat-lexers.adb<br>packrat-lexers.ads</td>
+ <td>Scanner functions, lexer components and combinators.</td>
+ </tr>
+ <tr>
+ <td>packrat-no_lex.ads</td>
+ <td>Convenience package to allow use of parser combinators and related functionality without
+ having to <em>with</em> and instantiate a long list of packages.</td>
+ </tr>
+ <tr>
+ <td>packrat-parse_graphs.adb<br>packrat-parse_graphs.ads</td>
+ <td>The data structure that parse results end up in. Externally it gives the appearance
+ of a directed acyclic graph with several root nodes. Internally a lot of deduplication is
+ done by labeling the nodes with starting points and the edges with finishing points then
+ keeping track of what edges are valid to go down given the current position.</td>
+ </tr>
+ <tr>
+ <td>packrat-parsers.adb<br>packrat-parsers.ads</td>
+ <td>Parser functions and combinators. More flexible and extensive than <em>Packrat.Lexers</em>.</td>
+ </tr>
+ <tr>
+ <td>packrat-standard.ads</td>
+ <td>Convenience package to allow use of both lexer and parser combinators as well as related
+ functionality without having to <em>with</em> and instantiate a long list of packages.</td>
+ </tr>
+ <tr>
+ <td>packrat-tokens.adb<br>packrat-tokens.ads</td>
+ <td>Handles the individual tokens that lexers give as output and that form the nodes
+ of a parse graph.</td>
+ </tr>
+ <tr>
+ <td>packrat-traits.adb<br>packrat-traits.ads</td>
+ <td>Convenience package to collect the various other things necessary to instantiate
+ a lot of the other packages.</td>
+ </tr>
+ <tr>
+ <td>packrat-utilities.adb<br>packrat-utilities.ads</td>
+ <td>Convenience predicates for use with <em>Satisfy</em> combinators and the like when
+ lexing or parsing standard strings.</td>
+ </tr>
+ </table>
+
+
+ </body>
+</html>
+
diff --git a/doc/test_overview.html b/doc/test_overview.html
new file mode 100644
index 0000000..a5c7856
--- /dev/null
+++ b/doc/test_overview.html
@@ -0,0 +1,51 @@
+
+<!DOCTYPE html>
+
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>/test Overview - Packrat Docs</title>
+ <link href="default.css" rel="stylesheet">
+ </head>
+
+ <body>
+
+
+ <h2>/test Overview</h2>
+
+ <a href="index.html">Return to Contents</a>
+
+
+ <p><strong>CAUTION:</strong> These files are used for unit testing the library and can
+ undergo changes at any time.</p>
+
+ <table>
+ <tr>
+ <td>packrat-lexers-debug.adb<br>packrat-lexers-debug.ads<br>
+ packrat-parsers-debug.adb<br>packrat-parsers-debug.ads</td>
+ <td>Extensions to the <em>Packrat.Lexers</em> and <em>Packrat.Parsers</em> package to expose
+ some of the functionality for unit testing.</td>
+ </tr>
+ <tr>
+ <td>rat_tests.ads</td>
+ <td>Sets up some common packages needed for all the unit tests.</td>
+ </tr>
+ <tr>
+ <td>rat_tests-errors.adb<br>rat_tests-errors.ads<br>
+ rat_tests-lexers.adb<br>rat_tests-lexers.ads<br>
+ rat_tests-parse_graphs.adb<br>rat_tests-parse_graphs.ads<br>
+ rat_tests-parsers.adb<br>rat_tests-parsers.ads<br>
+ rat_tests-tokens.adb<br>rat_tests-tokens.ads<br>
+ rat_tests-utilities.adb<br>rat_tests-utilities.ads</td>
+ <td>Unit tests for the various packages in Packrat.</td>
+ </tr>
+ <tr>
+ <td>test_main.adb</td>
+ <td>The main program that runs all the unit tests.</td>
+ </tr>
+ </table>
+
+
+ </body>
+</html>
+
diff --git a/doc/util_func.html b/doc/util_func.html
new file mode 100644
index 0000000..13d7c21
--- /dev/null
+++ b/doc/util_func.html
@@ -0,0 +1,148 @@
+
+<!DOCTYPE html>
+
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>Utility Functions - Packrat Docs</title>
+ <link href="default.css" rel="stylesheet">
+ </head>
+
+ <body>
+
+
+ <h2>Utility Functions</h2>
+
+ <a href="index.html">Return to Contents</a>
+
+
+ <p>These are intended as helper functions for use with <em>Satisfy</em> combinators and the like
+ when parsing ordinary strings.</p>
+
+ <table>
+ <tr>
+<td><pre>
+generic
+ Set : in Ada.Strings.Maps.Character_Set;
+function In_Set
+ (Element : in Character)
+ return Boolean;
+</pre></td>
+<td>Tests whether a <em>Character</em> is present within the given <em>Character_Set</em>.</td>
+ </tr>
+ <tr>
+<td><pre>
+generic
+ Set : in Ada.Strings.Maps.Character_Set;
+function Not_In_Set
+ (Element : in Character)
+ return Boolean;
+</pre></td>
+<td>Tests whether a <em>Character</em> is not present within the given <em>Character_Set</em>.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Is_Digit
+ (Char : in Character)
+ return Boolean;
+</pre></td>
+<td>Tests whether a <em>Character</em> is one of the digits 0 through 9.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Is_Hex
+ (Char : in Character)
+ return Boolean;
+</pre></td>
+<td>Tests whether a <em>Character</em> is one of the digits 0 through 9 or one of the letters
+A through F, case insensitive.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Is_Letter
+ (Char : in Character)
+ return Boolean;
+</pre></td>
+<td>Tests whether a <em>Character</em> is one of the letters A through Z, case insensitive.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Is_Alphanumeric
+ (Char : in Character)
+ return Boolean;
+</pre></td>
+<td>Tests whether a <em>Character</em> is one of the digits 0 through 9 or one of the letters
+A through Z, case insensitive.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Is_Punctuation
+ (Char : in Character)
+ return Boolean;
+</pre></td>
+<td>Tests whether a <em>Character</em> is one of the punctuation characters <em>! &quot; # $ %
+&amp; &apos; ( ) * + , - . / : ; &lt; = &gt; ? @ [ \ ] ^ _ ` { | } ~</em> which annoyingly
+occupies several disjoint sections of ASCII.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Is_ASCII
+ (Char : in Character)
+ return Boolean;
+</pre></td>
+<td>Tests whether a <em>Character</em> is in the lower half of the ASCII character set.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Is_Extended_ASCII
+ (Char : in Character)
+ return Boolean;
+</pre></td>
+<td>Tests whether a <em>Character</em> is in the upper half of the ASCII character set.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Is_Space
+ (Char : in Character)
+ return Boolean;
+</pre></td>
+<td>Tests whether a <em>Character</em> is a space.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Is_Linespace
+ (Char : in Character)
+ return Boolean;
+</pre></td>
+<td>Tests whether a <em>Character</em> is a space or horizontal tab.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Is_End_Of_Line
+ (Char : in Character)
+ return Boolean;
+</pre></td>
+<td>Tests whether a <em>Character</em> is a linefeed or carriage return.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Is_Whitespace
+ (Char : in Character)
+ return Boolean;
+</pre></td>
+<td>Tests whether a <em>Character</em> is a space, horizontal tab, linefeed, or carriage return.</td>
+ </tr>
+ <tr>
+<td><pre>
+function Not_Whitespace
+ (Char : in Character)
+ return Boolean;
+</pre></td>
+<td>Tests whether a <em>Character</em> is not a space, horizontal tab, linefeed, or carriage return.</td>
+ </tr>
+ </table>
+
+
+ </body>
+</html>
+