где посмотреть простейший парсер на с++?
От: Logic Bomb Россия  
Дата: 13.11.05 16:11
Оценка:
Надо отпарсить и подсветить несколько строк (для начала — хотя бы одну) формата CString. Лексеммы разделены запятыми, скобочками, логическими и математическими операторами (свой встроенный микроязык запросов). Хотелось бы посмотреть какие-нибудь простейшие реализации. На codeproject валяется html-парсер, но там строк больше тыщи, и естессно идея алгоритма не указывается. У меня задача гораздо проще, чем парсить html-текст в несколько десятков килобайт. Может кто-нибудь видел подобные вещи или делал сам?
Все имена функций и классов изменены, любое совпадение является случайным.
Re: где посмотреть простейший парсер на с++?
От: Аноним  
Дата: 13.11.05 16:29
Оценка: -1
Здравствуйте, Logic Bomb, Вы писали:

LB>Надо отпарсить и подсветить несколько строк (для начала — хотя бы одну) формата CString. Лексеммы разделены запятыми, скобочками, логическими и математическими операторами (свой встроенный микроязык запросов). Хотелось бы посмотреть какие-нибудь простейшие реализации. На codeproject валяется html-парсер, но там строк больше тыщи, и естессно идея алгоритма не указывается. У меня задача гораздо проще, чем парсить html-текст в несколько десятков килобайт. Может кто-нибудь видел подобные вещи или делал сам?


imho лучше не писать свой парсер с нуля, а научиться пользоваться одним из уже написанных — будет и быстрее, и надежнее
bison
bison++ (для тех, кому хочется ++)
boost::spirit
Re[2]: где посмотреть простейший парсер на с++?
От: Logic Bomb Россия  
Дата: 13.11.05 16:59
Оценка:
Здравствуйте, Аноним, Вы писали:

А>imho лучше не писать свой парсер с нуля, а научиться пользоваться одним из уже написанных — будет и быстрее, и надежнее

А>bison
А>bison++ (для тех, кому хочется ++)
А>boost::spirit

а это что за звери такие ?
Все имена функций и классов изменены, любое совпадение является случайным.
Re: где посмотреть простейший парсер на с++?
От: m3 Украина  
Дата: 14.11.05 00:41
Оценка:
Здравствуйте, Logic Bomb, Вы писали:

LB>Надо отпарсить и подсветить несколько строк (для начала — хотя бы одну) формата CString. Лексеммы разделены запятыми, скобочками, логическими и математическими операторами (свой встроенный микроязык запросов). Хотелось бы посмотреть какие-нибудь простейшие реализации. На codeproject валяется html-парсер, но там строк больше тыщи, и естессно идея алгоритма не указывается. У меня задача гораздо проще, чем парсить html-текст в несколько десятков килобайт. Может кто-нибудь видел подобные вещи или делал сам?



Почитайте Страуструпа, там в 3-ей главе описывается как раз самый простой парсер (калькулятор)... Прямую ссылку на книгу не привожу -> поиск в гугле сразу выдаст.
... Если в первый момент идея не кажется абсурдной, она безнадёжна. © Альберт Эйнштейн
Re[3]: где посмотреть простейший парсер на с++?
От: bnk СССР http://unmanagedvisio.com/
Дата: 14.11.05 08:28
Оценка:
Здравствуйте, Logic Bomb, Вы писали:

LB>Здравствуйте, Аноним, Вы писали:


А>>imho лучше не писать свой парсер с нуля, а научиться пользоваться одним из уже написанных — будет и быстрее, и надежнее

А>>bison
А>>bison++ (для тех, кому хочется ++)
А>>boost::spirit

LB>а это что за звери такие ?


GNU bison — генератор парсеров, "тяжелая артиллерия"

http://gnuwin32.sourceforge.net/packages/bison.htm
http://www.gnu.org/software/bison/bison.html

boost::spirit будет IMHO, попроще — наверное то что нужно..
http://www.boost.org
Re[2]: где посмотреть простейший парсер на с++?
От: all-x Россия http://treedl.sf.net
Дата: 14.11.05 13:47
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Logic Bomb, Вы писали:


LB>>Надо отпарсить и подсветить несколько строк (для начала — хотя бы одну) формата CString. Лексеммы разделены запятыми, скобочками, логическими и математическими операторами (свой встроенный микроязык запросов). Хотелось бы посмотреть какие-нибудь простейшие реализации. На codeproject валяется html-парсер, но там строк больше тыщи, и естессно идея алгоритма не указывается. У меня задача гораздо проще, чем парсить html-текст в несколько десятков килобайт. Может кто-нибудь видел подобные вещи или делал сам?


А>imho лучше не писать свой парсер с нуля, а научиться пользоваться одним из уже написанных — будет и быстрее, и надежнее


Я бы сказал, лучше не писать парсер без использования генератора парсеров

А>bison

А>bison++ (для тех, кому хочется ++)

+PCCTS — генерирует LL парсеры, которые отлаживать, проще чем LR/LALR.

А>boost::spirit
Re: где посмотреть простейший парсер на с++?
От: Logic Bomb Россия  
Дата: 14.11.05 14:12
Оценка:
Даа ребята... простейший — я имел ввиду на уровне продвинутой сортировки массивов. Просто банальный разбор по лексеммам. Я же не ворд собираюсь писать
Все имена функций и классов изменены, любое совпадение является случайным.
Re[2]: где посмотреть простейший парсер на с++?
От: all-x Россия http://treedl.sf.net
Дата: 14.11.05 14:21
Оценка:
Здравствуйте, Logic Bomb, Вы писали:

LB>Даа ребята... простейший — я имел ввиду на уровне продвинутой сортировки массивов. Просто банальный разбор по лексеммам. Я же не ворд собираюсь писать


Уж не знаю, причем тут сортировка массивов. Но почти любой разбор писать без генератора — дольше. Фактически надо писать код, который получается после генератора LL парсеров. Выглядит он просто, но длинно. Для каждого правила грамматики — метод. Каждая альтернатива — switch по первому символу и вызов кода для соответствующей последовательности.
Re[2]: где посмотреть простейший парсер на с++?
От: Vintik_69 Швейцария  
Дата: 14.11.05 14:22
Оценка:
Здравствуйте, Logic Bomb, Вы писали:

LB>Даа ребята... простейший — я имел ввиду на уровне продвинутой сортировки массивов. Просто банальный разбор по лексеммам. Я же не ворд собираюсь писать


Так в чем проблема разбить по лексемам? Если неохота это вручную делать, возьми lex. http://dinosaur.compilertools.net/#lex
Re: где посмотреть простейший парсер на с++?
От: Юрий Жмеренецкий ICQ 380412032
Дата: 15.11.05 02:23
Оценка:
Здравствуйте, Logic Bomb, Вы писали:

LB>Надо отпарсить и подсветить несколько строк (для начала — хотя бы одну) формата CString. Лексеммы разделены запятыми, скобочками, логическими и математическими операторами (свой встроенный микроязык запросов). Хотелось бы посмотреть какие-нибудь простейшие реализации. На codeproject валяется html-парсер, но там строк больше тыщи, и естессно идея алгоритма не указывается. У меня задача гораздо проще, чем парсить html-текст в несколько десятков килобайт. Может кто-нибудь видел подобные вещи или делал сам?



Spirit тебе уже насоветовали. Пример есть здесь(cpp_lexer).
Если парсить именно С++, то есть Boost::Wave. Там есть реализация препроцессора C/C++.
Re: где посмотреть простейший парсер на с++?
От: mefrill Россия  
Дата: 15.11.05 08:14
Оценка:
Здравствуйте, Logic Bomb, Вы писали:

Блин, человек интересуется как построить синтаксический анализатор языка программирвоания си, а не обзором инструментов для генерации синтаксических анализаторов. Для си есть класическая вещь, называется lcc. Это компилятор языка си дял различных платформ, написанный вручную методом рекурсивного спуска. Есть книжка "A Retargetable C Compiler: Design and Implementation", в которой описано просто и подробно как этот компилятор реализован. Для того, чтобы ее читать, не надо нчего из теории компиляции знать, там все как раз объясняется. Не знаю, есть ли она в электронном виде, но в бумажном я ее читал когда-то и всем интересующимся советую прочитать. Пока что и исходников будет достаточно наверное. Да ,есть еще специальная конференцияпо этому компилятору.
Re[2]: где посмотреть простейший парсер на с++?
От: gok Россия  
Дата: 16.02.06 18:46
Оценка:
Здравствуйте, Аноним, Вы писали:

Boost::spirit работает на msvc не ниже 7.1
gok
Re: где посмотреть простейший парсер на с++?
От: McSeem2 США http://www.antigrain.com
Дата: 18.02.06 15:12
Оценка: +1
Здравствуйте, 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 string
            while(*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 symbols
            if(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 string
                        while(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_symb
            if(quote_chr == 0)
            {
                if(check_chr(m_quote, c)) 
                {
                    quote_chr = c;
                    continue;
                }
            }
            else
            {
                //We are inside quote: pass all the mask symbols
                if(m_mask_chr && c == m_mask_chr)
                {
                    if(*pstr) 
                    {
                        ++count;
                        ++pstr;
                    }
                    continue; 
                }
                if(c == quote_chr) 
                {
                    quote_chr = 0;
                    continue;
                }
            }
        }
        return tok;
    }



Пользоваться примерно так:
    tokenizer cmd_line(" ", "\"' ", "\"'", '\\', tokenizer::multiple);
    cmd_line.set_str(lpszCmdLine);

    int argc = 0;
    argv[argc++] = argv_ptr;
    *argv_ptr++ = 0;

    while(argc < 64)
    {
        agg::tokenizer::token tok = cmd_line.next_token();
        if(tok.ptr == 0) break;
        if(tok.len)
        {
            memcpy(argv_ptr, tok.ptr, tok.len);
            argv[argc++] = argv_ptr;
            argv_ptr += tok.len;
            *argv_ptr++ = 0;
        }
    }


А вообще-то, надо "курить" конечные автоматы.
http://www.rsdn.ru/article/alg/checkStr.xml
Автор(ы): Николай Меркин
Дата: 19.01.2002

http://www.rsdn.ru/article/alg/Static_Finite_State_Machine.xml
Автор(ы): Alexander Nikolayenko
Дата: 08.10.2005
Машина с конечным числом состояний (FSM, Finite State Machine, или как принято называть по-русски, конечный автомат, КА) представляет собой одну из наиболее полезных концепций в арсенале разработчика. Существует несколько методик реализации конечных автоматов, но, забегая вперед, хочется сказать, что достойный результат дают только те из них, которые связаны с генерацией кода. Возможности, предоставляемые последней версией стандарта C++ и реализованные в последних версиях компиляторов, позволяют генерировать код во время компиляции основного кода проекта. Это дает возможность избежать использования отдельных утилит или расширений IDE и, оставаясь в рамках единого языка (C++), создавать приемлемые для практического использования реализации КА, которые при этом легко поддерживать и развивать.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.