I´m a student and need to write a Parser in C++ with the Boost-Library.
Therefore I write a grammer in QI because I need to parse into a struct. So far, so good.
I will give you some example-code. I think it is easier than writing the whole program down.
Description: So first we take a txt-File and read it, then the parser goes over it, says "Parsing is ok!" and parse into the struct. Our output is the struct in the console.
That works fine, now to some code examples. Here you can see the Grammar in Boost Spirit QI:
subject %= lexeme[lit("Fach: ") >> +(char_("a-zA-Z")) >> lit("\n")]; //works!
dozent %= lexeme[lit("Dozent: ") >> +(char_("a-zA-Z")) >> lit("\n")];
date %= lexeme[lit("Datum: ") >> digit >> digit >> lit("-") >> digit >> digit >> lit("-") >> digit >> digit >> digit >> digit >> lit("\n")];
count %= lexeme[lit("Anzahl: ") >> +digit >> lit("\n")];
points %= lexeme[+digit >> lit("\t")];
mark %= lexeme[digit >> lit("\n")];
matnumber %= lexeme[(digit >> digit >> digit >> punct >> digit >> digit >> digit) >> lit("\t")];
student %= matnumber >> points >> mark;
start %= subject >> dozent >> date >> count >> student;
That works fine, the rule for student brings the problem that we have an element with three parts. Matnumber, Points, and mark. That you can imagine what I mean, here the TXT-File which we try to parse:
Subject: Physics
Dozent: Wayne
Datum: 20-10-2014
Anzahl: 20
729.888 33 5
185.363 35 5
The last two lines are the rule student. And in the txt-File we have more than these two lines.
That we can take these lines as "student" we wrote a vector in our struct with typedef:
typedef boost::fusion::vector<string, string, string> student_t;
then we will use it in our struct:
struct klausur
{
string str_subject;
string str_dozent;
string str_date;
string count;
string matr_nr;
string points;
string mark;
string ende;
student_t student;
void ToString()
{
cout << "Struct.Fach: " << str_subject << endl;
cout << "Struct.Dozent: " << str_dozent << endl;
cout << "Struct.Datum: " << str_date << endl;
cout << "Struct.Anzahl: " << count << endl;
cout << "Struct.Mat_Nr: " << matr_nr << endl;
cout << "Struct.Punkte: " << points << endl;
cout << "Struct.Note: " << mark << endl;
cout << "Struct.Student<0>: " << vec::at_c<0>(student);
cout << "Struct.Student<1>: " << vec::at_c<1>(student);
cout << "Struct.Student<2>: " << vec::at_c<2>(student);
}
};
Then we have our BOOST_ADAPT_STRUCT like this:
BOOST_FUSION_ADAPT_STRUCT(
client::klausur,
(string, str_subject)
(string, str_dozent)
(string, str_date)
(string, count)
(string, matr_nr)
(string, points)
(string, mark)
(student_t, student)
)
You see we have the typedef down there.
And then we have our rules in the Grammar.
qi::rule<Iterator, string(), ascii::space_type> subject;
qi::rule<Iterator, string(), ascii::space_type> dozent;
qi::rule<Iterator, string(), ascii::space_type> date;
qi::rule<Iterator, string(), ascii::space_type> count;
qi::rule<Iterator, string(), ascii::space_type> matnumber;
qi::rule<Iterator, string(), ascii::space_type> points;
qi::rule<Iterator, string(), ascii::space_type> mark;
qi::rule<Iterator, boost::fusion::vector<boost::fusion::vector<std::string, std::string, std::string> >()> student;
And there is the hopefully final problem for our project...
We don´t know which datatype the qi:rule needs that the BOOST_ADAPT... works fine with it. All the other points are strings, but don´t know how to implement the own vector we created.
All the other rules are working fine and are in the struct later just the vector makes problems.
Has somebody an idea about that? I can upload more files and code-snippets if you need, but I still think that it´s maybe just a small problem that I can´t see. I look around for many boost topics but did not found the right thing.
I have to add the info that I am just a beginner, so maybe I did not explain everything right and... yeah. Hope you understand it. Also my english is not the best...
Thank you in advance for your help.
William