Syntax file consists of states. A state consists of optional conditionals and one default action. The best way understand the syntax is to read /usr/share/dex/syntax/dex (a simple example) or /usr/share/dex/syntax/c (a more complete example using sub-syntaxes).
Basic syntax of the syntax files is the same used in the rc files, but the available commands are different.
Conditionals and default actions have destination state. The special destination state "this" can be used to jump to current state.
Begin a new syntax. One syntax file can contain multiple syntax definitions, but you should only define one real syntax in one syntax file.
See also Sub-Syntaxes.
state <name> [emit-color]
Add new state. Conditionals (if any) and one default action must follow. First state is the start state.
default <color> <name>...
Set default color for emitted name.
default numeric oct dec hex
If there is no color defined for oct, dec or hex then color numeric is used instead.
list [-i] <name> <string>...
Define a list of strings.
list keyword if else for while do continue switch case
Use conditional inlist to test if a buffered string is in a list.
-i Make list case-insensitive.
- bufis [-i] <string> <destination> [emit-name]
Test if buffered bytes are same as string. If they are emit emit-name and jump to destination state.
- char [-bn] <characters> <destination> [emit-name]
Test if current byte is in the character list. If it is then emit emit-color and jump to destination state. If emit-name is not given then destination states emit name is used.
Characters is a list of strings. Ranges are supported (a-d is same as abcd).
-b Add byte to buffer.
-n Invert character bitmap.
- heredocend <destination>
Compare following characters to heredoc end delimiter and go to destination state if comparison is true.
- inlist <list> <destination> [emit-name]
Test if buffered bytes are found in list. If found emit emit-name and jump to destination state.
- str [-i] <string> <destination> [emit-name]
See if following bytes are same as string. If they are emit emit-name and jump to destination state.
NOTE: This conditional can be slow, especially if string is longer than two bytes.
Last command of every state must be default action. It is an unconditional jump.
eat <destination> [emit-name]
Consume byte, emit emit-name color and continue to destination state.
heredocbegin <subsyntax> <return-state>
Store buffered bytes as heredoc end delimiter and go to subsyntax. Subsyntax is like any other subsyntax but it must contain heredocend conditional.
noeat [-b] <destination>
Continue to destination state without emitting color or consuming byte.
-b Don't stop buffering.
recolor <color> [count]
If count is given, recolor count previous bytes, otherwise recolor buffered bytes.
Sub-syntaxes are useful when same states are needed in many contexts.
Sub-syntax name must be prefixed with ".". It is recommended to also use main syntax's name in the prefix. For example ".c-comment" if "c" is the main syntax.
Sub-syntax is a syntax of which some destination state's name is END. END is a special state name which is replaced by state given at another syntax.
char "*" star
state star comment
# END is a special state name
char / END comment
# main syntax
state c code
char " \t\n" c
char -b a-zA-Z_ ident
char "\"" string
char "'" char
# call sub-syntax
str "/*" .c-comment:c
# other states removed
In this example the destination state .c-comment:c is special syntax for calling a sub-syntax. ".c-comment" is name of the sub-syntax and "c" is the return state defined in the main syntax. Whole sub-syntax tree is copied into the main syntax and all destination states in the sub-syntax whose name is END are replaced with "c".
Timo Hirvonen <firstname.lastname@example.org>