Предварительно обработайте пользовательский текстовый файл для удаления комментариев с помощью Boost Spirit

У меня есть текст, содержащий "уравнения", например:

-- This is comment
ABC:= 121-XY1/7 > 45 OR SS >= 3
    ZY2 AND -- This is another comment
    (JKL * PQR) < 75;

JKL:= PP1 OR 
      PP2/2 XOR PP3;

ZZ_1:=A-B > 0 XOR (B2 % GH == 6 AND 
   SP == 4
-- Again a comment
    NOT AX > GF < 2 OR C*AS2 >= 5);

Я решил использовать дух ускорения для анализа этого текста, на данный момент мне просто нужно знать свои операнды и операторы.

Я сослался на этот хороший ответ (спасибо sehe :)), чтобы написать грамматику выражения (операторы отношения еще не написаны)

Однако я не могу убрать свои комментарии с помощью: -

     qi::phrase_parse(input.begin()
     ,input.end()
     ,p >> ';' // parser object
     ,qi::space | "--" >> *(qi::char_ - qi::eol) >> qi::eol
     ,result //expression object,  (boost::variant with boost::recursive_wrapper)
     ); 

поскольку это дает несколько ошибок, в некоторых сообщении говорится, что нужно настроить файл заголовка повышения.

Итак, я использую другую грамматику, чтобы сначала убрать комментарий, используя:

     qi::phrase_parse(input.begin()
     ,input.end()
     ,qi::char_ >> *qi::char_ 
     , qi::space | "--" >> *(qi::char_ - qi::eol) >> qi::eol
     ,stripped // std::string 
     );

Но это дает мне текст с удаленными пробелами и комментариями:

ABC:=121-XY1/7>45ORSS>=3ZY2AND(JKL*PQR)<75;JKL:=PP1ORPP2/2XORPP3;ZZ_1:=A-B>0XOR(B2%GH==6ANDSP==4NOTAX>GF<2ORC*AS2>=5);

Итак, вопрос в том, как я могу удалить только комментарии, сохранив место и новые строки?

Использование: Boost версии 1.55.0


person P0W    schedule 01.02.2014    source источник
comment
Я обрабатываю текстовый файл, в котором мне также нужно вырезать комментарии (C #, а не C ++), и я просто делаю это с помощью Regex, чтобы удалить все после и включая маркер комментария. Таким образом сохраняется структура файла. Я делаю этот шаг до того, как проанализирую свой файл. В то время как что-то вроде духа предназначено для того, чтобы разделить файл на токены, не так ли?   -  person Peter M    schedule 01.02.2014
comment
@PeterM Да, с регулярным выражением python / perl это будет вопрос нескольких строк, но меня как бы интересует функциональность, подобная компилятору. Например, правильная оценка выражений, выявление ошибок и т. Д.   -  person P0W    schedule 01.02.2014
comment
Я думаю, на этом этапе вам нужно думать как препроцессор C / C ++, а не как синтаксический анализатор / компилятор.   -  person Peter M    schedule 01.02.2014
comment
это то, что вам нужно?   -  person llonesmiz    schedule 01.02.2014
comment
О вашей исходной ситуации ... Как вы объявляете свой тип шкипера в своем объекте парсера? Если вставленный вами код - это то, что вы используете, вам нужно будет использовать decltype или BOOST_TYPEOF. Если бы это была ваша проблема (а я делаю снимок в темноте), я считаю, что обычным решением является создание грамматики шкипера (что-то вроде это).   -  person llonesmiz    schedule 01.02.2014
comment
@cv_and_he Спасибо! И я не знаю, почему я не смог увидеть вывод с помощью phrase_parse(f,l,qi::char_ >> *qi::char_ ,"--" >> *(qi::char_ - qi::eol) >> qi::eol,strip); (пока я не перенаправил вывод в текстовый файл), который в основном совпадает с тем, что вы сказали, если я прав? Пожалуйста, ответьте, я приму. Также относительно начального решения, не могли бы вы рассказать, как определить грамматику для оператора отношения, подобного this? а также включить шкипера, чтобы пропустить комментарий. Я попробовал вышеуказанный пост, но это не сработало   -  person P0W    schedule 01.02.2014


Ответы (1)


Ваш точный образец кода отсутствует. Разрешите мне добавить образец шкипера к этой «грамматике логических выражений», на которую вы связались:

std::string const input = 
        "a and\n"
        "-- abacadabra\n"
        "b;";

typedef std::string::const_iterator It;

// ADDED: allow comments
qi::rule<It> skip_ws_and_comments 
    = qi::space 
    | "--" >> *(qi::char_-qi::eol) >> qi::eol
    ;

parser<It, qi::rule<It> > p;

Это все необходимые изменения. Выход:

result: (a & b)

См. Live On Coliru

person sehe    schedule 01.02.2014
comment
Возможно, вам может пригодиться версия c ++ 03: coliru.stacked-crooked.com/a/ aaaa0971c0b3fed2 - person sehe; 02.02.2014
comment
Спасибо ! Я ждал вас: D Мой код из всех ваших ответов :) Любые предложения / doc / отвечает по грамматике для операторов отношения, аналогичных операторам airthmetic? - person P0W; 02.02.2014
comment
@ P0W Просто обобщите make_binop, чтобы распознать более одного токена char: coliru.stacked-crooked.com / a / 37faa9423bb47bbc (ну и немного очистки. Правило №1: чистый код делает разум ясным) - person sehe; 02.02.2014
comment
Благодаря тонну ! Я только начал изучать Boost Spirit, хотел, чтобы он был в одном из моих проектов, и ваши замечательные ответы очень мне пригодятся. - person P0W; 02.02.2014