55 template<
class CharSeq>
 
   69 template<
class CharSeq>
 
   83 template<
class CharSeq>
 
   96 template<
class CharSeq>
 
  109 template<
class CharSeq>
 
  114         if (!_ternary_cond_stack.size()) {
 
  116                         "':' of ternary conditional without preceding '?' " 
  122                 evaluation ternary_cond = _ternary_cond_stack.back();
 
  123                 _ternary_cond_stack.pop_back();
 
  134 template<
class CharSeq>
 
  148 template<
class CharSeq>
 
  149 template<
unsigned Precedence>
 
  150 pair<typename expression_parser<CharSeq>::infix_operation,
bool>
 
  157         infix_operation rightmost_op = 
nullptr;
 
  158         bool short_circuitable = 
false;
 
  159         size_t mark = size_t(chew);
 
  160         int paren_balance = 0;
 
  161         bool have_infix = 
false;
 
  162         bool have_lhs = 
false;
 
  163         for (   ;*chew && size_t(chew) < end;
 
  164                                 have_lhs = !have_infix,chew(
greyspace)) {
 
  165                 if (have_lhs && paren_balance == 0) {
 
  166                         size_t op_off = size_t(chew);
 
  170                                 if (Precedence == ternary_if) {
 
  172                                         op_end = size_t(++chew);
 
  178                                 short_circuitable = 
true;
 
  179                                 if (Precedence == ternary_either_or) {
 
  181                                         op_end = size_t(++chew);
 
  187                                 short_circuitable = 
true;
 
  188                                 if (Precedence == comma) {
 
  190                                         op_end = size_t(++chew);
 
  197                                         Precedence == boolean_and) {
 
  198                                         short_circuitable = 
true;
 
  200                                         op_end = size_t(++chew);
 
  202                                 } 
else if (Precedence == bit_and) {
 
  204                                         op_end = size_t(chew);
 
  211                                         Precedence == boolean_or) {
 
  212                                         short_circuitable = 
true;
 
  214                                         op_end = size_t(++chew);
 
  216                                 } 
else if (Precedence == bit_or) {
 
  218                                         op_end = size_t(chew);
 
  224                                 if (Precedence == bit_xor) {
 
  226                                         op_end = size_t(++chew);
 
  233                                         if (Precedence == eq) {
 
  235                                                 op_end = size_t(++chew);
 
  248                                                 op_end = size_t(++chew);
 
  253                                                 if (Precedence == lshift) {
 
  255                                                         op_end = size_t(++chew);
 
  262                                 if (Precedence == lt) {
 
  264                                         op_end = size_t(chew);
 
  274                                                 op_end = size_t(++chew);
 
  279                                                 if (Precedence == rshift) {
 
  281                                                         op_end = size_t(++chew);
 
  288                                 if (Precedence == gt) {
 
  290                                         op_end = size_t(chew);
 
  297                                         if (Precedence == neq) {
 
  299                                                 op_end = size_t(++chew);
 
  308                                 if (Precedence == add) {
 
  310                                         op_end = size_t(++chew);
 
  316                                 if (Precedence == subtract) {
 
  318                                         op_end = size_t(++chew);
 
  324                                 if (Precedence == mult) {
 
  326                                         op_end = size_t(++chew);
 
  332                                 if (Precedence == divide) {
 
  334                                         op_end = size_t(++chew);
 
  340                                 if (Precedence == mod) {
 
  342                                         op_end = size_t(++chew);
 
  351                                         if (Precedence == boolean_and) {
 
  353                                                 op_end = size_t(++chew);
 
  364                                         size_t mark = size_t(chew);
 
  370                                                 if (Precedence == bit_and) {
 
  372                                                         op_end = size_t(++chew);
 
  382                                                 if (Precedence == bit_or) {
 
  384                                                         op_end = size_t(++chew);
 
  396                                         if (Precedence == boolean_or) {
 
  398                                                 op_end = size_t(++chew);
 
  413                                         if (Precedence == neq) {
 
  415                                                 op_end = size_t(++chew);
 
  427                                         if (Precedence == bit_xor) {
 
  429                                                 op_end = size_t(++chew);
 
  440                 if (*chew == 
')' && --paren_balance < 0) {
 
  443                 paren_balance += *chew == 
'(';
 
  447         return make_pair(rightmost_op,short_circuitable);
 
  450 template<
class CharSeq>
 
  454                 gripe << 
", in expansion of \"" << _ref->invocation() << 
'\"';
 
  459 template<
class CharSeq>
 
  460 template<
unsigned Precedence>
 
  464         pair<infix_operation,bool> op(
nullptr,
false);
 
  466         size_t start_lhs = size_t(chew);
 
  467         size_t end_lhs = start_lhs;
 
  468         size_t start_rhs = end_lhs;
 
  470         for (; (op = seek_rightmost_infix<Precedence>(
 
  471                                         chew,end,start_rhs,end_lhs)),op.first != 
nullptr; ) {
 
  472                 lhs = next_evaluator<Precedence>(chew,start_rhs);
 
  473                 if (
size_t(chew(
greyspace)) != start_rhs) {
 
  478                 evaluation rhs = next_evaluator<Precedence - 1>(chew,end);
 
  479                 size_t end_rhs = size_t(chew);
 
  485                                 cut(start_lhs,end_lhs);
 
  494                                 cut(start_rhs,end_rhs);
 
  508         return next_evaluator<Precedence - 1>(chew,end);
 
  511 template<
class CharSeq>
 
  524                         result = unary_op(chew,end);
 
  534                         result = unary_op(chew,end);
 
  543                         size_t start = size_t(chew);
 
  545                         result = infix_op<max>(chew,end);
 
  557                                         delete_paren(start,
size_t(chew));
 
  565                         result = unary_op(chew,end);
 
  573                         result = unary_op(chew,end);
 
  581                 if (isdigit(*chew)) {
 
  582                         size_t mark = size_t(chew);
 
  594                 size_t mark = size_t(chew);
 
  599                         paren = *chew == 
'(';
 
  618                         if (!sloc->configured()) {
 
  628                         result = unary_op(chew,end);
 
  637                         result = unary_op(chew,end);
 
  650                         size_t mark = size_t(chew);
 
  663                         size_t mark = size_t(chew);
 
  664                         if (*chew == 
'L' || *chew == 
'u' || *chew == 
'U') {
 
  684                                         if (!sloc->
invoked() && args) {
 
  688                                         if (!ref.eval().insoluble() && !ref.args() &&
 
  702                                                 gripe << 
'\"' << ref.invocation()
 
  703                                                         << 
"\" expands to nothing within expression";
 
  704                                                 defer_diagnostic(gripe);
 
  706                                             if (ref.complete()) {
 
  708                             gripe << 
'\"' << ref.invocation()
 
  709                                 << 
"\" expands to non-expression >>" 
  710                                 << ref.expansion() << 
"<< within expression";
 
  711                             defer_diagnostic(gripe);
 
  714                             gripe << 
"Macro expansion of \"" 
  717                             "Will exceed max expansion size " 
  720                             defer_diagnostic(gripe);
 
  733                         gripe << 
"Ill-formed \"" << bad;
 
  735                                 gripe << 
"\" after \"" << good << 
'\"';
 
  737                         defer_diagnostic(gripe);
 
  743 template<
class CharSeq>
 
  747         _eval = infix_op<max>(chew,size_t(-1));
 
  748         bool orphan_if = 
false;
 
  749         if (_ternary_cond_stack.size()) {
 
  753         if ((chew || orphan_if)) {
 
  754                 _eval.set_insoluble();
 
  755                 std::shared_ptr<diagnostic_base> gripe;
 
  759                                 << 
"'?' of ternary conditional without following ':' " 
  767                         *gripe << 
"Ill-formed \"" << bad << 
"\" after \"" 
  789 template<
class CharSeq>
 
  792         string const & in = _seq.str();
 
  793         if (is_simplified()) {
 
  796                 for (   ; i < _start; ++i) {
 
  799                 if (i > 0 && _deletions[i] && isgraph(in[i - 1])) {
 
  803                 for (   ; ptrdiff_t(i) <= _last_deletion; ++i) {
 
  804                         if (!_deletions[i]) {
 
  808                 if (i + 1 < _seq.size()) {
 
  809                         out += _seq.substr(i);
 
  819 template<
class CharSeq>
 
  824 :       _ternary_cond_stack(0),_seq(seq),_start(start),
 
  825         _cuts(0),_last_deletion(-1),_ref(ref)
 
evaluation op_bit_and(evaluation const &lhs, evaluation const &rhs)
Bitwise AND operator. 
 
error_msg< 20 > error_ternary_cond_incomplete
Report an incomplete ternary conditional operator. 
 
template struct traits::is_random_access_char_sequence<T> exports a static const boolean member value...
 
static bool plaintext()
Are we to omit parsing for C/C++ comments? 
 
static bool implicit()
Do we implicitly --undef all unconfigured symbols? 
 
evaluation op_rshift(evaluation const &lhs, evaluation const &rhs)
Right-shift operator. 
 
template struct warning_msg<Id> generically encapsulates a warning diagnostic. 
 
unsigned long long raw() const 
Get the bits comprising the integer as an unsigned long long 
 
static integer read_numeral(chewer< CharSeq > &chew)
Read a numeral from a chewer<CharSeq> 
 
bool is_start_char(char ch)
Say whether a character can be the first of an identifier. 
 
template struct error_msg<Id> generically encapsulates an error diagnostic. 
 
evaluation apply(infix_operation op, evaluation &lhs, evaluation &rhs)
Apply a infix operation to arguments. 
 
std::shared_ptr< std::string const  > defn() const 
Get a pointer to the symbol's definition; null if undefined. 
 
integer const & value() const 
Get the integral value of the expression. 
 
evaluation op_add(evaluation const &lhs, evaluation const &rhs)
Addition operator. 
 
evaluation op_lt(evaluation const &lhs, evaluation const &rhs)
Less-than operator. 
 
std::string simplified() const 
Get the most simplified form of the expression. 
 
bool invoked() const 
Say whether the symbol has been invoked. 
 
evaluation op_ne(evaluation const &lhs, evaluation const &rhs)
Inequality operator. 
 
struct symbol::locator encapsulates a symbol table entry. 
 
bool good() const 
Say whether the integer is of valid type, not INT_UNDEF 
 
void set_parens_off(size_t loff, size_t roff)
Set the text offsets of surrounding parentheses. 
 
#define TOK_ALT_BIT_NOT
Constant denoting the alternative bitwise negation operator. 
 
evaluation op_lshift(evaluation const &lhs, evaluation const &rhs)
Left-shift operator. 
 
evaluation op_subtract(evaluation const &lhs, evaluation const &rhs)
Subtraction operator. 
 
void defer_diagnostic(diagnostic_base &gripe)
Defer a diagnostic, with the current line context appended if a source line is being parsed...
 
size_t lparen_off() const 
Get the text offset of the left parenthesis, if any. -1 if none. 
 
A base class for diagnostic classes. 
 
#define TOK_DEFINED
Constant denoting the defined operator. 
 
bool configured() const 
Say whether the symbol is configured. 
 
evaluation op_le(evaluation const &lhs, evaluation const &rhs)
Less-than-or-equal operator. 
 
evaluation op_mod(evaluation const &lhs, evaluation const &rhs)
Modulus operator. 
 
void set_insoluble()
Classify the expression as insoluble. 
 
Undetermined type or invalid. 
 
Class argument_list encapsulates a list of macro arguments, i.e. the arguments to a macro reference...
 
evaluation op_ge(evaluation const &lhs, evaluation const &rhs)
Greater-than-or-equal operator. 
 
Class integer encapsulates an integer of some type. 
 
warning_msg< 14 > warning_zero_divide
Report a divide by zero was found in an expression. 
 
std::string citable(chewer< std::string > &chew, size_t len=std::string::npos)
Make a citable version of length-delimited text. 
 
static locator lookup(std::string const &id)
Lookup an identifier in the symbol table. 
 
void set_value(integer const &val)
Set the integral value of the expression. 
 
bool variadic() const 
Say whether this symbol is a variadic macro. 
 
expression_parser(chewer< sequence_type > &chew, reference const *ref=nullptr)
Construct given a chewer<sequence_type> 
 
evaluation op_eq(evaluation const &lhs, evaluation const &rhs)
Equality operator. 
 
evaluation op_comma(evaluation const &lhs, evaluation const &rhs)
Comma operator. 
 
evaluation infix_op(chewer< sequence_type > &chew, size_t end)
Evaluator for infix operations. 
 
evaluation op_or(evaluation const &lhs, evaluation const &rhs)
Inclusive-or operator. 
 
size_t rparen_off() const 
Get the text offset of the right parenthesis, if any. -1 if none. 
 
std::string read(chewer< CharSeq > &chew)
Read an identifier from an chewer<CharSeq> 
 
bool defined() const 
Is the symbol defined. 
 
static size_t flush(unsigned reason)
Emit all queued diagnostics that match a reason-code. 
 
chew_mode::continuation const continuation
An exemplar chew_mode::continuation 
 
evaluation op_mult(evaluation const &lhs, evaluation const &rhs)
Multiplication operator. 
 
error_msg< 14 > error_unbalanced_paren
Report unbalanced parenthesis. 
 
The tag class is inserted in a diagnostic_base to tell it to emit itself. 
 
evaluation op_divide(evaluation const &lhs, evaluation const &rhs)
Division operator. 
 
evaluation op_ternary_either_or(evaluation const &lhs, evaluation const &rhs)
The ':' "operator". Pops the evaluation of the preceding `cond ?' from the stack. If cond is true, returns lhs; if cond is false returns rhs, else returns evaluation() 
 
chew_mode::greyspace const greyspace
An exemplar chew_mode::greyspace 
 
bool resolved() const 
Say whether the expression has been resolved. 
 
The tag class is inserted in a diagnostic_base to tell it to defer itself. 
 
evaluation op_and(evaluation const &lhs, evaluation const &rhs)
And operator. 
 
bool is_valid_char(char ch)
Say whether a character can occur in an identifier. 
 
integer_type type() const 
Get the type of the integer 
 
evaluation op_bit_or(evaluation const &lhs, evaluation const &rhs)
Bitwise OR operator. 
 
static constexpr unsigned max_expansion_size()
Cut-off size for macro-expansions. 
 
void set_parameters(formal_parameter_list const ¶ms)
Set a macro parameter list for the symbol. 
 
`template struct chewer<CharSeq> is a cursor-like type that is associated with a character-sequence t...
 
template class canonical<What> encapsulates the canonical representation of values of type What...
 
bool insoluble() const 
Say whether the expression is insoluble. 
 
evaluation op_gt(evaluation const &lhs, evaluation const &rhs)
Greater-than operator. 
 
void parse(chewer< sequence_type > &chew)
Evaluate text from a chewer<sequence_type> 
 
static integer read_char(chewer< CharSeq > &chew)
Read a character constant from a text offset, returning its value as an integer. 
 
evaluation op_bit_xor(evaluation const &lhs, evaluation const &rhs)
Bitwise XOR operator. 
 
bool is_false() const 
Say whether the expression is false. 
 
evaluation unary_op(chewer< sequence_type > &chew, size_t end)
Evaluator for innermost subexpressions. 
 
#define TOK_ALT_BOOLEAN_NOT
Constant denoting the alternative boolean negation operator. 
 
static std::string pretty()
Get a pretty printable version of the current input line. 
 
bool is_true() const 
Say whether the expression is true. 
 
evaluation op_ternary_if(evaluation const &lhs, evaluation const &rhs)
The '?' "operator". Stacks its left operand; returns its right. 
 
bool self_referential() const 
Say whether the symbol's definition is infinitely regressive. 
 
struct evaluation represents the result of evaluating a putative expression. 
 
std::pair< expression_parser::infix_operation, bool > seek_rightmost_infix(chewer< sequence_type > &chew, size_t end, size_t &op_start, size_t &op_end)
Search for the rightmost binary operator at a given level of precedence within delimited text...
 
unsigned short & net_infix_ops()
Get/set the residual number of binary operators in the expression, after simplification.