Apologies if this question has been answered before.
I want to insert a small DSL into a server application I work on. The syntax is very simple and even at this early stage I am stumped. I just can't get my head around how to construct the syntax in spirit.
Here is an example of the syntax I want to test for:
WHERE [not] <condition> [ and | or <condition> ] <command> [parameters]
The WHERE clause will select a number of objects from an internal store by testing named properties on them. The vector of selected objects is then passed as input to the command object.
There are 2 possible tests I want to perform on each object:
<property> = "value"
and
<property> like <regexp>
There are 2 commands also:
print <propertyName> [, <propertyName> [...]]
and
set <propertyName> = "value" [, <propertyName> = "value" [...] ]
so examples of the syntax would be:
where currency like "GBP|USD" set logging = 1, logfile = "myfile"
and
where not status = "ok" print ident, errorMessage
I know this is a big ask, but I am wondering if there are any spirit experts out there who can knock out this syntax in a few seconds flat? I got as far as parsing LIKE and =, but got stuck when trying to mix that with AND, OR and NOT. The problem for me is not knowing where to start when thinking about how spirit will tackle this.
See http://liveworkspace.org/code/3HUzjS for a proof of concept.
What I usually do first, is imagine how I'd like to store the parsed data.
Data types
I like to stick to standard containers,
boost::variant
(and sometimesboost::optional
). Read from the bottom up to see how simple it is, top-down:Notes:
regex
instead of requiring a switch on operator type (=
vs.like
) in the processing code.)and
vs.or
).set
orprint
command be unique.filter
by giving the first item a 'no-op' logic combination.Grammar
With this target structure in place, writing the grammar becomes relatively straightforward:
Notes:
\
an escape characterthe only 'tricky' business there is to make sure filter (conditions) starts with 'WHERE', and each subsequent condition must start with 'AND'/'OR'. It uses a semantic action
to check that the resulting list (
vector
) of filters is empty at that time during parsingthe
attr(...)
idiom is used to get a default value for an optional keyword (NOT
). The keyword is only optional in the grammar, not in the AST:I have put together a demo, that prints the AST back using Spirit Karma. Note that I didn't make a lot of effort to make the syntax roundtrip:
like
operators get printed as equality to regex (m/.../
)Output of test program:
Full test program
Note: in addition to
parser
it also contains agenerator
to print the parsed AST data types back.Live On Coliru