Re[3]: Нужен хелп оп Bison
От: nen777w  
Дата: 21.06.11 21:36
Оценка:
Здравствуйте, monitooa, Вы писали:

M>Спасибо, nen777w!


M>А нельзя ли выложить конкретный пример в исходнике.

M>Чтоб можно было его сразу собрать.

M>Еще рез спасибо!


Держите. Весь проект можно скачать тут.
Теперь немного о проекте.
Я бы не назвал организацию сканера образцовой. Даже по той причине что используется _scan_bytes() — которая производит дублирование входного буфера.
Можно и по другому сделать (но уже сами смотрите документацию по Flex-у).
Тут получился парсер в стиле "С" можно и в С++ (опять смотрите доку если сильно надо).
Ну и нет обработки в грамматике для случая когда последовательность перемешанная.

А вообще Flex/Bison штука классная, Я уже ого-го сколько парсеров на ней сделал, и даже один компилятор.
Так что советую изучить или Flex/Bison или ANTLR, там среда разработки есть (хотя мне хватает и Notepad++)
, и он позволяет задать опцию для просмотра наперёд более 1-й лексемы (LL(n)-грамматика), в отличии от bison где только LL(1))

Немного кода:

  "Код лексера"
%option noyywrap
%option stack
%option prefix="flex_bison_"

%{
    /************************************************************************
    * If you change this file don't forget rebuild parser with build.bat !!!!
    *************************************************************************/
    
    #include "bison_.hpp"
    
    bool    is_wilcard_string( const char* );
%}

WHITE_SPACE [ \t\f\v]
NEWLINE [\r\n|\n\r|\n|\r]


STRING                \"{1}[^\n"]*\"{1}

%%

<*>{WHITE_SPACE} { /*eatup*/ }

<*><<EOF>> {
    return tEND;
}

<INITIAL>{
    {STRING} {
        if(is_wilcard_string(yytext))
            return tWILDCARD_STRING;
        else
            return tSTRING;
    }
}

%%

void    scan( const char* pbuff, unsigned int length )
{
    flex_bison__scan_bytes( pbuff, length );
}


  "Код грамматического анализатора"
%name-prefix="flex_bison_"
%defines
%error-verbose

%{
    #ifndef NULL
        #define NULL 0
    #endif
    
    /************************************************************************
    * If you change this file don't forget rebuild analyzer with build.bat !!!!
    *************************************************************************/
    
    extern int     flex_bison_lex();
    extern void flex_bison_error(char *msg);
    
    extern void seq_detect( unsigned int n );
%}

%start root
%token tSTRING tWILDCARD_STRING tEND

%%

root: sequences
    ;

sequences: /*empty*/
         | any_sequence sequences
         | tEND { YYABORT; }
         ;

any_sequence:  seqence_comb         { seq_detect(1); }
            |  masked_seqence_comb     { seq_detect(2); }
            ;

seqence_comb: tSTRING tSTRING tSTRING 
            ;

masked_seqence_comb: tWILDCARD_STRING tWILDCARD_STRING tWILDCARD_STRING 
                   ;

%%

/**/


  "Используем так"

#include <iostream>
#include <string>

void flex_bison_error(char *msg)
{
    std::cout << msg << std::endl;
}

extern void    scan( const char* pbuff, unsigned int length );
extern int flex_bison_parse();

//.....................................................

void    seq_detect( unsigned int n )
{
    std::cout << n << std::endl;
}

bool    is_wilcard_string( const char* str )
{
    do {
        if( '*' == *str || '?' == *str ) return true;
    } while( '\0' != *(++str) );
    return false;
}

int _tmain(int argc, _TCHAR* argv[])
{
    std::string str = "\"This is the text\" \"text\" \"text2\" \"wild*\" \"?card\" \"te?*?xt\"";
 
    scan( str.c_str(), str.length());
    flex_bison_parse();

    return 0;
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.