we need an autodiff library at some point (or we need to roll our own but I do not think that makes sense). CppAD is well tested and header only and easy to include. It is also Liscene compatible with GPL v3.0. Here we bring it in as a dependency
390 lines
9.3 KiB
C++
390 lines
9.3 KiB
C++
# ifndef CPPAD_LOCAL_GRAPH_JSON_LEXER_HPP
|
|
# define CPPAD_LOCAL_GRAPH_JSON_LEXER_HPP
|
|
/* --------------------------------------------------------------------------
|
|
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-19 Bradley M. Bell
|
|
|
|
CppAD is distributed under the terms of the
|
|
Eclipse Public License Version 2.0.
|
|
|
|
This Source Code may also be made available under the following
|
|
Secondary License when the conditions for such availability set forth
|
|
in the Eclipse Public License, Version 2.0 are satisfied:
|
|
GNU General Public License, Version 2.0 or later.
|
|
-------------------------------------------------------------------------- */
|
|
|
|
# include <string>
|
|
# include <cppad/core/cppad_assert.hpp>
|
|
|
|
// BEGIN_NAMESPACE_CPPAD_LOCAL_GRAPH
|
|
namespace CppAD { namespace local { namespace graph {
|
|
|
|
// ===========================================================================
|
|
class json_lexer {
|
|
// ===========================================================================
|
|
|
|
/*
|
|
-------------------------------------------------------------------------------
|
|
$begin json_lexer_member_data$$
|
|
$spell
|
|
json
|
|
lexer
|
|
$$
|
|
|
|
$section json lexer: Private Data$$
|
|
|
|
$head graph_$$
|
|
The $cref json_ad_graph$$.
|
|
|
|
$head index_$$
|
|
is the index in the graph for the current character.
|
|
If a token is returned, this corresponds to the last character
|
|
it the token.
|
|
|
|
$head line_number_$$
|
|
line number in the graph for the current character
|
|
|
|
$head char_number_$$
|
|
character number in the graph for the current character
|
|
|
|
$head token_$$
|
|
used to return tokens.
|
|
|
|
$head function_name_$$
|
|
is the function name for this graph.
|
|
This is initialized as empty,
|
|
should be set as soon as it is parsed,
|
|
and is used for error reporting.
|
|
|
|
$head token$$
|
|
returns current value of $code token_$$.
|
|
|
|
$head line_number$$
|
|
returns current value of $code line_number_$$
|
|
(which corresponds to last character in the token).
|
|
|
|
$head char_number$$
|
|
returns current value of $code char_number_$$.
|
|
(which corresponds to last character in the token).
|
|
|
|
$head set_function_name$$
|
|
sets the value of $code function_name_$$.
|
|
|
|
$head Source Code$$
|
|
$srccode%hpp% */
|
|
private:
|
|
const std::string& json_;
|
|
size_t index_;
|
|
size_t line_number_;
|
|
size_t char_number_;
|
|
std::string token_;
|
|
std::string function_name_;
|
|
public:
|
|
const std::string& token(void) const;
|
|
size_t line_number(void) const;
|
|
size_t char_number(void) const;
|
|
void set_function_name(const std::string& function_name);
|
|
/* %$$
|
|
$end
|
|
-------------------------------------------------------------------------------
|
|
$begin json_lexer_report_error$$
|
|
$spell
|
|
json
|
|
lexer
|
|
CppAD
|
|
$$
|
|
|
|
$section json lexer: Report an Error$$
|
|
|
|
$head Syntax$$
|
|
$codei%
|
|
%json_lexer%.report_error(%expected%, %found%)
|
|
%$$
|
|
|
|
$head json_lexer$$
|
|
is a $code local::graph::json_lexer$$ object.
|
|
|
|
$head expected$$
|
|
is the token that is expected.
|
|
|
|
$head found$$
|
|
is the token or text that was found.
|
|
|
|
$head Report$$
|
|
The current CppAD $cref ErrorHandler$$ is used to report
|
|
an error parsing this Json AD graph.
|
|
|
|
$head Prototype$$
|
|
$srccode%hpp% */
|
|
public:
|
|
void report_error(const std::string& expected, const std::string& found);
|
|
/* %$$
|
|
$end
|
|
-------------------------------------------------------------------------------
|
|
$begin json_lexer_next_index$$
|
|
$spell
|
|
json
|
|
lexer
|
|
$$
|
|
|
|
$section json lexer: Advance Index by One$$
|
|
|
|
$head Syntax$$
|
|
$codei%
|
|
%json_lexer%.next_index()
|
|
%$$
|
|
|
|
$head json_lexer$$
|
|
is a $code local::graph::json_lexer$$ object.
|
|
|
|
$head index_$$
|
|
The input value of $code index_$$ is increased by one.
|
|
It is an error to call this routine when the input value
|
|
of $code index_$$ is greater than or equal $code json_.size()$$.
|
|
|
|
$head line_number_$$
|
|
If the previous character, before the call, was a new line,
|
|
$code line_number_$$ is increased by one.
|
|
|
|
$head char_number_$$
|
|
If the previous character, before the call, was a new line,
|
|
$code char_number$$ is set to one.
|
|
Otherwise, $code char_number_$$ is increased by one.
|
|
|
|
$head Prototype$$
|
|
$srccode%hpp% */
|
|
private:
|
|
void next_index(void);
|
|
/* %$$
|
|
$end
|
|
-------------------------------------------------------------------------------
|
|
$begin json_lexer_skip_white_space$$
|
|
$spell
|
|
json
|
|
lexer
|
|
$$
|
|
|
|
$section json lexer: Skip White Space That Separates Tokens$$
|
|
|
|
$head Syntax$$
|
|
$codei%
|
|
%json_lexer%.skip_white_space()
|
|
%$$
|
|
|
|
$head json_lexer$$
|
|
is a json lexer object.
|
|
|
|
$head Discussion$$
|
|
This member functions is used to increase $code index_$$ until either
|
|
a non-white space character is found or $code index_$$ is equal
|
|
to $code json_.size()$$.
|
|
|
|
$head Prototype$$
|
|
$srccode%hpp% */
|
|
private:
|
|
void skip_white_space(void);
|
|
/* %$$
|
|
$end
|
|
-------------------------------------------------------------------------------
|
|
$begin json_lexer_constructor$$
|
|
$spell
|
|
json
|
|
lexer
|
|
enum
|
|
op
|
|
arg
|
|
$$
|
|
|
|
$section json lexer: Constructor$$
|
|
|
|
$head Syntax$$
|
|
$codei%
|
|
local::graph::lexer %json_lexer%(%json%)
|
|
%$$
|
|
|
|
$head json$$
|
|
The argument $icode json$$ is an $cref json_ad_graph$$
|
|
and it is assumed that $icode json$$ does not change
|
|
for as long as $icode json_lexer$$ exists.
|
|
|
|
$head Initialization$$
|
|
The current token, index, line number, and character number
|
|
are set to the first non white space character in $code json_$$.
|
|
If this is not a left brace character $code '{'$$,
|
|
the error is reported and the constructor does not return.
|
|
|
|
$head Side Effect$$
|
|
If $code local::graph::op_name2enum.size() == 0$$,
|
|
the routine $cref/set_operator_info/cpp_graph_op/set_operator_info/$$
|
|
is called to initialize
|
|
$code op_enum2fixed_n_arg$$,
|
|
$code op_enum2name$$, and
|
|
$code op_name2enum$$.
|
|
This initialization cannot be done in
|
|
$cref/parallel mode/ta_in_parallel/$$.
|
|
|
|
$head Prototype$$
|
|
$srccode%hpp% */
|
|
public:
|
|
json_lexer(const std::string& json);
|
|
/* %$$
|
|
$end
|
|
-------------------------------------------------------------------------------
|
|
$begin json_lexer_check_next_char$$
|
|
$spell
|
|
json
|
|
lexer
|
|
ch
|
|
$$
|
|
|
|
$section Get and Check Next Single Character Token$$
|
|
|
|
$head Syntax$$
|
|
$codei%
|
|
%json_lexer%.check_next_char(%ch%)
|
|
%$$
|
|
|
|
$head index_$$
|
|
The search for the character starts
|
|
at one greater than the input value for $code index_$$ and skips white space.
|
|
|
|
$head ch$$
|
|
Is a non white space
|
|
single character token that is expected.
|
|
If this character is not found,
|
|
the error is reported and this function does not return.
|
|
In the special case where $icode ch$$ is $code '\0'$$,
|
|
any non-white space character will be accepted
|
|
(but there must be such a character).
|
|
|
|
$head token_$$
|
|
If this routine returns, $code token_$$ has size one
|
|
and contains the character that is found.
|
|
|
|
|
|
$head Prototype$$
|
|
$srccode%hpp% */
|
|
public:
|
|
void check_next_char(char ch);
|
|
/* %$$
|
|
$end
|
|
-------------------------------------------------------------------------------
|
|
$begin json_lexer_check_next_string$$
|
|
$spell
|
|
json
|
|
lexer
|
|
$$
|
|
|
|
$section Get and Check Next Single Character Token$$
|
|
|
|
$head Syntax$$
|
|
$codei%
|
|
%json_lexer%.check_next_string(%expected%)
|
|
%$$
|
|
|
|
$head index_$$
|
|
The search for the string starts
|
|
at one greater than the input value for $code index_$$ and skips white space.
|
|
|
|
$head expected$$
|
|
Is the value (not including double quotes) for the string that is expected.
|
|
If this string is not found, the error is reported
|
|
and this function does not return.
|
|
In the special case where $icode expected$$ is empty,
|
|
any string will be accepted.
|
|
|
|
$head token_$$
|
|
If this routine returns,
|
|
$icode token_$$ is the string that was found.
|
|
|
|
|
|
$head Prototype$$
|
|
$srccode%hpp% */
|
|
public:
|
|
void check_next_string(const std::string& expected);
|
|
/* %$$
|
|
$end
|
|
-------------------------------------------------------------------------------
|
|
$begin json_lexer_next_non_neg_int$$
|
|
$spell
|
|
json
|
|
lexer
|
|
neg
|
|
$$
|
|
|
|
$section Get Next Non-Negative Integer$$
|
|
|
|
$head Syntax$$
|
|
$codei%
|
|
%json_lexer%.next_non_neg_int()
|
|
%value% = %json_lexer%.token2size_t()
|
|
%$$
|
|
|
|
$head index_$$
|
|
The search for the non-negative integer starts
|
|
at one greater than the input value for $code index_$$ and skips white space.
|
|
|
|
$head token_$$
|
|
is set to the non-negative integer.
|
|
If the next token is not a non-negative integer,
|
|
the error is reported and this function does not return.
|
|
|
|
$head value$$
|
|
If the current token is a non-negative integer,
|
|
$icode value$$ is the corresponding value.
|
|
|
|
$head Prototype$$
|
|
$srccode%hpp% */
|
|
public:
|
|
void next_non_neg_int(void);
|
|
size_t token2size_t(void) const;
|
|
|
|
/* %$$
|
|
$end
|
|
-------------------------------------------------------------------------------
|
|
$begin json_lexer_next_float$$
|
|
$spell
|
|
json
|
|
lexer
|
|
$$
|
|
|
|
$section Get Next Floating Point Number$$
|
|
|
|
$head Syntax$$
|
|
$codei%
|
|
%ok% = %json_lexer%.next_float()
|
|
%value% = %json_lexer%.token2double()
|
|
%$$
|
|
|
|
$head index_$$
|
|
The search for the floating point number starts
|
|
at one greater than the input value for $code index_$$ and skips white space.
|
|
|
|
$head token_$$
|
|
is set to the floating point number.
|
|
If the next token is not a floating point number,
|
|
the error is reported and this function does not return.
|
|
|
|
$head value$$
|
|
If the current token is a floating point number,
|
|
$icode value$$ is the corresponding value.
|
|
|
|
$head Prototype$$
|
|
$srccode%hpp% */
|
|
public:
|
|
void next_float(void);
|
|
double token2double(void) const;
|
|
|
|
/* %$$
|
|
$end
|
|
*/
|
|
|
|
// ==========================================================================
|
|
}; // end class lexer
|
|
// ==========================================================================
|
|
|
|
|
|
} } } // END_NAMESPACE_CPPAD_LOCAL_GRAPH
|
|
|
|
|
|
# endif
|