AN S-EXPRESSION PARSER built with Sedlex and Menhir This is an example of the construction of an error-reporting parser and lexer using sedlex and menhir. The parser runs interactively when connected to a terminal. It is intended ONLY to serve as an example of the use of sedlex and menhir, but may be helpful if you need an uncomplicated parser for S-expressions that can parse them efficiently both interactively from terminals as well as from files. To construct the parser, the lexer, and an example of their use: dune build example.exe EFFICIENT INTERACTIVE LEXING The supplied sedlexing.{ml,mli} have been adapted so that the lexer can be made to respond /immediately/ to characters appearing on the input channel, when the channel is connected to a terminal, yet can run efficiently (without recourse to the operating system for every single input character) when connected to a file. Such a lexer is constructed from a lexbuf made from a channel that can be tested to see if it's a tty. let chan = open_in "/dev/stdin" in let istty = Unix.isatty @@ Unix.descr_of_in_channel chan in let lexbuf = Sedlexing.Utf8.from_channel ~chunk_size:(if istty then 1 else 1024) chan in Sedlexing.set_filename lexbuf "/dev/stdin"; if istty then Sedlexing.set_prompter lexbuf (fun () -> Format.printf "> %!"); [NB: the standard sedlexing.{ml,mli} can also be used as per other published examples and their documentation, but in this case the lexer responds to input only when the end-of-file key is pressed at the terminal. This is because the "chunk-size" for refilling the standard form of buffer is constant (512), and the refilling loop requires an eof before it terminates.] UPDATING ERROR MESSAGES The supplied sources are all up to date wrt. the grammar file sexpParser.mly The Makefile has four /consequential/ targets. diff: generates sexpParserMessages.new and runs a diff between it and the existing sexpParserMessages. This is the default target, invoked on make. * If no differences are reported then there is no need for further action. * If there are differences only in state numbers, then there is no need for further action. If there is a difference that contains something like <YOUR SYNTAX ERROR MESSAGE HERE> then you will need to edit the .new file to change such generic messages into concrete descriptions of the error. When you have done so, then make cp to copy the .new file to the sexpParserMessages file, then make ml to generate source file sexpParserMessages.ml new: Generates sexpParserMessages.new incrementally from sexpParserMessages and sexpParser.mly The .new file may need editing to bring its error messages up to date with the parser specification (see the diff target) raw: Generates sexpParserMessages.raw ab-initio from sexpParser.mly The .raw file will certainly need editing to bring its error messages up to date with the parser specification. ml: Generates the sexpParserMessages.ml source file from the parser specification and the messages file.