0

I'm trying to find a way to simplify the comparison cases of booleans. Currently, there are only three (as shown below), but I'm about to add a 4th option and this is getting very tedious.

bracketFirstIndex = message.indexOf('[');
mentionFirstIndex = message.indexOf('@');
urlFirstIndex = message.indexOf(urlStarter);

bool startsWithBracket = (bracketFirstIndex != -1);
bool startsWithAtSymbol = (mentionFirstIndex != -1);
bool startsWithUrl = (urlFirstIndex != -1);     

if (!startsWithBracket)
{
    if (!startsWithAtSymbol)
    {
        if (!startsWithUrl)
        {
            // No brackets, mentions, or urls. Send message as normal
            cursor.insertText(message);
            break;
        }
        else
        {
            // There's a URL, lets begin!
            index = urlFirstIndex;
        }
    }
    else
    {
        if (!startsWithUrl)
        {
            // There's an @ symbol, lets begin!
            index = mentionFirstIndex;
        }
        else
        {
            // There's both an @ symbol and URL, pick the first one... lets begin!
            index = std::min(urlFirstIndex, mentionFirstIndex);
        }
    }
}
else
{
    if (!startsWithAtSymbol) 
    {
        // There's a [, look down!
        index = bracketFirstIndex;
    }
    else
    {
        // There's both a [ and @, pick the first one... look down!
        index = std::min(bracketFirstIndex, mentionFirstIndex);
    }

    if (startsWithUrl)
    {
        // If there's a URL, pick the first one... then lets begin!
        // Otherwise, just "lets begin!"
        index = std::min(index, urlFirstIndex);
    }
}

Is there a better/more simpler way to compare several boolean values, or am I stuck in this format and I should just attempt to squeeze in the 4th option in the appropriate locations?

7
  • 1
    It looks like you are parsing some text... you could potentially simplify this with a regular expression or using a parser-generator. Commented Jul 12, 2015 at 0:41
  • @MichaelAaronSafyan Can you elaborate a little further on the REGEX plan / parser-generator (I've never heard of this wording). Commented Jul 12, 2015 at 0:44
  • 1
    @ZeldaZach Can you tell us what you are trying to parse? It seems its some sort of e-mail or URL, but I don't recall [ participating on any of those. If you can be more specific about your problem we might be able to help with regex. Commented Jul 12, 2015 at 0:46
  • @Havenard This is an in-program chat service, which we have special rules for different things. For example, you can @ mention somebody, post a url (example.com), use a card look up function [[card name]], and I'm working on adding a highlight function right now, but I'd like to see if I can simplify the statements Commented Jul 12, 2015 at 0:49
  • 1
    The notion that "starts with X" = "there is an X somewhere" sounds dubious to me. I suspect the presented code is not correct. Commented Jul 12, 2015 at 1:10

2 Answers 2

3

Some type of text processing are fairly common, and for those, you should strongly consider using an existing library. For example, if the text you are processing is using the markdown syntax, consider using an existing library to parse the markdown into a structured format for you to interpret.

If this is completely custom parsing, then there are a few options:

  • For very simple text processing (like a single string expected to be in one of a few formats or containing a piece of subtext in an expected format), use regular expressions. In C++, the RE2 library provides very powerful support for matching and extracting usign regexes.

  • For more complicated text processing, such as data spanning many lines or having a wide variety of content / syntax, consider using an existing lexer and parser generator. Flex and Bison are common tools (used together) to auto-generate logic for parsing text according to a grammar.

  • You can, by hand, as you are doing now, write your own parsing logic.

If you go with the latter approach, there are a few ways to simplify things:

  1. Separate the "lexing" (breaking up the input into tokens) and "parsing" (interpreting the series of tokens) into separate phases.

  2. Define a "Token" class and a corresponding hierarchy representing the types of symbols that can appear within your grammar (like RawText, Keyword, AtMention, etc.)

  3. Create one or more enums representing the states that your parsing logic can be in.

  4. Implement your lexing and parsing logic as a state machine that transforms the state given the current state and the next token or letter. Building up a map from (state, token type) to next_state or from (state, token type) to handler_function can help you to simplify the structure.

Sign up to request clarification or add additional context in comments.

Comments

0

Since you are switching only on the starting letter, use cases:

enum State { Start1, Start2, Start3, Start4};
State state;
if (startswithbracket) {
   state = Start1;
} else {
.
.
.
}

switch (state) {
   case Start1:
      dosomething;
      break;
   case Start2:
      .
      .
      .
 }

More information about switch syntax and use cases can be found here.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.