The parser

Classes

class  senf::console::Token
 Single argument token. More...
 
class  senf::console::ParseCommandInfo
 Single parsed console command. More...
 
class  senf::console::CommandParser
 Parse commands. More...
 

Detailed Description

The console/config library defines a simple language used to interact with the console or to configure the application. The parser is not concerned about interpreting commands or arguments, checking that a command exists or managing directories. The parser just takes the input and parses it.

The Language

The config/console language is used in configuration files and interactively at the
console. Some features of the language are more useful in config files, others at the
interactive console but the language is the same in both cases.

Let's start with a sample of the config/console language. The following is written as a
configuration file
# My someserver configuration file
/server/port 1234;
/logger/targets {
console {
accept senf::log::Debug IMPORTANT;
accept server::ServerLog CRITICAL;
}
provide serverlog senf::log::FileTarget "/var/log/server.log";
serverlog {
reject senf::log::Debug senf::Console::Server NOTICE;
accept senf::log::Debug NOTICE;
accept server::ServerLog;
}
}
/server/stuffing (UDPPacket x"01 02 03 04");
/server/allow_hosts 10.1.2.3 # our internal server
10.2.3.4 10.4.3.5 # client workstations
;
/help/infoUrl "http://senf.j32.de/src/doc";
The interactive syntax is the same with some notes:
\li All commands must be complete on a single line. This includes grouping constructs which must
    be closed on the same line they are opened.
\li The last ';' is optional. However, multiple commands may be entered on a single line when
    they are separated by ';'.
\li An empty line on the interactive console will repeat the last command.

The language consists of a small number of syntactic entities:

Special characters

These are characters, which have a special meaning. Some are used internally, others are just
returned as punctuation tokens

<table class="senf">
    <tr><td>#</td><td>Comments are marked with '#' and continue to the end of the line</td></tr>
    <tr><td>/</td><td>path component separator</td></tr>
    <tr><td>( )</td><td>argument grouping</td></tr>
    <tr><td>{ }</td><td>directory grouping</td></tr>
    <tr><td>;</td><td>command terminator</td></tr>
    <tr><td>, =</td><td>punctuation tokens</td></tr>
</table>

Basic elements

A <b>word</b> is \e any sequence of consecutive characters which does not include any special
character. Examples for words are thus
12.34
dev@w.nosp@m.ibac.nosp@m.k.org
eth0
1>2
The following are \e not valid words:
a/b/c
a,b
A <b>string literal</b> is just that: A double-quoted string (C/C++ style) possibly with
embedded escape chars:
"\"foo""
""
A <b>hex-string literal</b> is used to represent binary data. It looks like a string which has
only hexadecimal bytes or whitespace as contents (comments and newlines are Ok when not read
from the interactive console)
x"01 02 03 0405"
x"01 02   # ID header
  0405    # payload
  "
A <b>token</b> is a \e word, \e string or \e hex-string, or a single special character (that's
true, any special character is allowed as a token). '(' and ')' must be properly nested.

A <b>path</b> is a sequence of \e words separated by '/' (and optional whitespace). A path may
have an optional initial and/or a terminating '/'.
a/b/c
foo / bar /
/server

Statements

There are several types of statements:
\li The bulk of all statements are \e path statements
\li There are some \e built-in statements which are mostly useful at the interactive console
\li A special form of statement is the <em>directory group</em>

A <b>path</b> statement consists of a (possibly relative) path followed by any number of
arguments and terminated with a ';' (or end-of-input)
/path/to/command arg1 "arg2" (complex=(1 2) another) ;

Every argument is either

  • A single word, string or hex-string
  • or a parenthesized list of tokens.

So above command has three arguments: 'arg1', 'arg2' (a single token each) and one argument with the 7 tokens 'complex', '=', '(', '1', '2', ')', 'another'. The interpretation of the arguments is completely up to the command.

A built-in statement is one of

cd path Change current directory
ls [ path ]List contents of path or current directory
exit Exit interactive console
help [ path ]Show help for path or current directory

A directory group statement is a block of statements all executed relatively to a fixed directory.

/some/path {
    statement ;
    . . .
}

At the beginning of the block, the current directory is saved and the directory is changed to the given directory. All commands are executed and at the end of the block, the saved directory is restored.

The parser API

The senf::console::CommandParser is responsible for taking text input and turning it into a
sequence of senf::console::ParseCommandInfo structures. The structures are returned by passing
them successively to a callback function.

Every statement is returned as a senf::console::ParseCommandInfo instance. Directory groups are
handled specially: They are divided into two special built-in commands called PUSHD and POPD.