C++, Boost, Spirit: In Identifier-Ketten keine Blanks erlauben?

Gast #6190739
Lesenswert?
• ▲
▼
Ich versuche (erstmals mit Spirit) mit '.' verkettete Identifier zu 
parsen (wird Teil eines komplexeren Expression Parsers)

leider dürfen jetzt gerade zwischen den Identifieren und Punkten auch 
noch Blanks sein - was für die restliche Expression-Parser Entwicklung 
sehr gut ist aber in diesem Fall leider nicht

Ich habe versucht mit qi::lexeme und qi::no_skip zu arbeiten
aber leider scheint qi::lexeme nicht auf ganze Parser wie den Identifier 
anwendbar zu sein und mit no_skip wird gar nichts mehr geparst

d.h. die beiden letzten von den 4 Tests sollten nicht parsen

Zum Online kompilieren und spielen:
https://wandbox.org/permlink/o5kcYtUQEfKZqJgw
1
#include <iostream>
2
#include <iomanip>
3
#include <string>
4
#include <boost/spirit/include/qi.hpp>
5
#include <boost/spirit/include/support_utree.hpp>
6

7
namespace qi = boost::spirit::qi;
8
using boost::spirit::utree;
9

10
int main() {
11
    auto tests = std::vector<std::string> {
12
         "a", // ok
13
         "a.b", // ok
14
         "a . b", // nok
15
         "a . b. c" // nok
16
    };
17
    for (std::string str : tests) {
18
        auto iter = str.begin(), end = str.end();
19

20
        qi::rule<std::string::iterator, qi::blank_type, utree()> identifier 
21
            = qi::lexeme[qi::ascii::alpha >> *(qi::ascii::alnum | '_')];
22

23
        qi::rule<std::string::iterator, qi::blank_type, utree()> identifier_chain 
24
            = identifier >> *('.' >> identifier);
25

26
        utree ut;
27
        bool r = qi::phrase_parse(iter, end, identifier_chain, qi::blank, ut);
28

29
        if (r && iter == end) {
30
            std::cout << "OK: \n" << ut << "\n";
31
        }
32
        else {
33
            std::string rest(iter, end);
34
            std::cout << "Failed\nstopped at: \": " << rest << "\"\n";
35
        }
36
        std::cout << "----\n";
37
    }
38
    return 0;
39
}

Ziel:

so was will ich am Ende parsen können
1
"a.b.c.d[x,y][a,b].z.b[0].a(y,d,b)[39,2].x[3]"

da brauche ich wohl noch ein bisschen aber das wird schon
nur eben so whitespace Skipping blockiert mich gerade

TODOs die noch so auf meiner Liste sind:

double-quoted strings MIT Escaping:
1
double_quoted_string = '"' >> qi::no_skip[+~qi::char_('"')] >> '"';

wie kann man Escaping wie in CSV-Dateien mit einem weiteren " erreichen

also: "Hallo ""Spirit"" wie gehts"
Gast #6190760
Lesenswert?
• ▲
▼
und natürlich kann ich mein identifier_chain rule auch "manuell" 
ausprägen
1
qi::rule<std::string::iterator, qi::blank_type, utree()> identifier_chain 
2
  = qi::lexeme[qi::ascii::alpha >> *(qi::ascii::alnum | '_') 
3
  >> *('.' >> qi::ascii::alpha >> *(qi::ascii::alnum | '_'))];

dann geht es auch - ist aber reichlich redundant und was ist dann der 
Sinn von den Rules?
Gast #6191397
Lesenswert?
• ▲
▼
bei Stackoverflow wurde mir geholfen
1
        qi::rule<std::string::const_iterator, utree()>
2
            identifier = qi::ascii::alpha >> *(qi::ascii::alnum | '_'),
3
            identifier_chain = identifier >> *('.' >> identifier);

einfach den qi::blank_type weglassen dann ist lexeme default

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren