Commit b6bebb3c authored by css1dw's avatar css1dw
Browse files

Initial revision

parent 90adf0ef
datadec \- C data declaration module constructor
.RB [\- vno ]
.I basename
.RB [infile]
.B Datadec
takes an input file - or stdin if no input file is given -
containing a series of HOPE/Miranda style recursive data declarations
with optional hints on printing,
and builds an definition/implementation pair of files \-
.I "basename.h"
.I "basename.c"
containing data declarations,
constructor functions, deconstructor functions and printing functions.
The two files produced together form a module that implements the relevent
data types.
.TP 8
.B "\-v"
enter verbose mode.
.I "Datadec"
now displays the data types that it parses, along with various almost
certainly useless bits of information about optimization.
.B "\-n"
do not perform various optimizations.
.B "\-o"
perform optimizations (the default).
The simplest use is to prepare an input file, such as
.I ","
which might (for example) contain:
IntList = Null or Cons( int first, IntList next );
ILList = Null or Cons( IntList first, ILList next );
IdTree = Leaf( string id )
or Node( IdTree left, IdTree right );
To generate C code implementing these types, invoke:
datadec eek
which generates
.I "eek.h"
.I "eek.c"
The language accepted by datadec is split into two components:
the "outer language" is patterned after
the GMD compiler tools
.B "REX"
(similar to Yacc and Lex)
and allows you to specify four sections (only the last is compulsory):
.B "[ EXPORT { free_format_text } ]"
.B "[ GLOBAL { free_format_text } ]"
.B "[ BEGIN { free_format_text } ]"
.B "TYPE { types }"
The contents of the
.I "export"
section are placed in the header file (the .h).
Commonly, you may wish to add extern function declarations, public types and
external variable declarations
which must be
placed at the top of the header file, and also define some additional
procedures using the automatically generated types which must be placed after
the type declarations!
To achieve this, you should place a `@@' in the export section -- the text up
to that point is placed at the top of the header file, whereas the text
after it is placed at the bottom of the header file -- after all the types
have been defined.
Similarly, the contents of the
.I "global"
section are placed in the C file,
again with `@@' being used to split the global section into "top of file" and
"bottom at file" pieces.
Similarly, the contents of the
.I "begin"
section are placed in an initialization procedure, which the user of the
constructed module must remember to call at an appropriate juncture (eg.
immediately when main starts).
.I "types"
section contains the type declarations themselves - the inner language.
The "inner language" - that of specifying the actual types section -
is closely modelled on Miranda or Hope, with printing rules added.
Here is the grammar:
types = list(type)
type = type_name '=' shape list( 'or' shape ) ';'
shape = constructor_name [ '(' params ') ] [ print ]
params = param list( ',' param)
param = type_name param_name
print = list(element)
element = number | string_literal
Note that each data type is terminated by a semicolon,
and that (within one data type) each shape is separated from the next by 'or'
(just like the '|' in Miranda).
If a particular shape has parameters, they are separated from each other
by commas.
Each type name is simply an identifier.
.I "Datadec"
also generates routines to write each type to an open FILE *.
The method of printing each shape is governed by the presence or absence
of a print rule. If no print rule is given, the constructor name is printed,
and then each parameter is written out using the appropriate print routine.
If a print rule is given, each print element
(these are syntactically separated by whitespace)
is used to generate the write routine as follows:
A literal string will simply be printed
(well, '\\n' is turned into a newline!),
whereas a number (eg. 4) means that the
4th parameter is printed (invoking the print function for that routine).
For example, we could augment the
.I "IdTree"
type from the example given above with print rules:
IdTree = Leaf( string id ) "leaf(" 1 ")"
or Node( IdTree left, IdTree right ) "node(" 1 ",\\n" 2 ")";
Now, an IdTree constructed as
Node( Leaf( "hello" ), Node( Leaf( "there" ) ) )
would print as:
LALR, REX, Miranda Language Definition.
Some single letter typenames (eg. "f" or "p") could clash with internal
parameter names in the print routines, leading to syntax errors when you
compile the files generated by datadec.
Someday I'll get it to free up the types too!
And, finally, one day I'll have to write the C++ and Java versions :-)
Duncan C. White,
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment