One of my programs accepts a commands (like kill foo
) at runtime. Think of it as a little domain-specific language. Here are a few examples:
kill
kill client
exit
But also, chained commands are allowed and whitespace is not significant before and after commands, so the following examples are also valid:
kill ; say "that was fun"
kill ; kill ; kill;
I have currently implemented this with lex/yacc (flex/bison to be specific) and that caused a lot of headache. The lexer very much depends on the context (for example whitespace tokens are generally not returned, unless after a kill
keyword for example) and has many different states. The grammar used to have conflicts and I don’t really like the format in which it has to be specified (especially the $1, $2, $3, … to use arguments for non-terminals). Also, the error messages which bison provides (at parse-time) are sometimes accurate, but often not (the kill
command with optional arguments leads to error messages like Unexpected $undefined, expected $end or ;
for kill clont
instead of kill client
). Lastly, the C API for yacc is cruel (external defines all over the place).
I am not asking you to solve all the aforementioned questions (I will open separate threads with more specific descriptions and code if there is no way around lex/yacc). Instead, I am interested in alternatives to lex/yacc.
My criteria are the following:
As for a very simple and small grammar, I'd consider writing the lexer/parser by hand - it's often not that much work.
Virtually all linux distros ship a variant of lex/yacc. Other than that, two other widely used parser generators are lemon and antlr.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With