2015-12-29 6 views
6

मैं पार्स करना चाहता हूं (पहले उदाहरण में, केवल पहचानें, प्रतीकों को रखते हुए) लाटेक्स गणित। अभी, मुझे घुंघराले ब्रेसिज़ (उदा। 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'; 
} 

यह भी Available on Coliru है।

समस्या यह है, यह segfaults (मुझे स्पष्ट कारणों के लिए निश्चित है) और मेरे पास इसका कोई अन्य तरीका नहीं है, ठीक है, इसे अभिव्यक्त करना ... अभिव्यक्ति व्याकरण।

+0

आपकी समस्या [इस के समान है (लेकिन कहीं अधिक जटिल है)एक] (http://stackoverflow.com/questions/18611990/flipping-the-order-of-subrules-inside-a-rule-in-a-boostspirit-grammar-results)। मुझे विश्वास से बहुत दूर है कि [यह] (http://coliru.stacked-crooked.com/a/79e2edf0a6ff86d1) सही है, लेकिन देखें कि यह मदद करता है या नहीं। यदि भविष्य में आपको एएसटी बनाने की जरूरत है ... यह सुंदर नहीं होगा (अर्थपूर्ण कार्रवाई नरक)। उम्मीद है कि आपको एक बेहतर जवाब मिलेगा। पीएस: आपका 'char _- "_^{}" 'सही नहीं है' char_-lit (" _^{} ") के बराबर है, लेकिन' lit ("abc") 'बिल्कुल ठीक "abc" से मेल नहीं खाता "ए" "या" बी "या" सी "। – llonesmiz

+0

@cv_and_he वास्तव में आपका नमूना बाएं-रिकर्सन को हटा देता है और '{}' की मैला हैंडलिंग को ठीक करता है। यहां [एक अद्यतन जो दिखाता है] (http://coliru.stacked-crooked.com/a/30b2ee7981c52bab) यह कम से कम _matching_ समान परीक्षण मामलों (मुझे पूरा यकीन है कि एएसटी में कुछ अंतर है "लेकिन हम कर सकते हैं ओपी की जरूरत को बेहतर बनाने के लिए क्या कहना है, मुझे लगता है)। – sehe

उत्तर

4

मैंने अभी तक @cv_and_he द्वारा सुझाव नहीं देखा है, बल्कि अपने व्याकरण को स्वयं डिबग करने के बजाय। मैं इस के साथ आया था:

auto token  = lexeme [ +~char_("_^{} \t\r\n") ]; 
auto simple  = '{' >> sequence >> '}' | token; 
auto expr   = lexeme [ simple % char_("_^") ]; 
auto sequence_def = expr % +space; 

क्या मुझे लाया वहाँ मूल रूप से एक कदम-दर-कदम पर पुनर्विचार/वास्तविक व्याकरण कैसा दिखाई कल्पना थी।

यह मुझे दो प्रयासों ले लिया सही तरीके से सोचने के लिए "a b" को पार्स (पहली बार में मैं इसे एक बस एक और सबस्क्रिप्ट ऑपरेटर "काट दिया" char_(" _^") में प्राप्त करने के लिए, लेकिन मैं धारणा है कि के रूप में एक एएसटी के लिए नेतृत्व नहीं करेंगे मिला आप इसकी उम्मीद करते हैं। सुराग आप अंतरिक्ष के लिए एक कप्तान इस्तेमाल किया जा रहा है)।

अभी के लिए, वहाँ कोई एएसटी है, लेकिन हम सिर्फ "काटते" कच्चे स्ट्रिंग का मिलान नहीं हुआ का उपयोग कर .. x3::raw[...]

Live Coliru

//#define BOOST_SPIRIT_X3_DEBUG 
#include <iostream> 
#include <string> 

#include <boost/spirit/home/x3.hpp> 
namespace x3 = boost::spirit::x3; 

namespace grammar { 
    using namespace x3; 
    rule<struct _s> sequence { "sequence" }; 

    auto simple = rule<struct _s> {"simple"} = '{' >> sequence >> '}' | lexeme [ +~char_("_^{} \t\r\n") ]; 
    auto expr = rule<struct _e> {"expr"} = lexeme [ simple % char_("_^") ]; 
    auto sequence_def = expr % +space; 
    BOOST_SPIRIT_DEFINE(sequence) 
} 

int main() { 
    for (const std::string input : { 
      "a", 
      "a^b",  "a_b",  "a b", 
      "{a}^{b}", "{a}_{b}", "{a} {b}", 
      "a^{b_x y}", 
      "a^{b_x y}_z {v_x}^{{x^z}_y}" 
     }) 
    { 
     std::string output; // will only contain the characters as the grammar is defined above 
     auto first = input.begin(), last = input.end(); 
     bool result = x3::parse(first, last, x3::raw[grammar::sequence], output); 

     if (result) 
      std::cout << "Parse success: '" << output << "'\n"; 
     else 
      std::cout << "parse failed!\n"; 

     if (last!=first) 
      std::cout << "remaining unparsed: '" << std::string(first, last) << "'\n"; 
    } 
} 

आउटपुट:

Parse success: 'a' 
Parse success: 'a^b' 
Parse success: 'a_b' 
Parse success: 'a b' 
Parse success: '{a}^{b}' 
Parse success: '{a}_{b}' 
Parse success: '{a} {b}' 
Parse success: 'a^{b_x y}' 
Parse success: 'a^{b_x y}_z {v_x}^{{x^z}_y}' 

सक्षम डिबग जानकारी के साथ आउटपुट:

<sequence> 
<try>a</try> 
<expr> 
    <try>a</try> 
    <simple> 
    <try>a</try> 
    <success></success> 
    </simple> 
    <success></success> 
</expr> 
<success></success> 
</sequence> 
Parse success: 'a' 
<sequence> 
<try>a^b</try> 
<expr> 
    <try>a^b</try> 
    <simple> 
    <try>a^b</try> 
    <success>^b</success> 
    </simple> 
    <simple> 
    <try>b</try> 
    <success></success> 
    </simple> 
    <success></success> 
</expr> 
<success></success> 
</sequence> 
Parse success: 'a^b' 
<sequence> 
<try>a_b</try> 
<expr> 
    <try>a_b</try> 
    <simple> 
    <try>a_b</try> 
    <success>_b</success> 
    </simple> 
    <simple> 
    <try>b</try> 
    <success></success> 
    </simple> 
    <success></success> 
</expr> 
<success></success> 
</sequence> 
Parse success: 'a_b' 
<sequence> 
<try>a b</try> 
<expr> 
    <try>a b</try> 
    <simple> 
    <try>a b</try> 
    <success> b</success> 
    </simple> 
    <success> b</success> 
</expr> 
<expr> 
    <try>b</try> 
    <simple> 
    <try>b</try> 
    <success></success> 
    </simple> 
    <success></success> 
</expr> 
<success></success> 
</sequence> 
Parse success: 'a b' 
<sequence> 
<try>{a}^{b}</try> 
<expr> 
    <try>{a}^{b}</try> 
    <simple> 
    <try>{a}^{b}</try> 
    <sequence> 
     <try>a}^{b}</try> 
     <expr> 
     <try>a}^{b}</try> 
     <simple> 
      <try>a}^{b}</try> 
      <success>}^{b}</success> 
     </simple> 
     <success>}^{b}</success> 
     </expr> 
     <success>}^{b}</success> 
    </sequence> 
    <success>^{b}</success> 
    </simple> 
    <simple> 
    <try>{b}</try> 
    <sequence> 
     <try>b}</try> 
     <expr> 
     <try>b}</try> 
     <simple> 
      <try>b}</try> 
      <success>}</success> 
     </simple> 
     <success>}</success> 
     </expr> 
     <success>}</success> 
    </sequence> 
    <success></success> 
    </simple> 
    <success></success> 
</expr> 
<success></success> 
</sequence> 
Parse success: '{a}^{b}' 
<sequence> 
<try>{a}_{b}</try> 
<expr> 
    <try>{a}_{b}</try> 
    <simple> 
    <try>{a}_{b}</try> 
    <sequence> 
     <try>a}_{b}</try> 
     <expr> 
     <try>a}_{b}</try> 
     <simple> 
      <try>a}_{b}</try> 
      <success>}_{b}</success> 
     </simple> 
     <success>}_{b}</success> 
     </expr> 
     <success>}_{b}</success> 
    </sequence> 
    <success>_{b}</success> 
    </simple> 
    <simple> 
    <try>{b}</try> 
    <sequence> 
     <try>b}</try> 
     <expr> 
     <try>b}</try> 
     <simple> 
      <try>b}</try> 
      <success>}</success> 
     </simple> 
     <success>}</success> 
     </expr> 
     <success>}</success> 
    </sequence> 
    <success></success> 
    </simple> 
    <success></success> 
</expr> 
<success></success> 
</sequence> 
Parse success: '{a}_{b}' 
<sequence> 
<try>{a} {b}</try> 
<expr> 
    <try>{a} {b}</try> 
    <simple> 
    <try>{a} {b}</try> 
    <sequence> 
     <try>a} {b}</try> 
     <expr> 
     <try>a} {b}</try> 
     <simple> 
      <try>a} {b}</try> 
      <success>} {b}</success> 
     </simple> 
     <success>} {b}</success> 
     </expr> 
     <success>} {b}</success> 
    </sequence> 
    <success> {b}</success> 
    </simple> 
    <success> {b}</success> 
</expr> 
<expr> 
    <try>{b}</try> 
    <simple> 
    <try>{b}</try> 
    <sequence> 
     <try>b}</try> 
     <expr> 
     <try>b}</try> 
     <simple> 
      <try>b}</try> 
      <success>}</success> 
     </simple> 
     <success>}</success> 
     </expr> 
     <success>}</success> 
    </sequence> 
    <success></success> 
    </simple> 
    <success></success> 
</expr> 
<success></success> 
</sequence> 
Parse success: '{a} {b}' 
<sequence> 
<try>a^{b_x y}</try> 
<expr> 
    <try>a^{b_x y}</try> 
    <simple> 
    <try>a^{b_x y}</try> 
    <success>^{b_x y}</success> 
    </simple> 
    <simple> 
    <try>{b_x y}</try> 
    <sequence> 
     <try>b_x y}</try> 
     <expr> 
     <try>b_x y}</try> 
     <simple> 
      <try>b_x y}</try> 
      <success>_x y}</success> 
     </simple> 
     <simple> 
      <try>x y}</try> 
      <success> y}</success> 
     </simple> 
     <success> y}</success> 
     </expr> 
     <expr> 
     <try>y}</try> 
     <simple> 
      <try>y}</try> 
      <success>}</success> 
     </simple> 
     <success>}</success> 
     </expr> 
     <success>}</success> 
    </sequence> 
    <success></success> 
    </simple> 
    <success></success> 
</expr> 
<success></success> 
</sequence> 
Parse success: 'a^{b_x y}' 
<sequence> 
<try>a^{b_x y}_z {v_x}^{{</try> 
<expr> 
    <try>a^{b_x y}_z {v_x}^{{</try> 
    <simple> 
    <try>a^{b_x y}_z {v_x}^{{</try> 
    <success>^{b_x y}_z {v_x}^{{x</success> 
    </simple> 
    <simple> 
    <try>{b_x y}_z {v_x}^{{x^</try> 
    <sequence> 
     <try>b_x y}_z {v_x}^{{x^z</try> 
     <expr> 
     <try>b_x y}_z {v_x}^{{x^z</try> 
     <simple> 
      <try>b_x y}_z {v_x}^{{x^z</try> 
      <success>_x y}_z {v_x}^{{x^z}</success> 
     </simple> 
     <simple> 
      <try>x y}_z {v_x}^{{x^z}_</try> 
      <success> y}_z {v_x}^{{x^z}_y</success> 
     </simple> 
     <success> y}_z {v_x}^{{x^z}_y</success> 
     </expr> 
     <expr> 
     <try>y}_z {v_x}^{{x^z}_y}</try> 
     <simple> 
      <try>y}_z {v_x}^{{x^z}_y}</try> 
      <success>}_z {v_x}^{{x^z}_y}</success> 
     </simple> 
     <success>}_z {v_x}^{{x^z}_y}</success> 
     </expr> 
     <success>}_z {v_x}^{{x^z}_y}</success> 
    </sequence> 
    <success>_z {v_x}^{{x^z}_y}</success> 
    </simple> 
    <simple> 
    <try>z {v_x}^{{x^z}_y}</try> 
    <success> {v_x}^{{x^z}_y}</success> 
    </simple> 
    <success> {v_x}^{{x^z}_y}</success> 
</expr> 
<expr> 
    <try>{v_x}^{{x^z}_y}</try> 
    <simple> 
    <try>{v_x}^{{x^z}_y}</try> 
    <sequence> 
     <try>v_x}^{{x^z}_y}</try> 
     <expr> 
     <try>v_x}^{{x^z}_y}</try> 
     <simple> 
      <try>v_x}^{{x^z}_y}</try> 
      <success>_x}^{{x^z}_y}</success> 
     </simple> 
     <simple> 
      <try>x}^{{x^z}_y}</try> 
      <success>}^{{x^z}_y}</success> 
     </simple> 
     <success>}^{{x^z}_y}</success> 
     </expr> 
     <success>}^{{x^z}_y}</success> 
    </sequence> 
    <success>^{{x^z}_y}</success> 
    </simple> 
    <simple> 
    <try>{{x^z}_y}</try> 
    <sequence> 
     <try>{x^z}_y}</try> 
     <expr> 
     <try>{x^z}_y}</try> 
     <simple> 
      <try>{x^z}_y}</try> 
      <sequence> 
      <try>x^z}_y}</try> 
      <expr> 
       <try>x^z}_y}</try> 
       <simple> 
       <try>x^z}_y}</try> 
       <success>^z}_y}</success> 
       </simple> 
       <simple> 
       <try>z}_y}</try> 
       <success>}_y}</success> 
       </simple> 
       <success>}_y}</success> 
      </expr> 
      <success>}_y}</success> 
      </sequence> 
      <success>_y}</success> 
     </simple> 
     <simple> 
      <try>y}</try> 
      <success>}</success> 
     </simple> 
     <success>}</success> 
     </expr> 
     <success>}</success> 
    </sequence> 
    <success></success> 
    </simple> 
    <success></success> 
</expr> 
<success></success> 
</sequence> 
Parse success: 'a^{b_x y}_z {v_x}^{{x^z}_y}' 
+0

आप अभी भी [रिकॉर्ड किए गए लाइव कोडिंग सत्र] (https://www.livecoding.tv/video/rethinking-x3-latex-maths-expression-grammar/) में मुझे ठोकर और झुकाव देखने का आनंद ले सकते हैं। – sehe

संबंधित मुद्दे

 संबंधित मुद्दे