Skip to main content
replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link

As a solution to this SO questionthis SO question, I wrote following code:

As a solution to this SO question, I wrote following code:

As a solution to this SO question, I wrote following code:

deleted 5 characters in body; edited title
Source Link
Jamal
  • 35.2k
  • 13
  • 134
  • 238

conditional Conditional parsing, non-standard approach

next_token() reads the next token, and returns false if this fails. syntax_error sets a global error status with message which is checked after calling this function. map_value returns true if the token can be converted to an enum class value (so if it is a conditional operator as defined by me). This algorithm is more flexible than a shunting yard (due to my future plans). 

I have not tested this extremely well, but... what do you guys think?

conditional parsing, non-standard approach

next_token() reads the next token, and returns false if this fails. syntax_error sets a global error status with message which is checked after calling this function. map_value returns true if the token can be converted to an enum class value (so if it is a conditional operator as defined by me). This algorithm is more flexible than a shunting yard (due to my future plans). I have not tested this extremely well, but... what do you guys think?

Conditional parsing, non-standard approach

next_token() reads the next token, and returns false if this fails. syntax_error sets a global error status with message which is checked after calling this function. map_value returns true if the token can be converted to an enum class value (so if it is a conditional operator as defined by me). This algorithm is more flexible than a shunting yard (due to my future plans). 

I have not tested this extremely well, but what do you think?

Tweeted twitter.com/#!/StackCodeReview/status/79791196041510913
Source Link
rubenvb
  • 190
  • 1
  • 7

conditional parsing, non-standard approach

Conditional parsing (aka read some tokens and return true or false).

As a solution to this SO question, I wrote following code:

bool nectar_loader::resolve_conditional( const std::function<bool(const string&)> &config_contains )
{
    bool result = true;
    // My very own recursive implementation
    /*
      - each set of parenthesis is handled recursively
      - logical AND: +
      - logical OR:  |
      - logical NOT: !
      - two bools: "result" and "current"
      - "result" keeps global result, and is modified by "+"
      - "current" keeps results for "|" and "!"
      - syntax checking for invalid
    */
    bool previous_was_operator = true;
    bool current = false; // keep track of current state
    string token;
    while( next_token(token) )
    {
        conditional_operator op;
        if( map_value(conditional_operator_map, token, op) )
        {
            if( previous_was_operator )
            {
                if( op == conditional_operator::not_op )
                    current ^= current; // negate next
                else
                {
                    syntax_error( "Conditional operators \'+\', \'|\', \')\', and \'(\' must be followed by a CONFIG string." );
                    break;
                }
            }
            else
            {
                switch(op)
                {
                    case conditional_operator::right_parenthesis:
                        // TODO: allow conditionals without outer parenthesis of the form (a+b)|(c)
                        return result;
                    case conditional_operator::left_parenthesis: // recurse
                        return resolve_conditional( config_contains );
                    case conditional_operator::plus_op:
                        result = result && current; // "current" -> "result"
                        if( !result ) // negative when an element of a "+" expression
                        current = false; // reset "current"
                        break;
                    case conditional_operator::or_op: // combine with "current"

                    case conditional_operator::not_op: // unreachable
                        throw runtime_error( "Internal logic error in nectar_loader::resolve_conditional" );
                }
            }
            previous_was_operator = true;
        }
        else if( !previous_was_operator )
        {
            syntax_error( "In a conditional all CONFIG strings must be seperated by a conditional operator \'+\', \'|\', \')\', or \'(\'." );
            break;
        }
        else // previous was operator, so now we have a CONFIG string
        {
            // check CONFIG string, and perform a logical OR
            // TODO: check effect of "!"
            current = current || config_contains(token);
        }
    }
    return result;
}

next_token() reads the next token, and returns false if this fails. syntax_error sets a global error status with message which is checked after calling this function. map_value returns true if the token can be converted to an enum class value (so if it is a conditional operator as defined by me). This algorithm is more flexible than a shunting yard (due to my future plans). I have not tested this extremely well, but... what do you guys think?