So I want to write a... well... not-so-simple parser with boost::spirit::qi. I know the bare basics of boost spirit, having gotten acquainted with it for the first time in the past couple of hours.
Basically I need to parse this:
# comment
# other comment
set "Myset A"
{
figure "AF 1"
{
i 0 0 0
i 1 2 5
i 1 1 1
f 3.1 45.11 5.3
i 3 1 5
f 1.1 2.33 5.166
}
figure "AF 2"
{
i 25 5 1
i 3 1 3
}
}
# comment
set "Myset B"
{
figure "BF 1"
{
f 23.1 4.3 5.11
}
}
set "Myset C"
{
include "Myset A" # includes all figures from Myset A
figure "CF"
{
i 1 1 1
f 3.11 5.33 3
}
}
Into this:
struct int_point { int x, y, z; };
struct float_point { float x, y, z; };
struct figure
{
string name;
vector<int_point> int_points;
vector<float_point> float_points;
};
struct figure_set
{
string name;
vector<figure> figures
};
vector<figure_set> figure_sets; // fill with the data of the input
Now, obviously having somebody write it for me would be too much, but can you please provide some tips on what to read and how to structure the grammar and parsers for this task?
And also... it may be the case that boost::spirit is not the best library I could use for the task. If so, which one is?
EDIT: Here's where I've gotten so far. But I'm not yet sure how to go on: http://liveworkspace.org/code/212c31dfc0b6fbdf6c462d8d931c0e9f
I am able to read a single figure but, I don't yet have an idea how to parse a set of figures.
Here's my take on it
I believe the rule that will have been the blocker for you would be
This is actually a symptom of the fact that you parse inter-mixed
i
andf
lines into separate containers.See below for an alternative.
Here's my full code: test.cpp
It outputs the parsed data as a verification: output.txt
You will note that
int_points
precede allfloat_points
)3.0
instead of3
to show that the type if float.Alternative
Have something that keeps the actual point lines in original order:
Now the rules become simply:
Note the elegance in
And the output stays in the exact order of the input: output.txt
Once again, full demo code (on github only): test.cpp
Bonus update
Finally, I made my first proper Karma grammar to output the results:
That was actually considerably more comfortable than I had expected. See it in the lastest version of the fully updated gist: test.hpp