Надо отпарсить и подсветить несколько строк (для начала — хотя бы одну) формата CString. Лексеммы разделены запятыми, скобочками, логическими и математическими операторами (свой встроенный микроязык запросов). Хотелось бы посмотреть какие-нибудь простейшие реализации. На codeproject валяется html-парсер, но там строк больше тыщи, и естессно идея алгоритма не указывается. У меня задача гораздо проще, чем парсить html-текст в несколько десятков килобайт. Может кто-нибудь видел подобные вещи или делал сам?
Все имена функций и классов изменены, любое совпадение является случайным.
Здравствуйте, Logic Bomb, Вы писали:
LB>Надо отпарсить и подсветить несколько строк (для начала — хотя бы одну) формата CString. Лексеммы разделены запятыми, скобочками, логическими и математическими операторами (свой встроенный микроязык запросов). Хотелось бы посмотреть какие-нибудь простейшие реализации. На codeproject валяется html-парсер, но там строк больше тыщи, и естессно идея алгоритма не указывается. У меня задача гораздо проще, чем парсить html-текст в несколько десятков килобайт. Может кто-нибудь видел подобные вещи или делал сам?
imho лучше не писать свой парсер с нуля, а научиться пользоваться одним из уже написанных — будет и быстрее, и надежнее
bison
bison++ (для тех, кому хочется ++)
boost::spirit
Здравствуйте, Аноним, Вы писали:
А>imho лучше не писать свой парсер с нуля, а научиться пользоваться одним из уже написанных — будет и быстрее, и надежнее А>bison А>bison++ (для тех, кому хочется ++) А>boost::spirit
а это что за звери такие ?
Все имена функций и классов изменены, любое совпадение является случайным.
Здравствуйте, Logic Bomb, Вы писали:
LB>Надо отпарсить и подсветить несколько строк (для начала — хотя бы одну) формата CString. Лексеммы разделены запятыми, скобочками, логическими и математическими операторами (свой встроенный микроязык запросов). Хотелось бы посмотреть какие-нибудь простейшие реализации. На codeproject валяется html-парсер, но там строк больше тыщи, и естессно идея алгоритма не указывается. У меня задача гораздо проще, чем парсить html-текст в несколько десятков килобайт. Может кто-нибудь видел подобные вещи или делал сам?
Почитайте Страуструпа, там в 3-ей главе описывается как раз самый простой парсер (калькулятор)... Прямую ссылку на книгу не привожу -> поиск в гугле сразу выдаст.
Здравствуйте, Logic Bomb, Вы писали:
LB>Здравствуйте, Аноним, Вы писали:
А>>imho лучше не писать свой парсер с нуля, а научиться пользоваться одним из уже написанных — будет и быстрее, и надежнее А>>bison А>>bison++ (для тех, кому хочется ++) А>>boost::spirit
LB>а это что за звери такие ?
GNU bison — генератор парсеров, "тяжелая артиллерия"
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Logic Bomb, Вы писали:
LB>>Надо отпарсить и подсветить несколько строк (для начала — хотя бы одну) формата CString. Лексеммы разделены запятыми, скобочками, логическими и математическими операторами (свой встроенный микроязык запросов). Хотелось бы посмотреть какие-нибудь простейшие реализации. На codeproject валяется html-парсер, но там строк больше тыщи, и естессно идея алгоритма не указывается. У меня задача гораздо проще, чем парсить html-текст в несколько десятков килобайт. Может кто-нибудь видел подобные вещи или делал сам?
А>imho лучше не писать свой парсер с нуля, а научиться пользоваться одним из уже написанных — будет и быстрее, и надежнее
Я бы сказал, лучше не писать парсер без использования генератора парсеров
А>bison А>bison++ (для тех, кому хочется ++)
+PCCTS — генерирует LL парсеры, которые отлаживать, проще чем LR/LALR.
А>boost::spirit
Здравствуйте, Logic Bomb, Вы писали:
LB>Даа ребята... простейший — я имел ввиду на уровне продвинутой сортировки массивов. Просто банальный разбор по лексеммам. Я же не ворд собираюсь писать
Уж не знаю, причем тут сортировка массивов. Но почти любой разбор писать без генератора — дольше. Фактически надо писать код, который получается после генератора LL парсеров. Выглядит он просто, но длинно. Для каждого правила грамматики — метод. Каждая альтернатива — switch по первому символу и вызов кода для соответствующей последовательности.
Здравствуйте, Logic Bomb, Вы писали:
LB>Даа ребята... простейший — я имел ввиду на уровне продвинутой сортировки массивов. Просто банальный разбор по лексеммам. Я же не ворд собираюсь писать
Здравствуйте, Logic Bomb, Вы писали:
LB>Надо отпарсить и подсветить несколько строк (для начала — хотя бы одну) формата CString. Лексеммы разделены запятыми, скобочками, логическими и математическими операторами (свой встроенный микроязык запросов). Хотелось бы посмотреть какие-нибудь простейшие реализации. На codeproject валяется html-парсер, но там строк больше тыщи, и естессно идея алгоритма не указывается. У меня задача гораздо проще, чем парсить html-текст в несколько десятков килобайт. Может кто-нибудь видел подобные вещи или делал сам?
Spirit тебе уже насоветовали. Пример есть здесь(cpp_lexer).
Если парсить именно С++, то есть Boost::Wave. Там есть реализация препроцессора C/C++.
Блин, человек интересуется как построить синтаксический анализатор языка программирвоания си, а не обзором инструментов для генерации синтаксических анализаторов. Для си есть класическая вещь, называется lcc. Это компилятор языка си дял различных платформ, написанный вручную методом рекурсивного спуска. Есть книжка "A Retargetable C Compiler: Design and Implementation", в которой описано просто и подробно как этот компилятор реализован. Для того, чтобы ее читать, не надо нчего из теории компиляции знать, там все как раз объясняется. Не знаю, есть ли она в электронном виде, но в бумажном я ее читал когда-то и всем интересующимся советую прочитать. Пока что и исходников будет достаточно наверное. Да ,есть еще специальная конференцияпо этому компилятору.
Здравствуйте, Logic Bomb, Вы писали:
LB>Надо отпарсить и подсветить несколько строк (для начала — хотя бы одну) формата CString. Лексеммы разделены запятыми, скобочками, логическими и математическими операторами (свой встроенный микроязык запросов). Хотелось бы посмотреть какие-нибудь простейшие реализации. На codeproject валяется html-парсер, но там строк больше тыщи, и естессно идея алгоритма не указывается. У меня задача гораздо проще, чем парсить html-текст в несколько десятков килобайт. Может кто-нибудь видел подобные вещи или делал сам?
Если нужен чисто токенайзер, то я как-то раз делал такой.
class tokenizer
{
public:
enum sep_flag
{
single,
multiple,
whole_str
};
struct token
{
const char* ptr;
unsigned len;
};
public:
tokenizer(const char* sep,
const char* trim=0,
const char* quote="\"",
char mask_chr='\\',
sep_flag sf=multiple);
void set_str(const char* str);
token next_token();
private:
int check_chr(const char *str, char chr);
private:
const char* m_src_string;
int m_start;
const char* m_sep;
const char* m_trim;
const char* m_quote;
char m_mask_chr;
unsigned m_sep_len;
sep_flag m_sep_flag;
};
//-----------------------------------------------------------------------inline void tokenizer::set_str(const char* str)
{
m_src_string = str;
m_start = 0;
}
//-----------------------------------------------------------------------inline int tokenizer::check_chr(const char *str, char chr)
{
return int(strchr(str, chr));
}
//-----------------------------------------------------------------------
tokenizer::tokenizer(const char* sep,
const char* trim,
const char* quote,
char mask_chr,
sep_flag sf) :
m_src_string(0),
m_start(0),
m_sep(sep),
m_trim(trim),
m_quote(quote),
m_mask_chr(mask_chr),
m_sep_len(sep ? strlen(sep) : 0),
m_sep_flag(sep ? sf : single)
{
}
//-----------------------------------------------------------------------
tokenizer::token tokenizer::next_token()
{
unsigned count = 0;
char quote_chr = 0;
token tok;
tok.ptr = 0;
tok.len = 0;
if(m_src_string == 0 || m_start == -1) return tok;
register const char *pstr = m_src_string + m_start;
if(*pstr == 0)
{
m_start = -1;
return tok;
}
int sep_len = 1;
if(m_sep_flag == whole_str) sep_len = m_sep_len;
if(m_sep_flag == multiple)
{
//Pass all the separator symbols at the begin of the stringwhile(*pstr && check_chr(m_sep, *pstr))
{
++pstr;
++m_start;
}
}
if(*pstr == 0)
{
m_start = -1;
return tok;
}
for(count = 0;; ++count)
{
char c = *pstr;
int found = 0;
//We are outside of qotation: find one of separator symbolsif(quote_chr == 0)
{
if(sep_len == 1)
{
found = check_chr(m_sep, c);
}
else
{
found = strncmp(m_sep, pstr, m_sep_len) == 0;
}
}
++pstr;
if(c == 0 || found)
{
if(m_trim)
{
while(count &&
check_chr(m_trim, m_src_string[m_start]))
{
++m_start;
--count;
}
while(count &&
check_chr(m_trim, m_src_string[m_start + count - 1]))
{
--count;
}
}
tok.ptr = m_src_string + m_start;
tok.len = count;
//Next time it will be the next separator character
//But we must check, whether it is NOT the end of the string.
m_start += count;
if(c)
{
m_start += sep_len;
if(m_sep_flag == multiple)
{
//Pass all the separator symbols
//after the end of the stringwhile(check_chr(m_sep, m_src_string[m_start]))
{
++m_start;
}
}
}
break;
}
//Switch quote. If it is not a quote yet, try to check any of
//quote symbols. Otherwise quote must be finished with quote_symbif(quote_chr == 0)
{
if(check_chr(m_quote, c))
{
quote_chr = c;
continue;
}
}
else
{
//We are inside quote: pass all the mask symbolsif(m_mask_chr && c == m_mask_chr)
{
if(*pstr)
{
++count;
++pstr;
}
continue;
}
if(c == quote_chr)
{
quote_chr = 0;
continue;
}
}
}
return tok;
}