Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Qt и flex/bison или antlr + Visual Studio, работа с Qt и flex/bison or antlr 
:(
    Опции темы
Elfenlide
Дата 24.3.2013, 20:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 8.9.2012
Где: Беларусь

Репутация: нет
Всего: нет



Доброго всем времени суток, передомной такая задача: разработать собственный язык разметки на замену Html, разработать браузер который будет поддерживать этот язык и отображать странички. Так как использовать нужно Qt, есть там замечательная штука как компенент QWebView, можно свой язык переводить в html а затем выводить через компоненту.
Для того чтобы описать свой язык нужно использовать какой-то парсер, преподавательпредложил использовать flex/bison или antlr, но сам по этим библиотекам ничего не сказал."разбирайтесь сами." Я решил использовать Qt 5 подключив его к Visual Studio 2010. 
Вот моя идея:
 Открыть текстовый файл с моим текстом в обработке собственными тегами, парсить строку а затем сохранять результат в новый файл формата html, после чего выводить его на экран как html файл через QWebView.

Проблема:Облазил всё что мог, гуглил как умею и как не умею, но так и не нашёл как можно подключить flex/bison или antlr для работы с С++. 
Прошу объяснить значиющих как это делается.

P.S: У меня походу совсем кривые руки, тут в поиске ввожу слово "flex"  в ответ вижу фигу в виде строки "по вашему запросу ничего не найдено", хотя на форум забёрл по одной из сылок о flex-е из гугла
PM MAIL Skype   Вверх
kosmonaFFFt
Дата 25.3.2013, 07:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 538
Регистрация: 14.4.2008
Где: Иннополис

Репутация: нет
Всего: 5



flex и bison это не библиотеки, а генераторы кода - они принимают на вход файл с описанием грамматики (bison), или с описанием лексем (flex), и по ним генерируют C код, который потом можно включить в проект...
Я бы рекомендовал использовать flexc++ и bisonc++ (http://flexcpp.sourceforge.net/), они генерируют c++ код (flex и bison вроде тоже умеют C++, но код там получается довольно корявый)...


--------------------
user posted image
PM MAIL ICQ   Вверх
math64
Дата 25.3.2013, 07:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



Если твой язык разметки основан на xml - никакие бизоны не нужны.
В Qt есть классы для работы с xml, можно непосрадственно отображать xml (примеры этого есть в Qt), можно преобразовать xml в html и отображать полученный html (в самом Qt таких примеров нет, но думаю найти в инете можно).
PM   Вверх
Elfenlide
Дата 26.3.2013, 11:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 8.9.2012
Где: Беларусь

Репутация: нет
Всего: нет



Цитата(math64 @  25.3.2013,  07:21 Найти цитируемый пост)
Если твой язык разметки основан на xml - никакие бизоны не нужны.
В Qt есть классы для работы с xml, можно непосрадственно отображать xml (примеры этого есть в Qt), можно преобразовать xml в html и отображать полученный html (в самом Qt таких примеров нет, но думаю найти в инете можно). 

Нет, мне надо что-то своё придумать аля "BigWrods(hello world)" и чтобы парсер обработав это дело вывел мне "HELLO WORLD" что бы было проще сказали можно преобразовывать в html и выводить на компоненту QWebView.

Добавлено через 7 минут и 4 секунды
Цитата(kosmonaFFFt @  25.3.2013,  07:21 Найти цитируемый пост)
flex и bison это не библиотеки, а генераторы кода - они принимают на вход файл с описанием грамматики (bison), или с описанием лексем (flex), и по ним генерируют C код, который потом можно включить в проект...
Я бы рекомендовал использовать flexc++ и bisonc++ (http://flexcpp.sourceforge.net/), они генерируют c++ код (flex и bison вроде тоже умеют C++, но код там получается довольно корявый)... 

Теперь понял, но я уже неделю интернет мучаю, и не могу понять как это дело работает...готовые примеры видел, какие-то даже запустились...но как и почему, я так и не понял.
Если вам не трудно, могли бы вы написать самый простой пример(Hello world) чтоли... и при этом как-то показать что к чему и как делается? я так понял что нужно будет написать с++ код, потом создать какой-то Makefile, затем запустить генератор какой-то и он всё это обработает как надо, после чего я получу программу которую хочу. Но эта моя теория мне не помогла\

Форумы и сайты которые я находил с данной тематикой иллюстрируют примеры и что-то говорят о работе flex/bison, как они работают и что делают я вроде как понял, но я нигде не нашёл описания того, как пользоваться этими генераторами...препод сказал что можно использовать CMake для генерации проекта с включенным бизоном и флексом, но как это делать.."я давно это делал и уже не помню"...

PM MAIL Skype   Вверх
baldina
Дата 26.3.2013, 12:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата(Elfenlide @  24.3.2013,  20:01 Найти цитируемый пост)
flex/bison или antlr

попробуй antlr, можно использовать довольно дружественный antlrworks, это визуальная среда.

как вариант библиотеки безо всяких внешних генераторов и заморочек с make - boost::spirit

Добавлено через 1 минуту и 7 секунд
Цитата(Elfenlide @  26.3.2013,  11:49 Найти цитируемый пост)
самый простой пример(Hello world) чтоли

описание boost::spirit почти с этого и начинается))
PM MAIL   Вверх
kosmonaFFFt
Дата 26.3.2013, 13:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 538
Регистрация: 14.4.2008
Где: Иннополис

Репутация: нет
Всего: 5



Цитата(baldina @  26.3.2013,  16:08 Найти цитируемый пост)
попробуй antlr, можно использовать довольно дружественный antlrworks, это визуальная среда.

А с другой стороны придется избавляться от левой рекурсии, что многим очень трудно дается, аналогично и с boost::spirit, но там еще и огромные нечитаемые портянки сообщений об ошибках компилятора, если что-то не так сделаешь...

Цитата(Elfenlide @  26.3.2013,  15:49 Найти цитируемый пост)
Форумы и сайты которые я находил с данной тематикой иллюстрируют примеры и что-то говорят о работе flex/bison, как они работают и что делают я вроде как понял, но я нигде не нашёл описания того, как пользоваться этими генераторами...препод сказал что можно использовать CMake для генерации проекта с включенным бизоном и флексом, но как это делать.."я давно это делал и уже не помню"...

Это зависит от инструментов разработки... Если хочется интегрировать генерацию кода в процесс сборки, то можно Makefile или CMake использовать... А можно просто на эту тему не заморачиваться (это же не реальный проект, а учебный, если я правильно понимаю) и генерировать исходники лексера и парсера вручную после каждого изменения входных файлов для генератора...

Хеллоуворлд уже давно написан, нужно только поискать: http://flexcpp.sourceforge.net/flexc++man.html

З.Ы. В VisualStudio можно настроить pre build step, чтобы на нем генерировались файлы кода из спецификаций (предварительно сгенерив файлы руками и включив их в проект)...

Это сообщение отредактировал(а) kosmonaFFFt - 26.3.2013, 13:20


--------------------
user posted image
PM MAIL ICQ   Вверх
baldina
Дата 26.3.2013, 13:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



идеала нет.
все средства требуют определенной подготовки пользователя
PM MAIL   Вверх
Elfenlide
Дата 26.3.2013, 13:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 8.9.2012
Где: Беларусь

Репутация: нет
Всего: нет



Цитата(kosmonaFFFt @  26.3.2013,  13:18 Найти цитируемый пост)
Хеллоуворлд уже давно написан, нужно только поискать: http://flexcpp.sourceforge.net/flexc++man.html

Дело в том что примеров кучу я уже находил, а вот где написано будет куда нажимать итд, такого не видел. Тоесть, вот есть у меня например исходники простого примера, как мне заставить их работать? Я конкретно не знаю и не понимаю того, что нужно сделать для того чтобы запустить написанную программулину. 
Вот я выложил файлик, там калькулятор с граматикой итд..что делать дальше если я написал грамматику...логично сгенерировать парсер работающий на её основе, но как это сделать я не знаю так как у меня flex и bison это просто две папки с множеством файлов.

Присоединённый файл ( Кол-во скачиваний: 2 )
Присоединённый файл  parser.tar.gz 1,43 Kb
PM MAIL Skype   Вверх
Elfenlide
Дата 26.3.2013, 13:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 8.9.2012
Где: Беларусь

Репутация: нет
Всего: нет



Я сижу под Windows, а везде где я читал про генерирование, там какие-то g++ . Я так понял это Unix системы

Присоединённый файл ( Кол-во скачиваний: 1 )
Присоединённый файл  parser.tar.gz 1,43 Kb
PM MAIL Skype   Вверх
bsa
Дата 26.3.2013, 13:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Elfenlide, g++ входит в состав mingw, работающего под windows.
PM   Вверх
Elfenlide
Дата 26.3.2013, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 8.9.2012
Где: Беларусь

Репутация: нет
Всего: нет



Цитата(bsa @  26.3.2013,  13:47 Найти цитируемый пост)
g++ входит в состав mingw, работающего под windows. 

Понятно, спасибо, почитаю. 
Но всё же, что делать с архивами? для меня сейчас bison и flex это просто две папки с файлами\
Если не трудно, объясните на примере исходников которые нуждаються в генерации.
PM MAIL Skype   Вверх
baldina
Дата 26.3.2013, 14:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата(Elfenlide @  26.3.2013,  13:37 Найти цитируемый пост)
 а вот где написано будет куда нажимать

этого, батенька, вам никто не скажет. тут все умели когда-то нажимать, но давно забыли. спросите преподавателя: много проще и короче показать пальцем, сидя рядом.

Добавлено через 11 минут и 15 секунд
Цитата(Elfenlide @  26.3.2013,  14:05 Найти цитируемый пост)
Если не трудно, объясните на примере исходников которые нуждаються в генерации. 

составляете файл с грамматикой, допустим calculator.y (пример из документации)
Код

/* Reverse polish notation calculator. */

%{
#define YYSTYPE double
#include <math.h>
%}

%token NUM

%% 

input:    /* empty */
        | input line
;

line:     '\n'
        | exp '\n'  { printf ("\t%.10g\n", $1); }
;

exp:      NUM             { $$ = $1;         }
        | exp exp '+'     { $$ = $1 + $2;    }
        | exp exp '-'     { $$ = $1 - $2;    }
        | exp exp '*'     { $$ = $1 * $2;    }
        | exp exp '/'     { $$ = $1 / $2;    }
      /* Exponentiation */
        | exp exp '^'     { $$ = pow ($1, $2); }
      /* Unary minus    */
        | exp 'n'         { $$ = -$1;        }
;
%%

дальше напускаете на него bison:
Код

>bison calculator.y

получаете в результате calculator.tab.с
дальше составляете файл с лексическим анализатором (через flex или руками) calc_lex.c:

Код

#include <stdio.h>
#include <ctype.h>

int yylex ()
{
  int c;

  /* skip white space  */
  while ((c = getchar ()) == ' ' || c == '\t')  
    ;
  /* process numbers   */
  if (c == '.' || isdigit (c))                
    {
      ungetc (c, stdin);
      scanf ("%lf", &yylval);
      return NUM;
    }
  /* return end-of-file  */
  if (c == EOF)                            
    return 0;
  /* return single chars */
  return c;                                
}

void yyerror (s)  /* Called by yyparse on error */
     char *s;
{
  printf ("%s\n", s);
}

int main ()
{
  yyparse ();
  return 0;
}


вот эти два файла составляют исходный код приложения. их нужно включить в ваш проект VS2010
PM MAIL   Вверх
Elfenlide
Дата 26.3.2013, 15:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 8.9.2012
Где: Беларусь

Репутация: нет
Всего: нет



Цитата(baldina @  26.3.2013,  14:10 Найти цитируемый пост)
 тут все умели когда-то нажимать, но давно забыли.

Вот и препод мне тоже самое сказал....
Вот, вы сказали то что я знаю, файлы составлять итд....но вот каким образом 
Цитата(baldina @  26.3.2013,  14:10 Найти цитируемый пост)
дальше напускаете на него bison:
. У меня flex и bison это две папки с кучей файлов. Видимо с ними(папками) что-то нужно сделать, чтобы потом иметь возможность bison-ом творить чудеса, вот что именно, мне и интересно\

PM MAIL Skype   Вверх
baldina
Дата 26.3.2013, 16:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата(Elfenlide @  26.3.2013,  15:55 Найти цитируемый пост)
каким образом

в текстовом редакторе  smile 
серьезно, надо а) изучать синтаксис б) для начала составить БНФ своего языка, она уже преобразуется в синтаксис bison
Цитата(Elfenlide @  26.3.2013,  15:55 Найти цитируемый пост)
flex и bison это две папки с кучей файлов. Видимо с ними(папками) что-то нужно сделать

ваша куча файлов - http://downloads.sourceforge.net/gnuwin32/...n-2.4.1-bin.zip
разворачиваете архив в папку (видимо это уже сделано)
в папке bin видим bison.exe - вот его и надо запускать, передавая в качестве параметра ваш .y файл
автоматизировать это дело можно, настроив в VS pre-build шаг, прописав туда вызов bison

Добавлено через 14 секунд
с flex аналогично

Добавлено через 6 минут и 41 секунду
Цитата(Elfenlide @  24.3.2013,  20:01 Найти цитируемый пост)
 задача: разработать собственный язык разметки 

начните с этого. как будет готово, с инструментом будет легче определиться:
может оказаться, что ваш язык укладывается в регулярные выражения. если нет, он может оказаться прост настолько, что проще будет свой парсер написать.
создание языка и (в случае инструментов типа bison) формирование БНФ мне кажется наиболее важным и сложным (остальное дело техники)

Добавлено через 9 минут и 57 секунд
Цитата(Elfenlide @  24.3.2013,  20:01 Найти цитируемый пост)
парсить строку а затем сохранять результат в новый файл формата html, 

можно и не сохранять, а сразу передавать в QWebView::setHtml()
PM MAIL   Вверх
Elfenlide
Дата 26.3.2013, 18:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 8.9.2012
Где: Беларусь

Репутация: нет
Всего: нет



Цитата(baldina @  26.3.2013,  16:25 Найти цитируемый пост)
в папке bin видим bison.exe

Вот, у меня левые какие-то архивы были, скачал bison, flex с екзешкой не нашёл, но примеры не работают...я беру отсюда http://flexcpp.sourceforge.net/flexc++man.html и делаю как написано. bison ругается. Поискал flex, нашёл архив где под винду flex/bison сразу, вроде работают, но ошибки всё-равно есть, пробовал пример выше сделать бизоном calc.tab.c, а флексом лексический анализатор сделать не вышло. Брал такой исходник:
Код


%%
[ \t\n]+                            // skip white space chars.
[0-9]+                              return NUMBER;
[[:alpha:]_][[:alpha:][:digit:]_]*  return IDENTIFIER;


получил: C:\Flex & Bison\win_flex_bison-latest>win_flex lexer.l
lexer.l:5: EOF encountered inside an action


Когда попробовал ваш готовый анализатор взять и просто сделать преокт в Visual Studio, как я понял всё что нужно было сделать, это добавить туда эти два файла, получил в студии ошибки:
Ошибка    1    error C2065: yylval: необъявленный идентификатор    c:\flex & bison\win_flex_bison-latest\lexerp.c    13
Ошибка    2    error C2065: NUM: необъявленный идентификатор    c:\flex & bison\win_flex_bison-latest\lexerp.c    14
    7    IntelliSense: идентификатор "yylval" не определен    c:\flex & bison\win_flex_bison-latest\lexerp.c    13
    8    IntelliSense: идентификатор "NUM" не определен    c:\flex & bison\win_flex_bison-latest\lexerp.c    14
    9    IntelliSense: недопустимый неполный тип    c:\flex & bison\win_flex_bison-latest\lexerp.c    22
    10    IntelliSense: требуется объявление    c:\flex & bison\win_flex_bison-latest\lexerp.c    24
    11    IntelliSense: идентификатор "yyparse" не определен    c:\flex & bison\win_flex_bison-latest\lexerp.c    29

Цитата(baldina @  26.3.2013,  16:25 Найти цитируемый пост)
проще будет свой парсер написать
 Я уже подумываю, но парсеры нормальные писать не умею, миллион ифов писать не хочеться потому что это не правильно, а вот разобраться в такой штуке как генератор парсера вроде как очень полезно.

Цитата(baldina @  26.3.2013,  16:25 Найти цитируемый пост)
разработать собственный язык разметки 
 тут разрабатывать то нечего,  я буду просто писать в файле текст типа: Hello Kursive(World) newLine, и он мне должен вызвать функцию Kursive для букв в скобках, преобразовать в строку <i>World</i> и вывести уже в html тегах обработанную как курсив, ну итд...а вместо <br> нужно писать что-то типа newLine для перевода на новую строку...
Вообще я взялся за флекс и бизон потому что не знаю как по другому сделать, ну, не включая парсера из пары сотен ифов..это даже не парсер а ересь какая-то...а препод только о бизоне, флексе и antlr заикнулся, antlr  пробовал разобрать, но на с++ как с ним работать не особо въехал, везде про Java почти написано и интеграцию с Eclipse, думал сделать на Java парсер чтобы вызывался от с++ готовый джавовский екзешник и превращал мой язык в html, после чего выводил бы на QWebView уже готовую страничку просто, идея сразу не очень понравилась, а когда решил попробоввать убедился в том что тупня это....

PM MAIL Skype   Вверх
baldina
Дата 26.3.2013, 18:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата(Elfenlide @  26.3.2013,  18:32 Найти цитируемый пост)
миллион ифов писать не хочеться потому что это не правильно

простейший парсер сверху вниз - не надо много if, а для поиска ключевых слов используйте std::map

давайте-ка придумайте полностью ваш язык, опишите, дальше подумаем что и как делать

PM MAIL   Вверх
fish9370
Дата 27.3.2013, 12:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 663
Регистрация: 15.4.2007
Где: Москва

Репутация: 1
Всего: 1



может к черту бизон? 

регулярные выражения, парсер, шаблонизатор, пара шаблонов..


--------------------
undefined
PM MAIL WWW ICQ   Вверх
Elfenlide
Дата 27.3.2013, 15:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 8.9.2012
Где: Беларусь

Репутация: нет
Всего: нет



Цитата(baldina @  26.3.2013,  18:45 Найти цитируемый пост)
давайте-ка придумайте полностью ваш язык, опишите, дальше подумаем что и как делать

нужно реализовать возможность:
◦ указывать ссылки на другие страницы;
◦ вставлять изображения в текст;
◦ устанавливать выравнивание текста и его стиль (аналоги тегов <b><i><u><font>).
Я придумал так: $ это будет главное отличие, тоесть если не знак доллара, то свободно читаем как обычный символ и выводим как читаем.
вместо тегов b, i, u, font, ,будут: $Bold() , $Kursiv(), $UnderLine(), $Font() - для простоты я решил изменить его, html эквивалентный имеет 3 параметра: высота символа, тип шрифта, цвет. Следовательно будут отдельные теги: $Color(), $Size(), $TypeText(). Ну и в таком стиле остальные: ссылки, загрузка картики. 
Просто если я буду считывать каждый символ, то это ифы итд...я уже накидал код такой, который по сиволам разбирает, но исключительно из-за того что скоро здавать нужно будет, и не хочу двойку. А вот что-то толковое изучить, какой-то метод которым можно парсер хороший написать я не знаю, поэтому и хотел взять бизон и флекс...
Мой код на данный момент\ я думаю это не очень красивый вариант решения данной задачи. Я пишу на Qt, но тут от Qt только QString, остальное как в стандартном с++.

Код

void KursiveText(QString& KursiveStr, int& i, QString& str, QString& tempStr, int& tempStrInd);
void BoldText(QString& BoldStr,int& i, QString& str, QString& tempStr, int& tempStrInd);
void UnderLineText(QString& UnderLineStr,int& i, QString& str, QString& tempStr, int& tempStrInd);
void SizeText(QString& SizeStr,int& i, QString& str, QString& tempStr, int& tempStrInd);
void Endl(int& tempStrInd, QString& tempStr, int& i);

QString WebBrowser::parsing(QString str)
{
    QString tempStr;
    QString KursiveStr = "";
    QString BoldStr = "";
    QString UnderLineStr = "";
    QString SizeStr = "";
    int tempStrInd = 0;

    for(int i = 0; i < str.size(); i++)
    {
        if(str[i] == '$')
        {
            i++;

            if(str[i] == 'K' && str[i+1] == '(')
            {
                KursiveText(KursiveStr, i, str, tempStr, tempStrInd);
            }
            else if(str[i] == 'e' && str[i+1] == 'n'
                && str[i+2] == 'd' && str[i+3] == 'l'
                && str[i+4] == '(' && str[i+5] == ')')
            {
                Endl(tempStrInd, tempStr, i);
            }
            else if(str[i] == 'B' && str[i+1] == '(')
            {
                BoldText(BoldStr, i, str, tempStr, tempStrInd);
            }
            else if(str[i] == 'U' && str[i+1] == '(')
            {
                UnderLineText(UnderLineStr, i, str, tempStr, tempStrInd);
            }
            else if(str[i] == 'S' && str[i+1] == '(')
            {
                SizeText(SizeStr, i, str, tempStr, tempStrInd);
            }
            
        }
        else
        {
            tempStr[tempStrInd] = str[i];
            tempStrInd++;
        }        

    }

    return tempStr;
}

void KursiveText(QString& KursiveStr, int& i, QString& str, QString& tempStr, int& tempStrInd)
{
    int tempINDEX = 0;
    int KursiveInd = i+2;
    i = KursiveInd;

    while(str[i] != ')')
    {
        KursiveStr[tempINDEX] = str[KursiveInd];
        tempINDEX++; i++; KursiveInd++;
    }

    QString htmlRezult;
    htmlRezult = "<i>";
    htmlRezult += KursiveStr + "</i>";
    KursiveStr = htmlRezult;

    tempStr += KursiveStr;
    tempStrInd += KursiveStr.size();
    KursiveStr = "";
}

void BoldText(QString& BoldStr, int& i, QString& str, QString& tempStr, int& tempStrInd)
{
    int tempINDEX = 0;
    int BoldInd = i+2;
    i = BoldInd;

    while(str[i] != ')')
    {
        BoldStr[tempINDEX] = str[BoldInd];
        tempINDEX++; i++; BoldInd++;
    }

    QString htmlRezult;
    htmlRezult = "<b>";
    htmlRezult += BoldStr + "</b>";
    BoldStr = htmlRezult;

    tempStr += BoldStr;
    tempStrInd += BoldStr.size();
    BoldStr = "";
}

void UnderLineText(QString& UnderLineStr, int& i, QString& str, QString& tempStr, int& tempStrInd)
{
    int tempINDEX = 0;
    int UnderLineInd = i+2;
    i = UnderLineInd;

    while(str[i] != ')')
    {
        UnderLineStr[tempINDEX] = str[UnderLineInd];
        tempINDEX++; i++; UnderLineInd++;
    }

    QString htmlRezult;
    htmlRezult = "<u>";
    htmlRezult += UnderLineStr + "</u>";
    UnderLineStr = htmlRezult;

    tempStr += UnderLineStr;
    tempStrInd += UnderLineStr.size();
    UnderLineStr = "";
}

void SizeText(QString& SizeStr,int& i, QString& str, QString& tempStr, int& tempStrInd)
{
    int tempINDEX = 0;
    int  SizeStrInd = i+2;
    i =  SizeStrInd;

    while(str[i] != ')')
    {
        SizeStr[tempINDEX] = str[ SizeStrInd];
        tempINDEX++; i++;  SizeStrInd++;
    }

    QString htmlRezult;
    htmlRezult = "<font size = 7>";
    htmlRezult += SizeStr + "</font>";
    SizeStr = htmlRezult;

    tempStr += SizeStr;
    tempStrInd += SizeStr.size();
    SizeStr = "";
}

void Endl(int& tempStrInd, QString& tempStr, int& i)
{
    tempStr += "<br/>";
    tempStrInd += 5;
    i += 5;
}


Добавлено через 9 минут и 5 секунд
Да, забыл дописать, то что будет в скобках тега, то и будет обрабатываться им. $Bold(Hello) $UnderLine(World). Обрабатываются Hello и  World соответственно.
PM MAIL Skype   Вверх
math64
Дата 27.3.2013, 15:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



У тебя не $Bold() , а $B() и т. д. 
Не обрабатывается вложенность типа $B($I(Hello) $U(World))
т.е нужно искать не первую ), а парную и внутренность рекурсивно обрабатывать.
Поиск $:
Код

int index = str.indexOf('$', from);


Генерировать html проще так:
Код

QString boldStr = QString("<b>%1</b>").arg(str);

PM   Вверх
Elfenlide
Дата 27.3.2013, 17:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 8.9.2012
Где: Беларусь

Репутация: нет
Всего: нет



Да, у меня $B() а не $Bold(), но это временно, для того чтобы быстрее писать программу, когда будет готова, чутка буду поправлять. Но честно говоря заканчивать её с кучей инструкций а не толковым парсером, желания нет.
baldina с мапом предлагает как-то замутить, вот мне это интересно. Может что-то классное выйдет.

Цитата(math64 @  27.3.2013,  15:39 Найти цитируемый пост)
Не обрабатывается вложенность типа $B($I(Hello) $U(World))

Я её думал сделать вызвав проверку на вложенность внутри методов путём просмотра строки между "()", но чуть позже.
Я считаю что это вообщей самый ущербный метод, которые для "лишь бы сделать и забыть"...ну...я про это выше писал.
Я знаю ещё есть метод конечного автомата со стеком состояний, как-то мне нужно было вводить строку типа {a,b,c,d,g,{u,j,k}} и создавать объекты собственного класса "множества" с элементами, ну и при этом должна быть фишка что множество может быть элементом другого множества.
Но там только {} из символов,а тут нужно кучу разных тегов замутить...
Вот как-то так:
Код

Set Set::parse(stringstream &str)
{
    enum { 
        OPEN,
        ELEMENT,
        NEXT
    } state = OPEN;

    Set theSet;
    while (!str.eof()) {
        switch (state) {
        case OPEN:
            switch (str.get()) {
            case ' ':   continue;

            case '{':  state = ELEMENT;
                continue;
            default:    return Set();
            }
        case ELEMENT:
            switch (str.peek()) {
            case ' ':  
                {
                    str.ignore();
                    continue;
                }

            case ',':  { return Set(); }

            case '}': 
                {
                    str.ignore();
                    return theSet;
                }

            case '{':
                {    
                    theSet.add(parse(str));
                    state = NEXT;
                    continue;
                }

            default:    theSet.add(str.get());
                state = NEXT;
                continue;
            }
        case NEXT:
            switch (str.get()) {
            case ' ':  { continue; }

            case ',':  
                {
                    state = ELEMENT;
                    continue;
                }


            case '}':   return theSet;

            default:    return Set();
            }
        }
    }
    return Set();
}


PM MAIL Skype   Вверх
math64
Дата 27.3.2013, 20:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



QMap можно использовать так:
Код

QMap<QString,QString> map;
map["Bold"]="<b>%1</b>";

Ключи - теги между $ и (
Значения - код html с %1 на месте вставки аргумента.

Добавлено через 13 минут и 7 секунд
А вместо автомата с состояниями - используй рекурсию, при этом код будет более понятным.
В этом случае текущее состояние определяется вызовами на стеке.
PM   Вверх
Elfenlide
Дата 27.3.2013, 21:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 8.9.2012
Где: Беларусь

Репутация: нет
Всего: нет



QMap<QString,QString> map;
map["Bold"]="<b>%1</b>";

Ключи - теги между $ и (
Значения - код html с %1 на месте вставки аргумента.[/quote]
не совсем понял как работает, если я создам map["Bold"] то когда считывание строки будет происходить, он сам определит последовательность символов map?
Если можно с каким-то простеньким примером поясните пожалуйста.

PM MAIL Skype   Вверх
math64
Дата 28.3.2013, 07:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



Ищешь $ или ) - что первое встретится. 
Код

QRegExp re("(\\$([A-Za-z]+)\\()|\\)");

Если найден ) - преобразуешь то, что до ) и выходишь из рекурсивной функции разбора
Если найден $ - выбираешь имя тега
Код

QString key = re.cap(2);
if (!map.contains(key)) {
  << неверный тег >>
}
QString html = map[key];

далее делаешь рекурсивный вызов parse() - на выходе индекс должен стоять на ')'
Код

QString tmp = parse();
if (index >= str.lengh() || str[index] != ')') {
  << нет парной скобки >>
}
res += html.arg(tmp);

и повторяшь поиск.

Это сообщение отредактировал(а) math64 - 28.3.2013, 07:34
PM   Вверх
Elfenlide
Дата 28.3.2013, 09:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 8.9.2012
Где: Беларусь

Репутация: нет
Всего: нет



Код

QString key = re.cap(2);

эта строка отвечает за то что следующие 2 символа будут считаны из потока я так понял?которые идут после знака $ 
PM MAIL Skype   Вверх
math64
Дата 28.3.2013, 12:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



cap(0) - вся найденная строка $Bold(
cap(1) - первый фрагмент - $Bold( - выделен аргумент | - (\\$([A-Za-z]+)\\()
cap(2) - второй фрагмент - Bold  - специально выделено скобочками - ([A-Za-z]+)
На всякий случай проверь:
Код

qDebug() << "re.cap(0)=" << re.cap(0);
qDebug() << "re.cap(1)=" << re.cap(1);
qDebug() << "re.cap(2)=" << re.cap(2);


Добавлено через 11 минут и 12 секунд
Код

QRegExp re("\\$([A-Za-z]+)\\(|\\)");
...
QString key = re.cap(1);

Аргумент | можно специально не выыделять - скобки нужны когда выриантная не вся строка, пример из документации:
Код

QRegExp rx("(\\d+)(\\s*)(cm|inch(es)?)");
int pos = rx.indexIn("Length: 36 inches");
QStringList list = rx.capturedTexts();
// list is now ("36 inches", "36", " ", "inches", "es")

PM   Вверх
xvr
Дата 28.3.2013, 14:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



А я бы все же посмотрел в сторону bison'а. Ваша грамматика вся умещается в пару строк -
Код

%union {
 char* str;
 ProgItem* prog;
}
%token<str> vCTRL
%token<str> vSTR
%type<prog> prog p_item
$$
top: prog {set_output($1);} ;
prog: p_item | prog p_item {$$=join($1,$2);};
p_item: vSTR {$$=new PIString($1);}
       | vCTRL '(' prog ')' {$$=new PICtrl($1,$3);}
       ;

Где vCTRL - все слова, начинающиеся с $, а vSTR - все остальные символы (кроме скобок)

Если делать это на flex'е, то это будет так
Код

$[a-f]+  { yylval.str = strdup(yytext); return vCTRL;}
[()]        { return yytext[0]; }
[^()$]+ { yylval.str = strdup(yytext); return vSTR;}
Вместо strdup лучше взять что нибудь поближе к С++  smile 

Базовый класс ProgItem представляет кусок текста или фидективу форматирования. Он умеет вязаться в списки (функция ProgItem* join(ProgItem*,ProgItem*) )
Классы PIString и PICtrl - его наследники для чистых строк текста и директив форматирования соотвественно.
Функция set_output передает наружу результат парсинга - дерево, соотвествующее вашему тексту.

bison можно взять обычный С'ный - результат соберется в режиме С++

PM MAIL   Вверх
Elfenlide
Дата 28.3.2013, 18:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 8.9.2012
Где: Беларусь

Репутация: нет
Всего: нет



Цитата(xvr @  28.3.2013,  14:49 Найти цитируемый пост)
Если делать это на flex'е, то это будет так

Я чутка не понял, так можно либо на флексе, либо на бизоне делать? я просто из всего что читал, понял что нужно их вместе использовать, лексер задаёт правила, парсер по ним работает.
И я попробовал написать ваш код флекса, и получил в консоли кучу ошибок, насколько я понял синтаксис, правила должны быть заключены в %% %%, я добавил, вроде нормально сгенерировалось, осталось теперь только понять одно\ как этим делом пользоваться. Радость что теперь понимаю как генерировать это всё дело)Спасибо за это огромное).

math64 и вас спасибо большое за помощь, попробую двумя способами сделать, лишним не будет.
PM MAIL Skype   Вверх
math64
Дата 28.3.2013, 21:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



бизон работает в паре в флексом.
Если планируестя усложнение грамматики, можно воспользоваться бизоном+флексом,
а на теперешнем уровне для разбора достаточно одной рекурсивоной функции - так проще.
В том числе и для отладки - отдаживаться в коде, сгенерированном бизоном неудобно.
PM   Вверх
lexxmark
Дата 8.4.2013, 21:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 8.4.2013

Репутация: нет
Всего: нет



Привет, попробую помоч с flex/bison для Qt.
Прежде всего добавь в начало своего *.pro файла вот этот кусок кода. Тут настраивается qmake, что бы обрабатывать flex/bison файлы. 
Код

# объявляем новый обработчик файлов
flex.name = Flex ${QMAKE_FILE_IN}
# определяем что входными данными будет список файлов FLEX_SOURCES
flex.input = FLEX_SOURCES
# определяем какие будут получаться выходные файлы
flex.output = ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.lexer.cpp
# определяем какую команду надо вызвать для каждого входного файла 
win32:flex.commands = win_flex --wincompat -o ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.lexer.cpp ${QMAKE_FILE_IN}
# это версия команды для linux
unix:flex.commands = flex -o ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.lexer.cpp ${QMAKE_FILE_IN}
# говорим что наш генератор должен выполняться до основной компиляции
flex.CONFIG += target_predeps
# говорим что выходные файлы - исходники на C++, что бы они попали в компиляцию
flex.variable_out = GENERATED_SOURCES
# регистрируем только что настроенный объект flex  как внешний компилятор в qmake
QMAKE_EXTRA_COMPILERS += flex

# аналогично с bison
bison.name = Bison ${QMAKE_FILE_IN}
bison.input = BISON_SOURCES
bison.output = ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.parser.cpp
win32:bison.commands = win_bison -d -o ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.parser.cpp ${QMAKE_FILE_IN}
unix::bison.commands = bison -Wmidrule-value -t -d -o ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.parser.cpp ${QMAKE_FILE_IN}
bison.CONFIG += targets_predeps
bison.variable_out = GENERATED_SOURCES
QMAKE_EXTRA_COMPILERS += bison


Далее ниже в этом же *.pro файле прописываешь свои flex и bison файлы, например так:
Код

FLEX_SOURCES += MyFile.l
BISON_SOURCES += MyFile.y


После этого перестраиваешь проект и у тебя должны генерироваться MyFile.lexer.cpp и MyFile.parser.cpp файлы.
Сами команды генерации (flex.commands/bison.commands) можешь адаптировать под свои нужды - менять параметры запуска.
 Как видишь для windows версии используется win_flex/win_bison. Их можешь взять отсюда: http://sourceforge.net/projects/winflexbison/
Это более компактные версии flex/bisоn.
Как работать с flex/bison - можешь почитать pdf-ки с того же источника.
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1255 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.