1
1
The compiler consists of the following stages:
3
3
PARSER: sieve-parser.c, sieve-lexer.c
4
Parses the scriptfile and produces an abstract syntax tree for it
4
Parses the scriptfile and produces an abstract syntax tree for it
7
7
VALIDATOR: sieve-validator.c
8
Performs contextual analysis on the ast produced by the parser. This checks
9
for the validity of commands, tests and arguments. Also, the ast is decorated
10
with any context data acquired during the process. This context is used by the
8
Performs contextual analysis on the ast produced by the parser. This checks
9
for the validity of commands, tests and arguments. Also, the ast is decorated
10
with any context data acquired during the process. This context is used by the
13
13
GENERATOR: sieve-generator.c
14
This last compiler stage uses a visitor pattern to wander through the ast and
14
This last compiler stage uses a visitor pattern to wander through the ast and
15
15
produces sieve byte code (sieve-binary.c).
17
17
The resulting (in-memory) binary can be fed to the interpreter for execution:
19
INTERPRETER: sieve-interpreter.c
20
The interpreter executes the byte code and produces a sieve_result object.
21
This result is no more than just a collection of actions to be performed.
22
During execution, action commands add actions to the result. Duplates and
19
INTERPRETER: sieve-interpreter.c
20
The interpreter executes the byte code and produces a sieve_result object.
21
This result is no more than just a collection of actions to be performed.
22
During execution, action commands add actions to the result. Duplates and
23
23
conflicts between actions are handled in this execution phase.
25
25
RESULT: sieve-result.c sieve-actions.c
26
When the result is to be executed, it needs no further checking, as the
27
validity of the result was verified during interpretation already. The
28
result's actions are executed in a transaction-like atomic manner. If one of
29
the actions fails, the whole transaction is rolled back meaning that either
26
When the result is to be executed, it needs no further checking, as the
27
validity of the result was verified during interpretation already. The
28
result's actions are executed in a transaction-like atomic manner. If one of
29
the actions fails, the whole transaction is rolled back meaning that either
30
30
everything succeeds or everything fails. This is only possible to some extent:
31
transmitted responses can of course not be rolled back. However, these are
31
transmitted responses can of course not be rolled back. However, these are
32
32
executed in the commit phase, meaning that they will only be performed if all
33
33
other actions were successful.
37
37
BINARY-DUMPER: sieve-code-dumper.c sieve-binary-dumper.c
38
A loaded binary can be dumped to a stream in human-readable form using the
38
A loaded binary can be dumped to a stream in human-readable form using the
39
39
binary-dumper. The binary-dumper displays information on all the blocks that
40
40
the binary consists off. Program code blocks are dumped using the code-dumper.
41
It's implementation is similar to the interpreter, with the exception that it
42
performs no actions and just sequentially wanders through the byte code
43
printing instructions along the way. The term human-readable is a bit optimistic
44
though; currently, the presented data looks like an assembly language.
41
It's implementation is similar to the interpreter, with the exception that it
42
performs no actions and just sequentially wanders through the byte code
43
printing instructions along the way. The term human-readable is a bit optimistic
44
though; currently, the presented data looks like an assembly language.