Parsnip
parsing library
Loading...
Searching...
No Matches
parsnip_command.h
Go to the documentation of this file.
1
9
10#pragma once
11
12#include <string>
13#include <memory>
14#include <vector>
15#include <unordered_map>
16#include <exception>
17#include <functional>
18
19#include "parsnip.h"
20
21namespace Parsnip {
23 class NumberOutOfRange : public Exception {
24 public:
25 inline NumberOutOfRange() : Exception ("Value out of range"){};
26 inline NumberOutOfRange (const std::string &value) : Exception ("Value out of range", value){};
27 };
28
30 class NotNumeric : public Exception {
31 public:
32 inline NotNumeric() : Exception ("Not a number"){};
33 inline NotNumeric (const std::string &value) : Exception ("Not a number", value){};
34 };
35
37 class InvalidValue : public Exception {
38 public:
39 inline InvalidValue() : Exception ("Invalid value"){};
40 inline InvalidValue (const std::string &value) : Exception ("Invalid value", value){};
41 };
42
45 public:
46 inline IncompleteCommand() : Exception ("Incomplete command"){};
47 inline IncompleteCommand (const std::string &value) : Exception ("Incomplete command", value){};
48 };
49
51 class RunOnCommand : public Exception {
52 public:
53 inline RunOnCommand() : Exception ("Run-on command"){};
54 inline RunOnCommand (const std::string &value) : Exception ("Run-on command", value){};
55 };
56
58 class DuplicateOption : public Exception {
59 public:
60 inline DuplicateOption() : Exception ("Option respecified: "){};
61 inline DuplicateOption (const std::string &value) : Exception ("Option respecified", value){};
62 };
63
65 class NoSchemaDefined : public Exception {
66 public:
67 inline NoSchemaDefined() : Exception ("No Schema defined: "){};
68 inline NoSchemaDefined (std::string command) : Exception ("No schema defined", command){};
69 inline NoSchemaDefined (const int command) : Exception ("No schema defined", std::to_string (command)){};
70 };
71
72 extern const std::string EmptyString;
73
77 void operator() (class Evaluator *free_me);
78 };
79 using EvaluatorRef = std::unique_ptr<class Evaluator, EvaluatorDeleter>;
80
83 friend class OptionEvaluator;
84 friend class Schema;
85 public:
86 EvaluatorRef evaluator;
87
88 public:
89 // Structure for defining new option patterns.
90 using Definitions = std::vector<const char *>;
91
92 OptionParser() = default;
93 OptionParser (const Definitions &defs, class Parser * = nullptr);
94 void addOptions (const Definitions &defs, class Parser * = nullptr);
95 bool operator== (const OptionParser &) const;
96 };
97 using OptionParserRef = std::shared_ptr<OptionParser>;
98
100 class Parser {
101 friend class OptionEvaluator;
102 friend class SchemaSet;
103 private:
104 EvaluatorRef evaluator;
105 using OptionParsers = std::unordered_map<std::string, OptionParserRef>;
106 OptionParsers option_parsers;
107
108 public:
109 using CommandId = int;
110 using StringType = std::string;
111
112 // Structure for defining new parser patterns.
113 struct Definition {
114 CommandId command_id;
115 const char *statement;
116 };
117 using Definitions = std::vector<Definition>;
118
119 // Structure for evaluation results.
126
127 Parser() = default;
128 Parser (const Definitions &defs);
129 virtual ~Parser() = default;
130 void addOptionParser (const std::string &name, const OptionParserRef &add);
131 void addStatements (const Definitions &defs);
132 Result evaluate (const StringType &command) const;
133 bool operator== (const Parser &) const;
134 inline bool operator!= (const Parser &other) const {
135 return !(*this == other);
136 }
137 };
138 using ParserRef = std::shared_ptr<Parser>;
139
140 template <typename ReturnType, typename ContextType>
142 public:
143 virtual ReturnType interpret (Parser::CommandId command_id, const Parsnip::Data &parameters, ContextType context) = 0;
144 };
145
146 // A parser that includes dispatching capabilities.
147 template <typename DispatchReturnType, typename DispatchContextType>
149 protected:
150 const ParserRef parser;
151 public:
152 using ReturnType = DispatchReturnType;
153 using ContextType = DispatchContextType;
154 using ExecutorType = std::function <ReturnType (Parser::CommandId, const Parsnip::Data &, ContextType)>;
155 private:
156 std::unordered_map <Parser::CommandId, ExecutorType> handlers;
157#ifndef NDEBUG
158 int parser_number = 0;
159 std::unordered_map <Parser::CommandId, int> mapping_check;
160#endif
161 public:
162 Dispatcher (const ParserRef &parser);
163 void addHandler (const Parser::Definitions &defs, const ExecutorType &handler);
164 inline void addHandler (const Parser::Definitions &defs, Interpreter<DispatchReturnType, DispatchContextType> *interpreter);
165 void addStatements (const Parser::Definitions &defs, ExecutorType handler);
166 ReturnType operator () (Parser::CommandId command_id, const Parsnip::Data &parameters, DispatchContextType context) const;
167 ReturnType operator () (Parser::StringType command, ContextType context) const;
168 };
169
171 class SchemaSet {
172 public:
173 using CommandId = int;
174 using CommandSchemas = std::unordered_map <CommandId, SchemaBaseRef>;
175 using OptionSchemas = Schema::OptionSchemas;
176 using Dependencies = Schema::Dependencies;
177 private:
179 CommandSchemas schemas;
180 void integrateSchema (const int, const class DictionarySchema &);
181 SchemaBaseRef &getSchemaForCommand (CommandId command_id);
182 const SchemaBaseRef &getSchemaForCommand (CommandId command_id) const;
183
184 public:
186 OptionSchemas option_schemas;
187 public:
188 SchemaSet (const class Parser &from);
189 void validate (const CommandId, const Data &) const;
190 std::ostream &dump (const std::string &intro, const CommandId command_id, std::ostream &target = std::clog) const;
191
192 void addMember (const CommandId, const char *name, const SchemaBase &schema, bool mandatory = false,
193 const Dependencies &dependencies = Schema::NoDependencies);
194 void addMember (const char *name, const SchemaBase &schema, bool mandatory = false,
195 const Dependencies &dependencies = Schema::NoDependencies);
196 void replaceMember (const CommandId, const char *name, const SchemaBase &schema);
197 void removeMember (const CommandId, const char *name);
198 };
199 using SchemaSetRef = std::shared_ptr <SchemaSet>;
200
201
202 /*
203 *
204 * TEMPLATE IMPLEMENTATIONS
205 *
206 */
207
208 /*
209 * Dispatcher
210 */
211
214 template <typename DispatchReturnType, typename DispatchContextType>
216 : parser (par) {
217 }
218
224 template <typename DispatchReturnType, typename DispatchContextType>
225 void Dispatcher<DispatchReturnType, DispatchContextType>::addHandler (const Parser::Definitions &defs, const ExecutorType &handler) {
226#ifndef NDEBUG
227 parser_number++;
228#endif
229 for (auto &it : defs) {
230#ifndef NDEBUG
231 if (mapping_check [it.command_id]) {
232 assert (mapping_check [it.command_id] == parser_number);
233 } else {
234 mapping_check [it.command_id] = parser_number;
235 }
236#endif
237 handlers [it.command_id] = handler;
238 }
239 }
240
241
246 template <typename DispatchReturnType, typename DispatchContextType>
248 Interpreter <DispatchReturnType, DispatchContextType> *interpreter) {
250 interpreter, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3) };
251 addHandler (defs, handler);
252 }
253
257 template <typename DispatchReturnType, typename DispatchContextType>
258 void Dispatcher<DispatchReturnType, DispatchContextType>::addStatements (const Parsnip::Parser::Definitions &defs, ExecutorType handler) {
259 parser->addStatements (defs);
260 addHandler (defs, handler);
261 }
262
268 template <typename DispatchReturnType, typename DispatchContextType>
269 DispatchReturnType Dispatcher<DispatchReturnType, DispatchContextType>::operator () (Parser::CommandId command_id,
270 const Parsnip::Data &parameters,
271 ContextType context) const {
272 return handlers.at (command_id) (command_id, parameters, context);
273 }
274
279 template <typename DispatchReturnType, typename DispatchContextType>
280 DispatchReturnType Dispatcher<DispatchReturnType, DispatchContextType>::operator () (Parser::StringType command,
281 ContextType context) const {
282 Parser::Result result = parser->evaluate (command);
283 return (*this) (result.command_id, result.parameters, context);
284 }
285
286} // namespace Parsnip
Generic data type.
Definition parsnip.h:81
static const struct Parsnip::Data::dictionary_t Dictionary
Dictionary flag type/value.
Schema component for validating dictionaries.
Definition parsnip_schema.h:307
Definition parsnip_command.h:148
void addStatements(const Parser::Definitions &defs, ExecutorType handler)
Add statements to the parser and register their related handler.
Definition parsnip_command.h:258
void addHandler(const Parser::Definitions &defs, const ExecutorType &handler)
Register handlers with the dispatcher.
Definition parsnip_command.h:225
ReturnType operator()(Parser::CommandId command_id, const Parsnip::Data &parameters, DispatchContextType context) const
Dispatch a command to the executor/handler function.
Definition parsnip_command.h:269
Dispatcher(const ParserRef &parser)
Construct a dispatcher.
Definition parsnip_command.h:215
An option was supplied twice to an iterating option parser.
Definition parsnip_command.h:58
Evaluator base class.
Definition parsnip_evaluate.h:30
Class representing issues related to serialization & parsing.
Definition parsnip.h:41
More tokens were expected.
Definition parsnip_command.h:44
Definition parsnip_command.h:141
A token encountered was not one of the expected keywords.
Definition parsnip_command.h:37
A schema is not defined for a certain command ID.
Definition parsnip_command.h:65
Not numeric: A command pattern specified a number, but the token was not valid number.
Definition parsnip_command.h:30
NumberOutOfRange: The number was outside the range defined in the command pattern.
Definition parsnip_command.h:23
Evaluate remainder with a different parser.
Definition parsnip_evaluate.h:315
A class for parsing command line options (name-value pairs, for instance).
Definition parsnip_command.h:82
void addOptions(const Definitions &defs, class Parser *=nullptr)
Register new option patterns.
Definition parsnip_command.cpp:454
A class for parsing command lines.
Definition parsnip_command.h:100
Result evaluate(const StringType &command) const
Evaluate a command.
Definition parsnip_command.cpp:424
void addStatements(const Definitions &defs)
Add statements to the parser.
Definition parsnip_command.cpp:399
bool operator==(const Parser &) const
Check if a parser is identical to another parser.
Definition parsnip_command.cpp:435
void addOptionParser(const std::string &name, const OptionParserRef &add)
Register an options parser for use.
Definition parsnip_command.cpp:415
There were extra tokens at the end of the command pattern.
Definition parsnip_command.h:51
Definition parsnip_schema.h:28
Smart pointer for schemas, with unusual ability to be copied.
Definition parsnip.h:601
Schema for one JSON object.
Definition parsnip.h:612
A schema built to validate JSON messages based on command line patterns.
Definition parsnip_command.h:171
void addMember(const CommandId, const char *name, const SchemaBase &schema, bool mandatory=false, const Dependencies &dependencies=Schema::NoDependencies)
Modify a schema by adding a new dictionary member.
Definition parsnip_schema.cpp:1321
std::ostream & dump(const std::string &intro, const CommandId command_id, std::ostream &target=std::clog) const
Dump the schema in human-readable format.
Definition parsnip_schema.cpp:1307
void removeMember(const CommandId, const char *name)
Modify a schema by removing a dictionary member.
Definition parsnip_schema.cpp:1356
void validate(const CommandId, const Data &) const
Validate data against a command's schema.
Definition parsnip_schema.cpp:1299
OptionSchemas option_schemas
Schemas for each of the option parsers.
Definition parsnip_command.h:186
void replaceMember(const CommandId, const char *name, const SchemaBase &schema)
Modify a schema by replacing dictionary member.
Definition parsnip_schema.cpp:1349
Serialization and parsing library.
Definition parsnip.h:38
Parsnip serialization.
This does what std::default_delete would do, but is required since we haven't defined Evaluator yet.
Definition parsnip_command.h:76
Definition parsnip_command.h:113
Definition parsnip_command.h:120
CommandId command_id
< ID of command pattern that was matched.
Definition parsnip_command.h:122
Parsnip::Data parameters
Parameters collected from the command line.
Definition parsnip_command.h:124