Skip to content

Latest commit

 

History

History
202 lines (128 loc) · 4.71 KB

SYNTAX.md

File metadata and controls

202 lines (128 loc) · 4.71 KB

Syntax

Additional syntax definitions can be taken from a simple text configuration file. This allows the syntax to be easily extended without recompiling the main program. It also means that mere humans can create a functional CLI.

Basic Syntax

The file format for the syntax definitions is straightforward. At the simplest level, it is just a copy of commands that the user is allowed to type:

foo bar baz

Will allow the user to type "foo bar baz". Anything else is a syntax error.

Multiple lines can be used:

foo bar baz
bar bad
hello there

Again, any of these commands are allowed.

Comments and Blank Lines

Comments can be used, and blank lines are ignored:

# this command does "foo" stuff, with "bar" and "baz
# chasers.
foo bar baz

# A "bar" command
bar bad

# Cheery command.
hello there

Optional Parameters

By itself, this syntax isn't very useful. To make it more useful, we allow optional parameters. These are signified by surrounding them with square brackets, as with regular expressions:

 # allow "foo", or "foo bar baz"
 foo [bar baz]

The above example is equivalent to the following:

foo
foo bar baz

but it can be easier to understand.

Alternate Choices

Alternate choices can be specified by using round brackets and pipe characters, as with regular expressions:

# allow "foo a", or "foo b"
foo (a|b)

Again, the above example is equivalent to the following:

foo a
foo b

Alternate choices become more useful when you have multiple choices:

foo (a|b) (b|c) (e|f) (g|h)

It would be expensive to specify the above example using the "one line for each allowed syntax" paradigm.

Repetition

The standard "+" and "*" can be used to repeat any subset of a syntax.

Combination and Nesting

The above examples can be combined, of course:

# Allow "foo a b", "foo a c", "foo b", or "foo c"
foo [a] (b|c)

And nested:

# allow lots of things
foo (b (d|e) | c)
bar (b [c] | hack)

Variable arguments

It is often useful to allow for a variable number of arguments to a command. This can be done via the following syntax:

# allow *any* number of *any* arguments after "foo"
foo ...

The "..." syntax is a special-case for variable argument support. When it is seen, it will accept absolutely any number of arguments, in any format, after the initial command. There must be at least one command before the variable agument block. i.e. "..." by itself is forbidden.

It is also forbidden to use alternation or optional parameters with variable arguments.

# Disallowed: variable arguments in optional test
foo [...]

# Disallowed: there can't be alternation
foo (... | bar )

# Disallowed:  this is the same as above
foo ...
foo bar

Caveats

The input syntax is checked for being properly formatted. Invalid formats are rejected. Each input syntax is then merged with the previous ones, as a logical alternation. i.e. the following two syntaxes are identical, and will result in the identical syntax:

# two lines
foo bar
bar baz

and

# one line
(foo bar|bar baz)

Specifying the "same" syntax multiple times will not cause a problem. The duplicate syntaxes will be discovered, and ignored.

It is possibly to specify ambiguous syntaxes, as with the following:

[a] cat
a cat sat

In which case the second line cannot be used, as it will cause a syntax error.

The parser is "greedy", in that it takes the first match, and does minimal backtracking. The solution to poorly defined syntaxes is to use a well-defined syntax.

Data Types

The syntax format allows you to specify allowed data types in a command.

String

foo STRING

Allows the entry of a double-quoted or single quoted string. This means that the user can put spaces in a string, along with the question mark character. Backslashes are used within the string to escape the quote character.

Otherwise, the string is left as-is. Entering "foo bar" on the CLI when a STRING is allowed means that exact string is used, including the quotation marks.

IPv4 Address

foo IPADDR

Allows an IPv4 address, dotted quad notation.

Integer

foo INTEGER

Allows positive or negative integers, base 10.

MAC Addresses

foo MACADDR

Allows MAC (ethernet) addresses, 6 sets of 2 hex digits, separated by colons. i.e. 00:01:02:03:04:05. Other formats cause syntax errors.

See DATATYPES.md for more details.

Macros

There are cases where the same syntax is needed in many places. Recli therefore allows macros, via NAME=syntax format:

OPTIONS=(int INTEGER|ip IPADDR)

add foo OPTIONS
del foo OPTIONS

Macros make the syntax clearer and easier to write.