diff options
Diffstat (limited to 'doc')
-rw-r--r-- | doc/blank_template.html | 21 | ||||
-rw-r--r-- | doc/credits.html | 30 | ||||
-rw-r--r-- | doc/default.css | 29 | ||||
-rw-r--r-- | doc/depends.html | 29 | ||||
-rw-r--r-- | doc/errors.html | 33 | ||||
-rw-r--r-- | doc/example_overview.html | 40 | ||||
-rw-r--r-- | doc/features.html | 46 | ||||
-rw-r--r-- | doc/index.html | 48 | ||||
-rw-r--r-- | doc/lexer_comb.html | 347 | ||||
-rw-r--r-- | doc/license.html | 53 | ||||
-rw-r--r-- | doc/limits.html | 49 | ||||
-rw-r--r-- | doc/parse_graph_op.html | 424 | ||||
-rw-r--r-- | doc/parser_comb.html | 589 | ||||
-rw-r--r-- | doc/quickstart.html | 65 | ||||
-rw-r--r-- | doc/src_overview.html | 74 | ||||
-rw-r--r-- | doc/test_overview.html | 51 | ||||
-rw-r--r-- | doc/util_func.html | 148 |
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>! " # $ % +& ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~</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> + |