Chcę analizować (w pierwszej kolejności rozpoznawać tylko, zachowując symbole) LaTeX matematyki. W tej chwili mam problemy z super i indeksami dolnymi, w połączeniu z nawiasami klamrowymi (np. a^{bc}
i ich kombinacjami, mam podstawową a^b
działającą bez zarzutu). Minimalny przykład (tak krótki, jak to tylko możliwe przy zachowaniu czytelności):Jak uruchomić tę regułę rekursywną?
#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';
}
To również Available on Coliru.
Problem jest, to zwraca błąd (jestem pewien, że z oczywistych powodów) i nie mam innego sposobu, dobrze, wyrażając to w ... gramatyki ekspresji.
Twój problem jest podobny (ale daleko bardziej skomplikowane) do [tego jeden] (http://stackoverflow.com/questions/18611990/flipping-The-order-subrules-inside-a-rule-in-a-boostspirit-grammar-results). Nie jestem pewien, czy [to] (http://coliru.stacked-crooked.com/a/79e2edf0a6ff86d1) jest poprawny, ale zobacz, czy to pomaga. Jeśli w przyszłości musisz stworzyć AST ... nie będzie to piękne (semantyczne działanie piekła). Mam nadzieję, że otrzymasz lepszą odpowiedź. PS: Twoje 'char _-" _^{} "' nie jest poprawne to odpowiednik 'char_-lit (" _^{} ")' ale 'lit (" abc ")' pasuje dokładnie "abc" nie "a "lub" b "lub" c ". – llonesmiz
@ cv_and_he Rzeczywiście twoja próbka usuwa lewą rekursję i naprawia niechlujstwo w obsłudze '{}'. Oto [aktualizacja, która pokazuje] (http://coliru.stacked-crooked.com/a/30b2ee7981c52bab) to przynajmniej _przypadkowanie_wszystkich takich samych przypadków testowych (jestem prawie pewny, że istnieją pewne różnice w AST "dostał", ale możemy powiedzieć, co lepiej odpowiada potrzebom PO, jak sądzę). – sehe