2015-07-12 12 views
0

Я пытаюсь найти способ упростить примеры сравнения логических. В настоящее время их всего три (как показано ниже), но я собираюсь добавить 4-й вариант, и это становится очень утомительным.Как упростить логические сравнения на C++

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); 
    } 
} 

Есть ли лучше/более простой способ сравнить несколько логических значений, или я застрял в этом формате, и я просто должен пытаться втиснуть в 4-е варианта в соответствующих местах?

+1

Похоже, что вы разбираете текст ... вы могли бы упростить это с помощью регулярного выражения или с помощью синтаксического анализатора. –

+0

@MichaelAaronSafyan Можете ли вы подробнее рассказать о плане REGEX/синтаксическом анализаторе (я никогда не слышал об этой формулировке). – ZeldaZach

+1

@ZeldaZach Можете ли вы рассказать нам, что вы пытаетесь разобрать? Кажется, это своего рода электронная почта или URL-адрес, но я не помню '[' участие в любом из них. Если вы можете уточнить свою проблему, мы сможем помочь с регулярным выражением. – Havenard

ответ

3

Некоторый тип обработки текста довольно распространен, и для них вы должны настоятельно рассмотреть возможность использования существующей библиотеки. Например, если текст, который вы обрабатываете, использует синтаксис markdown, рассмотрите возможность использования существующей библиотеки для разбора уценки в структурированный формат для интерпретации.

Если это полностью настраиваемые синтаксическое, то есть несколько вариантов:

  • Для очень простой обработки текста (например, одной строки, как ожидается, находиться в одном из нескольких форматов или содержащий фрагмент подтекст в ожидаемом формате), используйте regular expressions. В C++ библиотека RE2 предоставляет очень мощную поддержку для сопоставления и извлечения регулярных выражений.

  • Для более сложной обработки текста, такой как данные, охватывающие многие строки или имеющие широкий спектр контента/синтаксиса, рассмотрите возможность использования существующего генератора лексера и синтаксического анализатора. Flex и Bison являются общими инструментами (используются вместе) для автоматической генерации логики для анализа текста в соответствии с грамматикой.

  • Вы можете, вручную, как вы сейчас это делаете, написать собственную логику синтаксического анализа.

Если вы идете с последним подходом, есть несколько способов, чтобы упростить вещи:

  1. Отделить «лексический» (ломки входа в токены) и «разбор» (переводческий серия токенов) в отдельные фазы.

  2. Определение класса «Маркер» и соответствующая иерархии, представляющие тип символов, которые могут появиться в ваших грамматиках (как RawText, ключевое слово, AtMention и т.д.)

  3. Создайте один или несколько перечислений, представляющее государство что ваша логика синтаксического анализа может быть включена.

  4. Реализовать логику лексирования и разбора в качестве конечного автомата, который преобразует состояние с учетом текущего состояния и следующего токена или буквы. Создание карты из (state, token type) в next_state или из (state, token type) в handler_function может помочь вам упростить структуру.

0

Поскольку вы переключаетесь только на начальной буквой, случаи использования:

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

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

Больше информации о синтаксисе переключателя и использовать случаи могут быть найдены here.