Assay is a C library that provides functions to parse a configuration file in yet one more variation on the widely used and under specified INI format. The syntax of the file format implemented by Assay is specified by an LALR(1) grammar that was strongly influenced by my experience using configuration files in the Asterisk open source PBX. Portions of the C code, specifically its reentrant lexical scanner and reentrant shift-reduce parser, are generated at build time using the GNU Flex and Bison tools. Assay is built on top of the Diminuto library of GNU/Linux-based software tools and makes heavy use of its implementation of balanced Red-Black trees.
Here is an example of what an INI file might look like.
; This property goes into the default section named "general".
keyword01 = value01
keyword\ 13 : value 13
keyword3 = \ value\t3
[Section3] keyword5: value5
[Section3] keyword6: value6
See also the example files used by the included unit tests.
The syntax rules for the INI file format supported by Assay are pretty simple (but the grammar is the definitive source).
- The characters octothorpe, equal sign, colon, semicolon, left square bracket, and right square bracket, are special.
- White space at the beginning of any line is ignored.
- A comment begins with a semicolon and can occur on a line by itself or on the same line after any other statement.
- The beginning of a section is declared within square brackets. The section name must escape special characters or white space, which then becomes part of the section name.
- Properties consist of a keyword, an equal sign or a colon, and a value. White space may occur on either side of the equal sign or colon.
- If a keyword contains special characters or white space, those characters must be escaped.
- The value starts at the first non-white space character following the equal sign or colon. A white space character that is the first character of a value must be escaped. The value continues until end of line or a comment. A semicolon in the value must be escaped.
- As a short cut, a section can be declared followed by a property on the same line.
- Statements can be extended across multiple lines by escaping the newline at the end, which is discarded.
- An octothorpe as the first character of a statement signals an operation that interrupts the parsing of the current input stream. Every operation consists of an operator and an argument separated by white space. The two operators currently supported are include and exec.
- The include operator temporarily redirects parsing to the file identified by the path name in the argument. When end of file is reached, parsing of the stream containing the include statement resumes.
The exec operator temporarily redirects parsing to the standard output of the shell command specified by the argument, which may include white space. When the shell command exits, parsing of the stream containing the exec statement resumes.
- The exec operator temporarily redirects parsing to the standard output of the shell command specified by the argument, which may include white space. When the shell command exits, parsing of the stream containing the exec statement resumes.
I had a variety of reasons for tackling this project.
- I've written many recursive descent parsers, and parsers implemented as push-down automata, over the years, but had never worked with Lex/Flex or Yacc/Bison.
- I've worked with a lot of much simpler LL(1) grammars, but never an LALR(1) grammer, except as an academic exercise way back in graduate school.
- I found the support for configuration files in Asterisk to be really useful.
- I wanted to implement a non-trivial application using the Diminuto Red-Black balanced tree feature.
Here are some references I found useful.
- Wikipedia, "INI file", http://en.wikipedia.org/wiki/INI_file
- Asterisk Project, "Asterisk Configuration Files", https://wiki.asterisk.org/wiki/display/AST/Asterisk+Configuration+Files
- John R. Levine, Tony Mason, Doug Brown, lex & yacc, 2nd ed., O'Reilly, 1995
- John R. Levine, flex & bison, O'Reilly, 2009
- Tom Niemann, "LEX & YACC TUTORIAL", http://epaperpress.com/lexandyacc/download/LexAndYaccTutorial.pdf
- Saumya, K. Debray, "Lex and Yacc: A Brisk Tutorial", http://www.cs.arizona.edu/~debray/Teaching/CSc453/DOCS/tutorial-large.pdf
Assay can be found on GitHub here.