Нужен хелп оп Bison
От: monitooa  
Дата: 21.06.11 15:27
Оценка:
Помогите на бизоне сделать простенький парсер буквально по 2-м условиям.

А. Если предложение содержит 3 точные последовательности в произвольном порядке:
последовательность №1 "This document content"
последовательность №2 "one"
последовательность №3 "two"
-----------------
Если есть совпадение, то возвращается результат "1"

Б. Если предложение содержит 3 точные последовательности с заданными масками в заданном порядке:
последовательность №1 "This doc*"
последовательность №2 "co*nt"
последовательность №3 "t?o"
-----------------
Если есть совпадение, то возвращается результат "2"

Сам никогда с бизоном не работал, а времени вникать в тонкости бизона совсем нету!
Спасобо!
Re: Нужен хелп оп Bison
От: nen777w  
Дата: 21.06.11 16:11
Оценка:
Здравствуйте, monitooa, Вы писали:

M>Помогите на бизоне сделать простенький парсер буквально по 2-м условиям.


M>А. Если предложение содержит 3 точные последовательности в произвольном порядке:

M> последовательность №1 "This document content"
M> последовательность №2 "one"
M> последовательность №3 "two"
M> -----------------
M> Если есть совпадение, то возвращается результат "1"

M>Б. Если предложение содержит 3 точные последовательности с заданными масками в заданном порядке:

M> последовательность №1 "This doc*"
M> последовательность №2 "co*nt"
M> последовательность №3 "t?o"
M> -----------------
M> Если есть совпадение, то возвращается результат "2"

M> Сам никогда с бизоном не работал, а времени вникать в тонкости бизона совсем нету!

M> Спасобо!


root: sequences ;

sequences: /*empty*/
         | any_sequence sequences
         ;

any_sequence:  seqence_comb { return 1; }
            |  masked_seqence_comb { return 2; }
            ;


seqence_comb: tSEQ tSEQ tSEQ 
            ;

masked_seqence_comb: tMSK_SEQ tMSK_SEQ tMSK_SEQ 
                   ;


Что то вроде того. Если Я правильно понял.
Определять что у тебя есть tSEQ а что tMSK_SEQ нужно будет научить лексер FLex т.е..
Вот только что ты будешь делать если они будут идти в перемешку?

p.s.
2Moderators: сделайте пожалуста наконец-то возможность редактирования сообщений.
Это ж невозможно так 3-й раз горхать меседж что бы что то исправить.
Re[2]: Нужен хелп оп Bison
От: monitooa  
Дата: 21.06.11 16:24
Оценка:
Спасибо, nen777w!

А нельзя ли выложить конкретный пример в исходнике.
Чтоб можно было его сразу собрать.

Еще рез спасибо!
Re[2]: Нужен хелп оп Bison
От: monitooa  
Дата: 21.06.11 16:33
Оценка:
Спасибо, nen777w!

Если возможно, попрошу набросать исходник который можно скомпилить.

Еще раз спасибо!
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...
Пока на собственное сообщение не было ответов, его можно удалить.