[proto][spirit] parsing into proto expressions

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

[proto][spirit] parsing into proto expressions

Igor R.
Hi,

Long story short: I would like to create proto expressions at run-time
using spirit parsers. Would it be possible?
More in details: I'd like to parse disassembler output, creating proto
expression template for instruction and its operands.
Lets assume we define proto expressions that would allow to express
the following asm:
"lea eax, [ebx + 2 * ecx]"
like this:
BOOST_PROTO_AUTO(lea_instr, eax = &*(ebx + 2 * ecx)); // registers and
immediates are proto terminals
Of course, we can't write such an expression in C++ code, because the
actual operands get known after the asm string is parsed.
So we can express any "lea" in the code (at compile-time) in a more
general form, using placeholders: _1 = &_2;
Then, when the parser matches "lea", we need to parse and create at
run-time the actual operands, i.e. to substitute _1 with eax and _2
with *(ebx + 2 * ecx).

I'd appreciate any pointer!

Thanks.
_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [proto][spirit] parsing into proto expressions

llonesmiz
Igor R. wrote
Hi,

Long story short: I would like to create proto expressions at run-time
using spirit parsers. Would it be possible?
More in details: I'd like to parse disassembler output, creating proto
expression template for instruction and its operands.
Lets assume we define proto expressions that would allow to express
the following asm:
"lea eax, [ebx + 2 * ecx]"
like this:
BOOST_PROTO_AUTO(lea_instr, eax = &*(ebx + 2 * ecx)); // registers and
immediates are proto terminals
Of course, we can't write such an expression in C++ code, because the
actual operands get known after the asm string is parsed.
So we can express any "lea" in the code (at compile-time) in a more
general form, using placeholders: _1 = &_2;
Then, when the parser matches "lea", we need to parse and create at
run-time the actual operands, i.e. to substitute _1 with eax and _2
with *(ebx + 2 * ecx).

I'd appreciate any pointer!

Thanks.
I'm not an expert in either Spirit or Proto but my understanding is that Spirit requires specific (fixed) types as the result of its parsers and a proto expression generated as you intend wouldn't fit in that model(unless you use some kind of type erasure, but I don't know if that would be even possible).

I think what you need to use is Boost.Metaparse (in Boost 1.61). Abel Sinkovics has a great tutorial (sadly not completely up-to-date with the most recent version, but there are very little differences) at https://github.com/sabel83/metaparse_tutorial (the real interesting part is in "lab 6", the rest is a great introduction to metaprogramming and mpl conventions). I think this answer(http://stackoverflow.com/questions/17783393/how-to-parse-text-for-a-dsl-at-compile-time/17807607#17807607) could also be useful. It's not as well explained but it's up-to-date and tries to compare Metaparse with a Spirit approach.
Reply | Threaded
Open this post in threaded view
|

Re: [proto][spirit] parsing into proto expressions

llonesmiz
llonesmiz wrote
Igor R. wrote
Hi,

Long story short: I would like to create proto expressions at run-time
using spirit parsers. Would it be possible?
More in details: I'd like to parse disassembler output, creating proto
expression template for instruction and its operands.
Lets assume we define proto expressions that would allow to express
the following asm:
"lea eax, [ebx + 2 * ecx]"
like this:
BOOST_PROTO_AUTO(lea_instr, eax = &*(ebx + 2 * ecx)); // registers and
immediates are proto terminals
Of course, we can't write such an expression in C++ code, because the
actual operands get known after the asm string is parsed.
So we can express any "lea" in the code (at compile-time) in a more
general form, using placeholders: _1 = &_2;
Then, when the parser matches "lea", we need to parse and create at
run-time the actual operands, i.e. to substitute _1 with eax and _2
with *(ebx + 2 * ecx).

I'd appreciate any pointer!

Thanks.
I'm not an expert in either Spirit or Proto but my understanding is that Spirit requires specific (fixed) types as the result of its parsers and a proto expression generated as you intend wouldn't fit in that model(unless you use some kind of type erasure, but I don't know if that would be even possible).

I think what you need to use is Boost.Metaparse (in Boost 1.61). Abel Sinkovics has a great tutorial (sadly not completely up-to-date with the most recent version, but there are very little differences) at https://github.com/sabel83/metaparse_tutorial (the real interesting part is in "lab 6", the rest is a great introduction to metaprogramming and mpl conventions). I think this answer(http://stackoverflow.com/questions/17783393/how-to-parse-text-for-a-dsl-at-compile-time/17807607#17807607) could also be useful. It's not as well explained but it's up-to-date and tries to compare Metaparse with a Spirit approach.
Sorry, I have failed to consider your runtime requirements. If you need to input your asm code at runtime that would disqualify the Metaparse approach. If your use case is simply to write the expressions in your code in a style similar to your "BOOST_PROTO_AUTO(lea_instr, eax = &*(ebx + 2 * ecx))" then I think it could work.