Russian Qt Forum
Ноябрь 23, 2024, 07:17 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 2 [3] 4   Вниз
  Печать  
Автор Тема: Игнорирование комментариев при парсинге.  (Прочитано 22758 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #30 : Апрель 22, 2014, 12:22 »

А теперь слегка усложним задачу.. Сейчас наш формат допускает наличие комментариев. Комментарий начинается с символа % и заканчивается концом строки.
Теперь, если какая то команда окажется в закоментированном блоке, то предыдущее решение по прежнему выцепит её..  Более того, коменты могут быть и внутри команды, что ещё попортит нам крови при разбиении на токены..
А зачем Вы смешиваете регулярку и токенайзер? Делайте все токенами, тогда сразу получаете токен содержащий коммент целиком и пропускаете его. Может у Вас текст вшит во что-то "большое" - ну то я не знаю
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #31 : Апрель 22, 2014, 14:47 »

А теперь слегка усложним задачу.. Сейчас наш формат допускает наличие комментариев. Комментарий начинается с символа % и заканчивается концом строки.
Теперь, если какая то команда окажется в закоментированном блоке, то предыдущее решение по прежнему выцепит её..  Более того, коменты могут быть и внутри команды, что ещё попортит нам крови при разбиении на токены..
А зачем Вы смешиваете регулярку и токенайзер? Делайте все токенами, тогда сразу получаете токен содержащий коммент целиком и пропускаете его. Может у Вас текст вшит во что-то "большое" - ну то я не знаю
Так не получится.. Вернее получится, но не красиво.. Да, команды вшиты в большой текст, встречаются то здесь, то там..  И комментарии могут быть внутри команд, например:
Код
Bash
text text text \cite{arg1, %comment \n
arg2, % comment \n
...
% comment
}
text text text % \cite {argN} \n
 
 
и т.д..

Вобщем не хочется мне думать при разборе ещё и о комментах..
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #32 : Апрель 23, 2014, 09:40 »

Так не получится.. Вернее получится, но не красиво.. Да, команды вшиты в большой текст, встречаются то здесь, то там..  И комментарии могут быть внутри команд, например:
Ну хорошо, надо регуляркой так надо. Тогда почему не так

- найти регуляркой команду (\cite)
- проверить не закомментирована ли она (просмотрев назад, если % да, если eol нет)
- заглотить токенайзером  все что в скобках и извлечь аргументы
- учесть отработанную позицию (}) для след регулярки

Для др комментариев (многострочных) решения нет. Напр если в середине файла непарная кавычка - она покроет все до конца, ну это решается постановкой.

---------------

По поводу концептуальности. Связавшись с тулзом/либой ее остается очень немного  Улыбающийся Мы должны "принимать без доказательств" что вот это так - потому что оно так сделано и менять это нельзя. Усилия направлены на "прикручивание" т.е. добиться чтобы тулза делала что надо. Такое проектирование практически часто эффективно (но не всегда) и оно ограничено.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #33 : Апрель 23, 2014, 09:57 »

Такое проектирование практически часто эффективно (но не всегда) и оно ограничено.
Практически часто редко ограниченно эффективно... Улыбающийся Зато какие слова весомые.

Понимаете, вот ваш CTextAnalizer очень ограничен, он может делать только то, о чем вы думали в момент его создания. Без его модификации ничего нового он не сделает, ну это и не удивительно, если все засунуто в класс MainWindow, невозможно изменить поведение подсистемы не изменив сам класс.
Удачные решения состоят из кучи маленьких подсистем, которые делают исключительно свою работу. Поэтому, при таком концепте, легко можно изменить поведение одной подсистемы ничего более не меняя в остальной системе.
И совершенно не важно, применяется там буст или стд, можно не используя их писать удобные расширяемые решения. В данном случае мы обсуждаем итератор, в котором используются регулярки из boost, но никто не запрещает вместо них использовать регулярки Qt (или любые другие).

Все решения, которые попадают в boost и тем более из него в стандарт, долгое время продумываются и тестируются в песочницах, для того что бы получилось действительно универсальное решение. И именно поэтому, там очень много интересных подходов, которые можно использовать в своих программах и без буста.
« Последнее редактирование: Апрель 23, 2014, 11:20 от Old » Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #34 : Апрель 23, 2014, 10:24 »

Так не получится.. Вернее получится, но не красиво.. Да, команды вшиты в большой текст, встречаются то здесь, то там..  И комментарии могут быть внутри команд, например:
Ну хорошо, надо регуляркой так надо. Тогда почему не так

- найти регуляркой команду (\cite)
- проверить не закомментирована ли она (просмотрев назад, если % да, если eol нет)
- заглотить токенайзером  все что в скобках и извлечь аргументы
- учесть отработанную позицию (}) для след регулярки

Потому что, это плохой костыльный подход, от которого я изначально хотел избавиться. Этот подход плох тем, что мне придётся переписывать логику разбора текста, захламляя код доп. проверками и т.п.. И всё равно это будет менее эффективно/медленнее работать.. Что если "смотреть назад" придётся очень далеко?
 
Цитировать
Для др комментариев (многострочных) решения нет. Напр если в середине файла непарная кавычка - она покроет все до конца, ну это решается постановкой.
А Вы не путаете цитаты (quote) с комментариями (comment)?
« Последнее редактирование: Апрель 23, 2014, 10:26 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #35 : Апрель 23, 2014, 12:22 »

Потому что, это плохой костыльный подход, от которого я изначально хотел избавиться. Этот подход плох тем, что мне придётся переписывать логику разбора текста, захламляя код доп. проверками и т.п.. И всё равно это будет менее эффективно/медленнее работать.. Что если "смотреть назад" придётся очень далеко?
Речь идет о комментах "до конца строки", вычислительные расходы пренебрежимо малы и написать этот "просмотр вверх" - десяток строк. Что касается "идейности" то в упор не понимаю в чем же "костыльность" такого решения? Нужно проверить не экранировано ли найденное? Нужно, вот и делаем (самым простым образом). А так зачем Ваш парсер ловит комменты которые могут быть совсем посторонними?

А Вы не путаете цитаты (quote) с комментариями (comment)?
Здесь нет принципиальной разницы: все это "экранированный" текст который должен быть считан как один токен (и вероятно пропущен)
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #36 : Апрель 23, 2014, 12:41 »

Речь идет о комментах "до конца строки", вычислительные расходы пренебрежимо малы и написать этот "просмотр вверх" - десяток строк.
Вот-вот.. У вас слегка изменилась задача и вам приходится по всему коду дописывать эти 10 строк с проверками и пр.
Далее, появится поддержка  многострочных комментов.. Будете писать ещё +10 (и если бы 10) строк по всему коду с доп. проверками и т.д..?

В результате на каждый чих, Ваш код всё больше будет напоминать болото.. (Ну я уже не удивляюсь, что для вас это приемлемо)
 

Что касается "идейности" то в упор не понимаю в чем же "костыльность" такого решения?
Ну здесь только грустный смайлик остаётся поставить(  
Old тоже выше уже писал почему это костыльное/ограниченное  решение..  
Вы вообще читаете предыдущие сообщения?

Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #37 : Апрель 29, 2014, 13:06 »

Написал на Spiritе маленький парсер для извлечения из команд (\cite) списка ключей..
С поддержкой комментариев:
Код
C++ (Qt)
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
 
#include <string>
#include <functional>
#include <algorithm>
 
 
template <class Container>
bool add_unique_key(const std::string & key, Container & container)
{
   using namespace std::placeholders;
   if (std::find_if(container.begin(), container.end(), std::bind(std::equal_to<std::string>(), _1, key)) == container.end())
   {
       container.push_back(key);
       return true;
   }
   return false;
}
 
 
template <class ForwardIterator, class Container>
bool key_extractor(ForwardIterator & it, ForwardIterator end, Container & container)
{
   using namespace boost::spirit;
   namespace ph = boost::phoenix;
   namespace sn = boost::spirit::standard_wide;
 
   auto skipper = sn::space | '%' >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi);
   qi::rule<ForwardIterator, std::string(), decltype(skipper)> key, expr;
 
   key = +(qi::char_ - qi::char_(",{}%"));
   expr = qi::lexeme[qi::lit("\\cite")] >> '{'
       >>
       key[ ph::bind(&add_unique_key<Container>, qi::_1, ph::ref(container)) ] % ','
       >> '}'
       | qi::char_ ;
 
   return qi::phrase_parse(it, end, *expr, skipper) && (it == end);
}
 
 

И всё бы хорошо, если бы не одно но.. Как заставить skipper отличать начало комментария % от того, что началом комментария не является, т.е. \%
 Непонимающий

Или придётся на вход парсера свой skipper_iterator подавать? Не хотелось бы(
« Последнее редактирование: Апрель 29, 2014, 13:18 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #38 : Апрель 29, 2014, 13:40 »

Я сейчас далеко от компьютера, поэтому проверить не могу.
Попробуйте в скипере проверять вначале случай с экранированным % с помощью  оператора '!', тогда правило будет завершаться.
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #39 : Апрель 29, 2014, 13:48 »

Я сейчас далеко от компьютера, поэтому проверить не могу.
Попробуйте в скипере проверять вначале случай с экранированным % с помощью  оператора '!', тогда правило будет завершаться.

Уже пробовал(  
Но тогда началом коммента также будет считаться: любой символ кроме '\\' за которым следует '%'.
Это плохо, поскольку в следующей ситуации коммент "откусит" предыдущий символ (3):

text, text, \cite{key1, keq2, key3% start comment
, key4}  

Т.е. началом коммента будет 3%, что неправильно(

« Последнее редактирование: Апрель 29, 2014, 13:50 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #40 : Апрель 29, 2014, 14:35 »

Я имел ввиду проверять именно комбинацию из двух символов '\%'
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #41 : Апрель 29, 2014, 14:57 »

Я имел ввиду проверять именно комбинацию из двух символов '\%'
Так тоже не выходит..
Код
C++ (Qt)
nocom = qi::lit("\\%");
skipper = sn::space | !nocom >> '%' >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi);
 
По сути, это ни чем не отличается от просто
Код
C++ (Qt)
skipper = sn::space | '%' >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi);
 

Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #42 : Апрель 29, 2014, 15:11 »

Я думал о чем то таком:

Код
C++ (Qt)
nocom = qi::lit("\\%");
skipper = sn::space | ( !nocom | '%' ) >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi);
 

Но можно попробовать добавить правило обработки комментариев в основной парсер вместо скипетра и игнорировать результат.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #43 : Апрель 29, 2014, 16:50 »

Думал-думал. Все таки, пока не вижу, как это решить в скипере.
Сейчас попробую решить с правилом в основном правиле.
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #44 : Апрель 29, 2014, 16:55 »

Думал-думал. Все таки, пока не вижу, как это решить в скипере.
Сейчас попробую решить с правилом в основном правиле.
Похоже, что в Skipper не решит эту проблему в принципе(

Да, либо в правило в основном правиле или skipper_iterator  Улыбающийся
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Страниц: 1 2 [3] 4   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.383 секунд. Запросов: 23.