Я хочу разобрать (в первую очередь, только распознать, сохранив символы) математику LaTeX. Прямо сейчас у меня проблемы с надстрочными и нижними индексами в сочетании с фигурными скобками (например, a^{bc}
и их комбинациями, у меня базовый a^b
работает нормально). Минимальный пример (настолько короткий, насколько это возможно, сохраняя при этом удобочитаемость):
#include <iostream>
using std::cout;
#include <string>
using std::string;
#include <boost/spirit/home/x3.hpp>
namespace x3 = boost::spirit::x3;
using x3::space;
using x3::char_;
using x3::lit;
using x3::repeat;
x3::rule<struct scripts, string> scripts = "super- and subscripts";
x3::rule<struct braced_thing, string> braced_thing = "thing optionaly surrounded by curly braces";
x3::rule<struct superscript, string> superscript = "superscript";
x3::rule<struct subscript, string> subscript = "subscript";
// main rule: any number of items with or without braces
auto const scripts_def = *braced_thing;
// second level main rule: optional braces, and any number of characters or sub/superscripts
auto const braced_thing_def = -lit('{') >> *(subscript | superscript | repeat(1)[(char_ - "_^{}")]) >> -lit('}');
// superscript: things of the form a^b where a and b can be surrounded by curly braces
auto const superscript_def = braced_thing >> '^' >> braced_thing;
// subscript: things of the form a_b where a and b can be surrounded by curly braces
auto const subscript_def = braced_thing >> '_' >> braced_thing;
BOOST_SPIRIT_DEFINE(scripts)
BOOST_SPIRIT_DEFINE(braced_thing)
BOOST_SPIRIT_DEFINE(superscript)
BOOST_SPIRIT_DEFINE(subscript)
int main()
{
const string input = "a^{b_x y}_z {v_x}^{{x^z}_y}";
string output; // will only contain the characters as the grammar is defined above
auto first = input.begin();
auto last = input.end();
const bool result = x3::phrase_parse(first, last,
scripts,
space,
output);
if(first != last)
std::cout << "partial match only:\n" << output << '\n';
else if(!result)
std::cout << "parse failed!\n";
else
std::cout << "parsing succeeded:\n" << output << '\n';
}
Он также доступен на Coliru.
Проблема в том, что это segfaults (я уверен, по понятным причинам), и у меня нет другого способа, ну, выразить это в... грамматике выражений.
char_-"_^{}"
неверен, он эквивалентенchar_-lit("_^{}")
, ноlit("abc")
точно соответствует abc, а не a, b или c. - person llonesmiz   schedule 29.12.2015{}
. Вот обновление, которое показывает, что оно как минимум соответствует одному и тому же тестовые случаи (я почти уверен, что есть некоторая разница в предоставляемых AST, но мы не можем сказать, что лучше соответствует потребностям OP, я думаю). - person sehe   schedule 30.12.2015