Parsing a program requires providing the interpreter with the program textual representation and some functions, operators and variables sets. Basic error reporting will also be demonstrated in this section since getting parsing errors with no further details may be quite frustrating.
The parsing of procedural programs very much ressembles parsing imperative programs or expressions.
See Crash Introduction.
The actual program parsing may be achieved as in:
status = x1f4_init_shuffle(&program, data, flags, &a1);
See x1f4_init_shuffle.
The x1f4_init_shuffle
function builds the executable representation of
the program from its data
textual representation (null terminated string
if not otherwise specified) and stores the result in program
.
Program executable representations are opaque structures and application wise
typeless. Only references to program executable representations are
application available. For convenience the C type of program executable
representations is void *
.
One may declare program
as:
void *program;
The rest of x1f4_init_shuffle
input is provided via the a1
record. The flags
parameter hints x1f4_init_shuffle
that it must
pay attention to certain a1
fields. In this simple example it is
assumed X1f4_A1_BCOLLECT
.
See Procedural Language Interpreter Generation Flags.
The C type of the a1
record is struct x1f4_a1_type
. The
a1
record is thus declared as:
struct x1f4_a1_type a1;
See struct x1f4_a1_type.
The minimal additional input for program parsing is the functions, operators and variables sets in use.
The variables set refers those variables used as state exports from the
application toward the executed program. It is specified as a specialized
collection (radix tree based). If no state export via variables is required
setting the corresponding field in the a1
record to NULL
should
do fine:
a1.variable_set.context = NULL;
The functions set is specified as for the imperative language interpreter: a context and a lookup method are to be provided.
In this example the context is a null terminated array of struct
x1f4_function_type
records (null terminated means here that the name
field of the last record in the array is nil). The very unsophisticated lookup
method in the expression evaluator crash introduction will apply. The function
set fields in the struct x1f4_a1_type
record will be set as:
attributes.function_set.get = select_function; attributes.function_set.context = function_data;
The function_data
is declared as:
struct x1f4_function_type *function_data;
and points to the function definitions array aforementioned. It merges the libx1f4i0 trivialities set with a very simple minded standard output printing functions set required by this example.
See x1f4_e4_defaults.
See Generalities Function Set.
The two sets may be merged together as in the imperative language example.
Set the operators sets to some C like operators sets, as in:
x1f4_llink_operator1s(&a1.operator1s); x1f4_llink_operator2s(&a1.operator2s);
See C Prefix Unary Operators Set.
See C Infix Binary Operators Set.
Last needed is the parsing error collector. Declare it like:
struct x1f4_a1record_type a1record;
add it in the parsing attributes record as in:
a1.bcollect_set.a1record_data = &a1record;
The X1f4_A1_BCOLLECT
bit set in the flags
argument of the program
parsing function will request the program parser to record whatever parsing
error if any in the a1record
record.
See Procedural Program Parsing Error Reporting.
The recorded parsing error may be detailed for the benefit of the user. The return of the program parsing function may be examined for processing result, and if not 0 the appropriate error messages may be displayed (there are only two errors: memory allocation and parsing error), so the program parsing may be rewritten as:
status = x1f4_init_shuffle(&program, data, flags, &a1); if (status) { if (status == X1f4_A1_ALLOC_ERROR) { perror(argv[0]); } else { fprintf(stderr, "%s: cannot parse `%s'\n", argv[0], ...); fprintf(stderr, "%s: ", argv[0]); x1f4_stat_program(stderr, ..., data, &a1record, NULL); fprintf(stderr, "\n"); } }
See x1f4_stat_shuffle.