Reputation: 538
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?
Upvotes: 0
Views: 481
Reputation: 95449
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:
Separate the "lexing" (breaking up the input into tokens) and "parsing" (interpreting the series of tokens) into separate phases.
Define a "Token" class and a corresponding hierarchy representing the types of symbols that can appear within your grammar (like RawText, Keyword, AtMention, etc.)
Create one or more enums representing the states that your parsing logic can be in.
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.
Upvotes: 3
Reputation: 1502
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.
Upvotes: 0