Использование указателя на парсер в boost :: spirit

В основном я занимаюсь парсером выражений. Поскольку мне нужна как можно более высокая производительность, и, согласно документации, построение грамматики может быть довольно медленным, я хотел бы повторно использовать грамматику и связать таблицу символов непосредственно перед синтаксическим анализом. Поскольку у клиента грамматики, вероятно, будет таблица символов, которая создается и поддерживается перед синтаксическим анализом, в идеале я бы также хотел избежать копирования фактической таблицы, что приводит меня к следующему (упрощенному) коду для перевода терминов:

qi::symbols< char, double >* m_Symbols;
qi::rule< Iterator, double(), ascii::space_type > m_Val;

m_Val = qi::int_[ _val = boost::phoenix::static_cast_< double >( boost::spirit::_1 ) ] | qi::double_ | m_Symbols;

Проблема здесь в m_Symbols. Я бы хотел, чтобы m_Val содержал m_Symbols по ссылке, поскольку, когда мы привязываем таблицу символов, я естественным образом изменяю указатель, что, как я полагаю, можно каким-то образом решить с помощью boost :: phoenix :: ref? Но более серьезная проблема заключается в том, что я не могу использовать указатель на парсеры при создании нового парсера. Используя разыменование в выражении разыменования m_Symbols сразу, что нежелательно, я хочу отложить разыменование, чтобы разобрать время.


person Ylisar    schedule 09.03.2011    source источник
comment
Это действительно кажется неправильным подходом к сокращению количества экземпляров грамматики. Почему бы просто не создать статический / одноэлементный экземпляр грамматики и сделать его не копируемым?   -  person ildjarn    schedule 09.03.2011
comment
К сожалению, мне все равно придется привязать таблицу символов перед синтаксическим анализом, что приведет к той же проблеме.   -  person Ylisar    schedule 10.03.2011


Ответы (1)


Я считаю простой

qi::symbols<char, double>* m_Symbols;
qi::rule<Iterator, double(), ascii::space_type> m_Val;

m_Val = qi::int_ | qi::double_ | qi::lazy(*m_Symbols);

должен делать то, что вам нужно. Синтаксический анализатор lazy (см. здесь) оценивает свой аргумент (многократно) только во время синтаксического анализа.

person hkaiser    schedule 09.03.2011
comment
Спасибо за помощь, здорово, что вам поможет эксперт! К сожалению, я уже пробовал это решение, и, похоже, qi :: lazy () не очень рад принять это выражение. Я получаю следующую ошибку от MSVC 2008: 1 ›‹deleted› /main.cpp(75): error C2784: 'proto :: terminal‹ boost :: phoenix ::actor ‹Eval› ›:: type boost :: spirit: : lazy (const boost :: phoenix :: Актер ‹Eval› &) ': не удалось вывести аргумент шаблона для' const boost :: phoenix ::actor ‹Eval› & 'from' boost :: spirit :: qi :: symbols ‹Char, T› 'Что наводит меня на мысль, что m_Symbols разыменовывается перед передачей в lazy ()? - person Ylisar; 10.03.2011
comment
Казалось бы, следующий трюк: qi :: lazy (* boost :: phoenix :: val (boost :: phoenix :: ref (m_Symbols))). Val действует как оболочка для разыменования, ref, чтобы убедиться, что указатель не копируется. - person Ylisar; 10.03.2011