|
| Data | parse_json (std::istream &from, bool check_termination) |
| | Parse a stream as JSON data. More...
|
| |
| Data | parse_json (const std::string &from) |
| | Parse a string as a JSON stream. More...
|
| |
| std::ostream & | operator<< (std::ostream &out, const Parsnip::Data &data) |
| |
| static void | options_evaluator_convert (EvaluatorRef &evaluator) |
| | Convert a terminator evaluator to an end-of-options evaluator. More...
|
| |
| void | parser_assert (bool requirement, const char *explanation) |
| |
| void | parser_assert (bool requirement, const char *explanation, const std::string &detail) |
| |
| template<class DesiredEvaluator > |
| static DesiredEvaluator * | uptype_construct (EvaluatorRef &parser, bool *existed=nullptr) |
| | If an evaluator isn't constructed, create it. More...
|
| |
| static char | hexdigit (int digit) |
| | Helper function: Retrieve a hexadecimal digit. More...
|
| |
| static void | do_indent (std::ostream &target, int amount) |
| | Generate some indentation. More...
|
| |
| static void | do_newline (std::ostream &target, int amount) |
| | Write a newline to a stream. More...
|
| |
| static void | json_encode_string (std::ostream &target, const std::string &value) |
| | Write a string to a stream, literal-encoding special characters. More...
|
| |
| std::istream::int_type | next_non_whitespace (InputStream &from) |
| | Read from a stream until a non-whitespace character is found. More...
|
| |
| static void | require_character (InputStream &from, std::istream::int_type expect) |
| | Verify the next non-whitespace character in a stream is what's expected. More...
|
| |
| static int | parse_hex_digits (InputStream &from, int count) |
| | Parse hexadecimal digits from a stream. More...
|
| |
| static const std::string | parse_json_string (InputStream &from, const char quote) |
| | Parse a string out of a JSON stream. More...
|
| |
| static Data | parse_json_inline_text (InputStream &from) |
| | Parse a keyword out of a JSON string. More...
|
| |
| static Data | parse_json_inline_value (InputStream &from) |
| | Parse a numeric value in a JSON stream. More...
|
| |
| static Data | parse_json_element (InputStream &from) |
| | Extract data from a JSON stream. More...
|
| |
| static Data | parse_json_dictionary (InputStream &from) |
| | Parse a JSON dictionary from a stream. More...
|
| |
| static Data | parse_json_list (InputStream &from) |
| | Parse a list from a JSON stream. More...
|
| |
| static SchemaBase * | construct_schema (const Parsnip::Data &schema_spec) |
| | Assemble a schema from a specification. More...
|
| |
| static DictionarySchema * | asDictionary (const SchemaBaseRef &schema) |
| | Verify the schema is the dictionary we expect, and return it typecast as such. More...
|
| |
Serialization and parsing library.
Classes providing evaluation for command lines.
The Parser class accepts arrays of strings/command ID combinations (Parser::Definition). From these, it builds a parse tree against which it can subsequently evaluate commands, identifying commands by ID and providing a dictionary the commands parameters. Multiple definition sets can be added to a single parser.
Lexically, commands are split at spaces, unless quoted. Single or double quotes may be used, but must match. Open quotes are only identified at the start of a word, close quotes only at the end of a word. Quotes may be doubled within a quoted span to insert a literal quote.
Statement patterns can be composed of:
Literal:
keyword – a bare word for matching command pattern. Alternation:
<name:one|two> – accepts any 1 of the required words in that position Optional:
[name:optional] – accepts an optional word in the current position
[name:four|five] – accepts 0 or 1 optional words in the current position
[word] – accepts an optional word, named itself, in the current position Fillable fields:
{name} – accepts any string/number/value in that position
{#name:3-5} – Accepts numeric range in that position. See range note below.
{name...} – accepts the remainder of the command line, raw/unparsed as a single string. Optional remainder fillable fields (only at end of command):
[{name}] – accepts a single optional value; may be string or numeric fillable.
[{name}] ... – accepts 0 or more optional values; may be string or numeric fillable.
[{name...}] – accepts the raw/unparsed remainder, if present. Always string.
Names:
- Must not vary within consistent parsing patterns
- May be reused in different branches; use with care.
Alternation and optional patterns may contain an arbitrary number of possible keywords, Storage behavior:
- Numeric values with ranges are evaluted and stored in the dictionary as their proper type.
- Alternation options are stored as strings.
- Optional keywords are stored as strings when present, otherwise omitted.
- Remainders (parsed form, optional or not) return an array of the appropriate type. No values returns an empty array, rather than the array being omitted.
Ranges:
- If either min or max in range have a decimal point, values are treated as doubles. Otherwise, they are considered integers.
- For integers, if either min or max has a leading zero, it enables radix detection: 0 -> octal, 0x -> hex, otherwise decimal.
- If neither max nor min has a leading 0, only base 10 is accepted.
- Reals are always evaluated base 10.
Examples:
{ CREATE_USER, "create <rank:admin|guest|user> {username} {password}" }
-- Recognizes the 3 types of users and requires username & password parameter, nothing more.
{ CREATE_USER_EXTENDED, "create <rank:admin|guest|user> {username} {password} [{additional}] ..." }
-- Recognizes the 3 types of users and requires username, password, & at least 1 additional parameter.
{ CREATE_USER_OPTIONAL_EXTENDED, "create <rank:admin|guest|user> {user} {password} ... }
-- Recognizes the 3 types of users, requires username and password, allows additional parameters.
This definition is incompatible with CREATE_USER above--the parser would error when adding this
definition. (There is no way to delineate that command and this command with 0 parameters.)
A completely different approach to the above would be:
{ CREATE_ADMIN_USER, "create admin {username} {password} ..." },
{ CREATE_STANDARD_USER, "create standard {username} {password} ..." },
{ CREATE_GUEST_USER, "create guest {username} {password} ..." }
-- Returns different values for the different user types, so you can determine that
from the command's enumeration instead of having to further parse. As written, these
would each allow additional optional parameters beyond username and password.
Since the parse tree is assumed to be hard-coded in your application, this module simply throws a runtime_error it finds problems in the parse definitions.
Options parsing
An option parser may be used inline or as a remainder handler:
- {name:parser} – accepts one matching sequence in that position
- {name:parser} ... – accepts 0 or more trailing sequences
The option parser must be predefined and registered with the containing Parser prior to adding statements that reference it. Values from within the option parser sequences are stored in a dictionary named name.
- It is an error to specify the same option twice.
- Remainder fill-ins are allowed.
If the parser name in the fill-in referencing it is written as <name>, the first keyword of each option is are used to select the option parser.
Example: {options:<my_options>}
This allows optionals before the option parser, or multiple parallel option parsers. Only one option parser will be used at a time (though an optional non-iterating option parsing could precede a final iterating one).