Помогите на бизоне сделать простенький парсер буквально по 2-м условиям.
А. Если предложение содержит 3 точные последовательности в произвольном порядке:
последовательность №1 "This document content"
последовательность №2 "one"
последовательность №3 "two"
-----------------
Если есть совпадение, то возвращается результат "1"
Б. Если предложение содержит 3 точные последовательности с заданными масками в заданном порядке:
последовательность №1 "This doc*"
последовательность №2 "co*nt"
последовательность №3 "t?o"
-----------------
Если есть совпадение, то возвращается результат "2"
Сам никогда с бизоном не работал, а времени вникать в тонкости бизона совсем нету!
Спасобо!
Здравствуйте, 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-й раз горхать меседж что бы что то исправить.
Здравствуйте, 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;
}
|
| |