- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# /home/coin/SVN-release/Osi-0.98.1/DyLP/src/DylpStdLib/dylib_bnfrdr.h

Go to the documentation of this file.

    00001 #ifndef _DYLIB_BNFRDR_H
    00002 #define _DYLIB_BNFRDR_H
    00003
    00004 /*
    00005   This file is part of the support library for the Dylp LP distribution.
    00006
    00007         Copyright (C) 2005 -- 2007 Lou Hafer
    00008
    00009         School of Computing Science
    00010         Simon Fraser University
    00011         Burnaby, B.C., V5A 1S6, Canada
    00012         lou@cs.sfu.ca
    00013
    00014   This code is licensed under the terms of the Common Public License (CPL).
    00015 */
    00016
    00017 #include "dylib_io.h"
    00018
    00019 /*
    00020   sccs: @(#)bnfrdr.h    3.5     09/01/99
    00021   svn/cvs: "$Id: dylib_bnfrdr.h 181 2007-10-02 17:48:15Z lou $" ;
    00022
    00023   This file contains the structure definitions required to use the bnf reader
    00024   package. The bnf reader depends heavily on the following two assumptions:
    00025
    00026   * There is some pointer type into which any other pointer can be cast and
    00027     recovered.
    00028
    00029   * An int can be cast into a pointer and recovered. This is used to prevent
    00030     the complexity of the bnf data structure from getting out of hand, but
    00031     could be avoided at the expense of a substantial increase in its size and
    00032     awkwardness of use.
    00033
    00034   The basic scheme is something like this. At the bottom, we have a number of
    00035   terminal constructs: immediates, literals, terminals, and labels of various
    00036   flavours. Above these are the three non-terminal constructs: primitives,
    00037   non-primitives, and generators. The non-terminals have bodies which are made
    00038   up of references to other terminal or non-terminal constructs. Generator
    00039   bodies have only one parse; primitive and non-primitive bodies can have a
    00040   number of alternative parses. A picture is probably in order here:
    00041
    00042   definition      body
    00043
    00044   ----------      ----------      ----------      ----------
    00045   |        | ---> |        | ---> |  ref   | ---> |  defn  |
    00046   ----------      ----------      ----------      ----------
    00047                   |  ....  |
    00048                   ----------      ----------      ----------
    00049                   |        | ---> |  ref   | ---> |  defn  |
    00050                   ----------      ----------      ----------
    00051
    00052   A definition contains a pointer to its body, which is an array of pointers to
    00053   references. Each reference points to a definition. Essentially, a reference
    00054   specifies how the second definition is to be used in the context of the body
    00055   of the first definition.
    00056
    00057   The bnf reader has the capability to create arbitrary links in the data
    00058   structure it's building. Some terminology will make things easier:
    00059
    00060                 |  ....  |
    00061                 ----------      ----------
    00062       socket -->| label -+----->|        |
    00063                 ----------      ----------
    00064                 |  ....  |      |  ....  |
    00065
    00066   The value of a label is the address of something. To make a link, the
    00067   value of the label has to be stored.  The place where it is stored is
    00068   called a socket. The value of a socket is the address of the field where
    00069   the value of the label is stored. When it defines a socket, the bnf reader
    00070   associates a name with an address; similarly for a label. Both socket and
    00071   label references cause a label to be stored in a socket; the difference
    00072   between the two lies in which of the socket or label can be undefined when
    00073   the reference is processed.
    00074
    00075   When it's not important to distinguish between sockets and labels, the
    00076   documentation uses label to include both.
    00077
    00078   To write a bnf, you use the set of macros defined at the end of
    00079   the file. For a detailed explanation of the sorts of things that can be
    00080   specified with the bnf, the user should take a look at the supplementary
    00081   documentation. The structures and code will make a lot more sense afterward.
    00082 */
    00083
    00084
    00085
    00086 /*
    00087   Definitions of enum types used as codes in the bnf structures which follow.
    00088 */
    00089
    00090 /*
    00091   bnftype_enum codes the type of the bnf definition.
    00092
    00093   Value         Description
    00094   -----         -----------
    00095   bnfG          Generator definition
    00096   bnfNP         Non-primitive definition
    00097   bnfP          Primitive definition
    00098   bnfT          Terminal definition
    00099   bnfDS         Socket definition definition
    00100   bnfDL         Label definition definition
    00101   bnfRS         Socket reference definition
    00102   bnfRL         Label reference definition
    00103   bnfI          Immediate value definition
    00104   bnfL          Literal definition
    00105 */
    00106
    00107 typedef enum {bnfG,bnfNP,bnfP,bnfT,bnfDS,
    00108               bnfDL,bnfRS,bnfRL,bnfI,bnfL} bnftype_enum ;
    00109
    00110
    00111 /*
    00112   bnfttype_enum codes the type of lexeme expected by a terminal.
    00113
    00114   Value         Description
    00115   -----         -----------
    00116   bnfttNIL      the null lexeme
    00117   bnfttN        number
    00118   bnfttID       identifier
    00119   bnfttD        delimiter
    00120   bnfttF        fixed-length string
    00121   bnfttQ        quoted string
    00122 */
    00123
    00124 typedef enum {bnfttNIL,bnfttN,bnfttID,bnfttD,bnfttF,bnfttQ} bnfttype_enum ;
    00125
    00126
    00127 /*
    00128   bnflblsrc_enum codes the way in which text strings used for label names
    00129   are obtained.
    00130
    00131   Value         Description
    00132   -----         -----------
    00133   bnfncBNF      A bnf is supplied which will produce a text string. If this
    00134                 code appears in the context of a name, the string will be the
    00135                 name of the label. If it appears in the context of a value,
    00136                 the string will be used as a label name and the value
    00137                 associated with the name will become the value of the label
    00138                 being defined.
    00139   bnfncS        An index in the saved text array is supplied. The string
    00140                 retrieved is interpreted as for bnfncBNF.
    00141   bnfncC        The value of curnde is used as the socket/label value. This
    00142                 code is not valid in the context of a name.
    00143   bnfncN        The value of newnde is used as the socket/label value. This
    00144                 code is not valid in the context of a name.
    00145 */
    00146
    00147 typedef enum {bnfncBNF,bnfncS,bnfncC,bnfncN} bnflblsrc_enum ;
    00148
    00149
    00150
    00151 /*
    00152   Flag definitions used in bnf definitions.
    00153
    00154   Flag          Description
    00155   ----          -----------
    00156   bnfadv        Indicates the redefinition of a previously defined label. The
    00157                 usual context for use is to redefine (advance) a label which
    00158                 is the link in a linked list.
    00159   bnfsvnd       Save the text string developed by the nd part of a label
    00160                 definition definition or label reference definition.
    00161   bnfsvnm       Save the text string developed by the nm part of a label
    00162                 definition definition or label reference definition. This
    00163                 flag is also used in literal definitions to indicate that text
    00164                 should be retrieved from the saved text array.
    00165 */
    00166
    00167 #define bnfadv  1<<0
    00168 #define bnfsvnd 1<<1
    00169 #define bnfsvnm 1<<2
    00170
    00171
    00172 /*
    00173   Flag definitions used in bnf references.
    00174
    00175   Flag          Description
    00176   ----          -----------
    00177   bnflst        The definition referenced describes one element of a list of
    00178                 indefinite length.
    00179   bnfstore      The value produced by the referenced bnf will be stored
    00180                 somehow, and the offset field should be valid.
    00181   bnfatsgn      Store a pointer to the character string produced by the
    00182                 referenced bnf, rather than the string itself.
    00183   bnfstbg       The bnf referenced as the separator between list elements is
    00184                 really the beginning of the next list element. (Hence we'll
    00185                 have to back up over it once we recognize it.)
    00186   bnfflt        A float number is expected here.
    00187   bnfdbl        A double number is expected here.
    00188   bnfcs         Forces a case-sensitive comparison of the string read for a
    00189                 terminal with the value specified in the terminal definition.
    00190   bnfmin        Requests a minimum-length comparison - as long as the string
    00191                 parsed for the terminal matches the value specified in the
    00192                 terminal definition up to the end of the parsed string, the
    00193                 comparison succeeds.
    00194   bnfsv         Used in primitives to indicate that the string is to be stored
    00195                 in the savedtxt array. The offset should be a valid savedtxt
    00196                 index in this case.
    00197   bnfexact      (bnfttF only) used to prevent the addition of the null
    00198                 terminator at the end of a character string when the string
    00199                 is stored directly in a field (must be specified to store a
    00200                 single char in a field of size sizeof(char))
    00201   bnfdebug      Debugging should be activated for this reference and all
    00202                 bnf rules nested within it.
    00203 */
    00204
    00205 #define bnflst          1<<0
    00206 #define bnfstore        1<<1
    00207 #define bnfatsgn        1<<2
    00208 #define bnfstbg         1<<3
    00209 #define bnfflt          1<<4
    00210 #define bnfcs           1<<5
    00211 #define bnfmin          1<<6
    00212 #define bnfsv           1<<7
    00213 #define bnfexact        1<<8
    00214 #define bnfdebug        1<<9
    00215 #define bnfdbl          1<<10
    00216
    00217
    00218
    00219 /*
    00220   Bnfrdr regularly uses the first ([0]) entry of an array of addresses to hold
    00221   the number of addresses in the array. In order to convert this back to an
    00222   integer without triggering compiler warnings, the code uses this macro.
    00223 */
    00224
    00225 # define addrToInt(zz_addr_zz) \
    00226   ((int) (((char *)(zz_addr_zz)) - ((char *)(0))))
    00227
    00228 /*
    00229   Data structures used for bnf definitions. There are three types of things
    00230   here: individual structures for the various definition types, a common
    00231   structure which consists only of the fields common to all of the individual
    00232   structures, and a pointer union which is handy when walking around in a bnf.
    00233
    00234   For C++ fans: really, what we're doing here is faking a base class and
    00235   derived classes, with early 1980's technology.
    00236
    00237   Just to keep the explanation in hand a bit, let's define components and
    00238   alternatives. The body of a bnf definition consists of alternatives
    00239   (alternative parses), each of which has a number of components. A component
    00240   array is an array of pointers to bnf reference structures, each of which in
    00241   turn references a bnf definition structure. An alternative array is an array
    00242   of pointers to component arrays. I know this is ugly and involves a lot of
    00243   dereferencing but it seems to be the only way to handle the variable lengths
    00244   involved.
    00245
    00246   NOTE: To keep things from getting completely out of hand, the first entry
    00247         in a component or alternative array specifies the number of pointers
    00248         that follow. This is an abuse of type and casting. Bad when the world
    00249         was 32-bit architectures. Worse now that it's a mix of 32- and 64-bit
    00250         architectures. See the addrToInt macro above.
    00251 */
    00252
    00253 /*
    00254   The common portion.
    00255
    00256   Field         Description
    00257   -----         -----------
    00258   type          Type code identifying what sort of definition this is.
    00259   name          The name of the rule (derived from the C variable name;
    00260                 see the macros gdef, npdef, etc.)
    00261 */
    00262
    00263 #define bnfdef_common bnftype_enum type ; \
    00264                       const char *name ;
    00265
    00266 typedef struct { bnfdef_common } bnfdef_struct ;
    00267
    00268
    00269 /*
    00270   Data structure for a generator definition. Generators cause the creation of a
    00271   node in the data structure being built for the user. For simplicity, they may
    00272   not have alternative parses, but since they can reference non-primitives no
    00273   flexibility is lost.
    00274
    00275   Field         Description
    00276   -----         -----------
    00277   bnfdef_common As above.
    00278   size          Size (in bytes) of the node to be created.
    00279   link          Offset (in bytes) from the base of the node created by the
    00280                 generator to the field used as a link field when this node is
    00281                 in a linked list.
    00282   comps         Pointer to a component array.
    00283 */
    00284
    00285 typedef struct { bnfdef_common
    00286                  int size ;
    00287                  int link ;
    00288                  struct bnfref_struct_tag **comps ; } bnfGdef_struct ;
    00289
    00290
    00291 /*
    00292   Data structure for a non-primitive definition. Non-primitives are simply a
    00293   device for defining alternative parses. They don't directly create anything.
    00294
    00295   Field         Description
    00296   -----         -----------
    00297   bnfdef_common As above.
    00298   alts          Pointer to an alternative array.
    00299 */
    00300
    00301 typedef struct {bnfdef_common
    00302                 struct bnfref_struct_tag ***alts ; } bnfNPdef_struct ;
    00303
    00304
    00305
    00306 /*
    00307   Data structure for a primitive definition. The distinction between a
    00308   primitive and a non-primitive is that a primitive constructs a string which
    00309   is the concatenation of the strings returned by the bnf's referenced in the
    00310   primitive's body. The data structure is identical to that for non-primitives.
    00311 */
    00312
    00313 typedef bnfNPdef_struct bnfPdef_struct ;
    00314
    00315
    00316 /*
    00317   Data structure for a terminal. Terminals are used to specify specific things
    00318   to be obtained from the input stream. The various parameters required to
    00319   describe a terminal should really be mushed into a union, but then the bnf
    00320   data structure would have to be built dynamically, since unions can't be
    00321   initialized.
    00322
    00323   Field         Description
    00324   -----         -----------
    00325   bnfdef_common As above.
    00326   ttype         Code identifying the type of terminal to be obtained.
    00327   qschr         Starting character for a quoted string.
    00328   qechr         Ending character for a quoted string.
    00329   parm1         Overloaded field, interpreted as follows:
    00330                 numbers: specifies the radix
    00331                 fixed-length strings: specifies the string length
    00332   val           Expected value of the string obtained from the input stream.
    00333                 (This test is applied before the string is converted to the
    00334                  internal form appropriate for whatever is specified in ttype.)
    00335 */
    00336
    00337 typedef struct { bnfdef_common
    00338                  bnfttype_enum ttype ;
    00339                  char qschr ;
    00340                  char qechr ;
    00341                  int parm1 ;
    00342                  const char *val ; } bnfTdef_struct ;
    00343
    00344
    00345 /*
    00346   Data structure for an immediate value. Immediates are used to jam a code into
    00347   the data structure being built.
    00348
    00349   Field         Description
    00350   -----         -----------
    00351   bnfdef_common As above.
    00352   ival          Integer value.
    00353 */
    00354
    00355 typedef struct {bnfdef_common
    00356                 int ival ; } bnfIdef_struct ;
    00357
    00358
    00359 /*
    00360   Data structure for a literal. Literals are used to insert characters into the
    00361   input stream. (Handy for generating label names, for instance.)
    00362
    00363   Field         Description
    00364   -----         -----------
    00365   bnfdef_common As above.
    00366   dflgs         Flags.
    00367   txt           The string to be inserted. This field is also used to index
    00368                 into the saved text array by casting it to an int.
    00369 */
    00370
    00371 typedef struct { bnfdef_common
    00372                  flags dflgs ;
    00373                  char *txt ; } bnfLdef_struct ;
    00374
    00375
    00376 /*
    00377   Last but not least, the data structure used to define socket/label
    00378   definitions and references. (Definitions, mind you - there is another
    00379   structure to reference socket/label definitions and references.) A
    00380   socket/label definition associates of a name (a text string) with a value
    00381   (almost always an address).  A socket/label reference specifies a socket
    00382   and a label. The label is inserted into the socket. Fields prefixed by nm
    00383   are the name in a socket/label definition and the socket in a socket/label
    00384   reference. Fields prefixed by nd are the value in a socket/label definition
    00385   and the label in a socket/label reference.
    00386
    00387   Field         Description
    00388   -----         -----------
    00389   bnfdef_common As above.
    00390   dflgs         Flags.
    00391   nmcd          Specifies how name/socket will be obtained.
    00392   ndcd          Specifies how value/label will be obtained.
    00393   savnm         Specifies location in saved text array where string associated
    00394                 with nm will be stored.
    00395   nmsrc         Pointer to bnf which will produce string for nm, or cast into
    00396                 an int and used as a location in the saved text array.
    00397   savnd         Specifies location in saved text array where string associated
    00398                 with nd will be stored.
    00399   ndsrc         Pointer to bnf which will produce string for nd, or cast into
    00400                 an int and used as a location in the saved text array.
    00401   offset        Correction (in bytes) to socket/label value (socket/label
    00402                 definitions) or socket (socket/label references).
    00403   offset2       Correction (in bytes) to label (socket/label references).
    00404 */
    00405
    00406 typedef struct { bnfdef_common
    00407                  flags dflgs ;
    00408                  bnflblsrc_enum nmcd ;
    00409                  bnflblsrc_enum ndcd ;
    00410                  int savnm ;
    00411                  struct bnfref_struct_tag *nmsrc ;
    00412                  int savnd ;
    00413                  struct bnfref_struct_tag *ndsrc ;
    00414                  int offset ;
    00415                  int offset2 ; } bnfLBdef_struct ;
    00416
    00417
    00418 /*
    00419   And finally, the handy union of pointers promised back at the start. We
    00420   really should be using this in the bnf reference structure declarations,
    00421   rather than (bnfdef_struct *), but since references and definitions are
    00422   mutually recursive we get into ugliness. There's also the point that we
    00423   want to be able to create bnfs at compile time and you can't initialize
    00424   unions.
    00425 */
    00426
    00427 typedef union { bnfdef_struct *com ;
    00428                 bnfGdef_struct *G ;
    00429                 bnfNPdef_struct *NP ;
    00430                 bnfPdef_struct *P ;
    00431                 bnfTdef_struct *T ;
    00432                 bnfIdef_struct *I ;
    00433                 bnfLdef_struct *L ;
    00434                 bnfLBdef_struct *LB ; } bnfdef_any ;
    00435
    00436
    00437
    00438 /*
    00439   Now, on to the data structures used to reference bnf definitions. Recall if
    00440   you will the introductory comments about component and alternative arrays and
    00441   the general setup of the bnf data structure. We have the same three types of
    00442   data structures here as for bnf definitions.
    00443 */
    00444
    00445 /*
    00446   The common portion. It includes a type code, a name, usage flags, and a
    00447   pointer to the bnf definition.
    00448
    00449   Field         Description
    00450   -----         -----------
    00451   type          Type code identifying what sort of definition this reference
    00452                 points to.
    00453   name          The name of the reference (derived from the C variable name;
    00454                 see the macros qref, npref, pref, etc.)
    00455   uflgs         Usage flags.
    00456   defn          Pointer to a bnf definition structure.
    00457 */
    00458
    00459 #define bnfref_common bnftype_enum type ; \
    00460                       const char *name ; \
    00461                       bnfdef_struct *defn ; \
    00462                       flags uflgs ;
    00463
    00464 typedef struct bnfref_struct_tag { bnfref_common } bnfref_struct ;
    00465
    00466
    00467 /*
    00468   References to labels of all flavours and to literals require only the
    00469   common fields. The only reason we need the uflgs field is for the bnfdebug
    00470   flag.
    00471 */
    00472
    00473 typedef bnfref_struct bnfLBref_struct ;
    00474 typedef bnfref_struct bnfLref_struct ;
    00475
    00476
    00477 /*
    00478   References to terminals and immediates require an offset for storage.
    00479
    00480   Field         Description
    00481   -----         -----------
    00482   bnfref_common As above.
    00483   offset        Offset (in bytes) into current node to the field where the
    00484                 value produced by the referenced bnf will be stored.
    00485 */
    00486
    00487 struct bnfref_type2 { bnfref_common
    00488                       int offset ; } ;
    00489
    00490 typedef struct bnfref_type2 bnfTref_struct ;
    00491 typedef struct bnfref_type2 bnfIref_struct ;
    00492
    00493
    00494 /*
    00495   References to generators, non-primitives, and primitives can be in lists and
    00496   require a separator specification in addition to the offset. Non-primitives
    00497   do not make use of the offset field.
    00498
    00499   Field         Description
    00500   -----         -----------
    00501   bnfref_common As above.
    00502   offset        Offset (in bytes) into current node to the field where the
    00503                 value produced by the referenced bnf will be stored.
    00504   sep           A reference to a bnf definition describing the separator
    00505                 between list elements in the input stream.
    00506 */
    00507
    00508 struct bnfref_type3 { bnfref_common
    00509                       int offset ;
    00510                       bnfref_struct *sep ; } ;
    00511
    00512 typedef struct bnfref_type3 bnfGref_struct ;
    00513 typedef struct bnfref_type3 bnfNPref_struct ;
    00514 typedef struct bnfref_type3 bnfPref_struct ;
    00515
    00516
    00517 /*
    00518   And the handy union pointer type. Same general comments as for the
    00519   declaration of bnfdef_any.
    00520 */
    00521
    00522 typedef union { bnfref_struct *com ;
    00523                 struct bnfref_type1 *t1 ;
    00524                 struct bnfref_type2 *t2 ;
    00525                 struct bnfref_type3 *t3 ;
    00526                 bnfGref_struct *G ;
    00527                 bnfNPref_struct *NP ;
    00528                 bnfPref_struct *P ;
    00529                 bnfTref_struct *T ;
    00530                 bnfIref_struct *I ;
    00531                 bnfLref_struct *L ;
    00532                 bnfLBref_struct *LB ; } bnfref_any ;
    00533
    00534
    00535
    00536 /*
    00537   The macros that make defining the bnf data structures marginally
    00538   less painful.
    00539 */
    00540
    00541 /*
    00542   Macros to help with constructing field offsets. NULLP is specially designed
    00543   to produce a NULL value when used as &NULLP. This is required for some of the
    00544   macros where one must fill the field with either the address of a
    00545   bnfref_struct or the value NULL. By this device we avoid having to make the
    00546   user aware of when and when not to use &. mkoff simply produces the offset of
    00547   a given field in a structure type.
    00548 */
    00549
    00550 #define NULLP (*((char *) 0))
    00551 #define mksav(qqoff) (*((char *) qqoff))
    00552 #define mkoff(qqtype,qqfield) (&((qqtype *) 0)->qqfield)
    00553
    00554 /*
    00555   Macros for alternative and component lists. These just generate the headers;
    00556   the actual lists have to be typed out, as:
    00557
    00558   althd(arule_alts) = { altcnt(3),
    00559                         mkaref(arule_alt1), mkaref(arule_alt2),
    00560                         mkaref(arule_alt3) } ;
    00561
    00562   comphd(arule_alt1) = { compcnt(2),
    00563                          mkcref(brule_ref), mkcref(crule_ref) } ;
    00564
    00565   where brule_ref and crule_ref are bnf references (most likely constructed
    00566   using the gref, npref, etc. macros).
    00567 */
    00568
    00569 #define althd(qqnme) bnfref_struct **qqnme[]
    00570 #define altcnt(qqcnt) (bnfref_struct **) (qqcnt)
    00571 #define mkaref(qqref) (bnfref_struct **) (qqref)
    00572
    00573 #define comphd(qqnme) bnfref_struct *qqnme[]
    00574 #define compcnt(qqcnt) (bnfref_struct *) (qqcnt)
    00575 #define mkcref(qqref) (bnfref_struct *) (&qqref)
    00576
    00577 /*
    00578   Macros to initialise bnf definitions. Note the use of the ANSI C
    00579   'stringisation' operator, '#', to get a text string for the name. For
    00580   non-ANSI implementations, replacing #qqnme with "qqnme" usually works (but
    00581   not all non-ANSI preprocessor implementations will see the macro parameter
    00582   inside a string, and ANSI C explicitly disallows it).
    00583 */
    00584
    00585 #define gdef(qqnme,qqsze,qqlnk,qqcomps) \
    00586 bnfGdef_struct qqnme = { bnfG, #qqnme, (int) (qqsze), (int) (qqlnk), \
    00587                          (bnfref_struct **) qqcomps }
    00588
    00589 #define npdef(qqnme,qqalts) \
    00590 bnfNPdef_struct qqnme = { bnfNP, #qqnme, (bnfref_struct ***) qqalts }
    00591
    00592 #define pdef(qqnme,qqalts) \
    00593 bnfPdef_struct qqnme = { bnfP, #qqnme, (bnfref_struct ***) qqalts }
    00594
    00595 #define tdef(qqnme,qqttype,qqparm,qqval) \
    00596 bnfTdef_struct qqnme = { bnfT, #qqnme, qqttype, '\0', '\0', \
    00597                          (int) (qqparm), (const char *) (qqval) }
    00598
    00599 #define tqdef(qqnme,qqschr,qqechr,qqval) \
    00600 bnfTdef_struct qqnme = { bnfT, #qqnme, bnfttQ, (char) qqschr, (char) qqechr,\
    00601                          0, (char *) (qqval) }
    00602
    00603 #define dfdef(qqnme,qqdflgs,qqnmcd,qqnm,qqsavnm,qqndcd,qqnd,qqsavnd,qqoff) \
    00604 bnfLBdef_struct qqnme = { bnfDS, #qqnme, (flags) (qqdflgs), qqnmcd, qqndcd, \
    00605                           (int) (qqsavnm), (bnfref_struct *) &qqnm, \
    00606                           (int) (qqsavnd), (bnfref_struct *) &qqnd, \
    00607                           (int) (qqoff), 0 }
    00608
    00609 #define dbdef(qqnme,qqdflgs,qqnmcd,qqnm,qqsavnm,qqndcd,qqnd,qqsavnd,qqoff) \
    00610 bnfLBdef_struct qqnme = { bnfDL, #qqnme, (flags) (qqdflgs), qqnmcd, qqndcd, \
    00611                           (int) (qqsavnm), (bnfref_struct *) &qqnm, \
    00612                           (int) (qqsavnd), (bnfref_struct *) &qqnd, \
    00613                           (int) (qqoff), 0 }
    00614
    00615 #define rfdef(qqnme,qqdflgs,qqnmcd,qqnm,qqsavnm,qqoff,qqndcd,qqnd,qqsavnd,qqoff2) \
    00616 bnfLBdef_struct qqnme = { bnfRS, #qqnme, (flags) (qqdflgs), qqnmcd, qqndcd, \
    00617                           (int) (qqsavnm), (bnfref_struct *) &qqnm, \
    00618                           (int) (qqsavnd), (bnfref_struct *) &qqnd, \
    00619                           (int) (qqoff), (int) (qqoff2) }
    00620
    00621 #define rbdef(qqnme,qqdflgs,qqnmcd,qqnm,qqsavnm,qqoff,qqndcd,qqnd,qqsavnd,qqoff2) \
    00622 bnfLBdef_struct qqnme = { bnfRL, #qqnme, (flags) (qqdflgs), qqnmcd, qqndcd, \
    00623                           (int) (qqsavnm), (bnfref_struct *) &qqnm, \
    00624                           (int) (qqsavnd), (bnfref_struct *) &qqnd, \
    00625                           (int) (qqoff), (int) (qqoff2) }
    00626
    00627 #define idef(qqnme,qqval) \
    00628 bnfIdef_struct qqnme = { bnfI, #qqnme, (int) (qqval) }
    00629
    00630 #define ldef(qqnme,qqdflgs,qqtxt) \
    00631 bnfLdef_struct qqnme = { bnfL, #qqnme, (flags) (qqdflgs), (char *) (qqtxt) }
    00632
    00633
    00634
    00635 #define gref(qqnme,qqref,qquflgs,qqoff,qqsep) \
    00636 bnfGref_struct qqnme = { bnfG, #qqnme, (bnfdef_struct *) &qqref, \
    00637                          (flags) (qquflgs), (int) (qqoff), \
    00638                          (bnfref_struct *) &qqsep }
    00639
    00640 #define npref(qqnme,qqref,qquflgs,qqsep) \
    00641 bnfNPref_struct qqnme = { bnfNP, #qqnme, (bnfdef_struct *) &qqref, \
    00642                          (flags) (qquflgs), (int) 0, (bnfref_struct *) &qqsep }
    00643
    00644 #define pref(qqnme,qqref,qquflgs,qqoff,qqsep) \
    00645 bnfPref_struct qqnme = { bnfP, #qqnme, (bnfdef_struct *) &qqref, \
    00646                          (flags) (qquflgs), (int) (qqoff), \
    00647                          (bnfref_struct *) &qqsep }
    00648
    00649 #define tref(qqnme,qqref,qquflgs,qqoff) \
    00650 bnfTref_struct qqnme = { bnfT, #qqnme, (bnfdef_struct *) &qqref, \
    00651                          (flags) qquflgs, (int) qqoff }
    00652
    00653 #define dfref(qqnme,qqref) \
    00654 bnfLBref_struct qqnme = { bnfDS, #qqnme, (bnfdef_struct *) &qqref, (flags) 0 }
    00655
    00656 #define dbref(qqnme,qqref) \
    00657 bnfLBref_struct qqnme = { bnfDL, #qqnme, (bnfdef_struct *) &qqref, (flags) 0 }
    00658
    00659 #define rfref(qqnme,qqref) \
    00660 bnfLBref_struct qqnme = { bnfRS, #qqnme, (bnfdef_struct *) &qqref, (flags) 0 }
    00661
    00662 #define rbref(qqnme,qqref) \
    00663 bnfLBref_struct qqnme = { bnfRL, #qqnme, (bnfdef_struct *) &qqref, (flags) 0 }
    00664
    00665 #define iref(qqnme,qqref,qqoff) \
    00666 bnfIref_struct qqnme = { bnfI, #qqnme, (bnfdef_struct *) &qqref, \
    00667                         (flags) 0, (int) qqoff }
    00668
    00669 #define lref(qqnme,qqref) \
    00670 bnfLref_struct qqnme = { bnfL, #qqnme, (bnfdef_struct *) &qqref, (flags) 0 }
    00671
    00672 #ifndef DYLP_NDEBUG
    00673
    00674 /*
    00675   This set of definitions sets the bnfdebug flag, but doesn't add a separate
    00676   uflgs parameter (we don't want to lead the user to think any of the others
    00677   are valid).
    00678 */
    00679
    00680 #define dfrefdbg(qqnme,qqref) \
    00681 bnfLBref_struct qqnme = { bnfDS, #qqnme, (bnfdef_struct *) &qqref, \
    00682                           (flags) bnfdebug }
    00683
    00684 #define dbrefdbg(qqnme,qqref) \
    00685 bnfLBref_struct qqnme = { bnfDL, #qqnme, (bnfdef_struct *) &qqref, \
    00686                           (flags) bnfdebug }
    00687
    00688 #define rfrefdbg(qqnme,qqref) \
    00689 bnfLBref_struct qqnme = { bnfRS, #qqnme, (bnfdef_struct *) &qqref, \
    00690                           (flags) bnfdebug }
    00691
    00692 #define rbrefdbg(qqnme,qqref) \
    00693 bnfLBref_struct qqnme = { bnfRL, #qqnme, (bnfdef_struct *) &qqref, \
    00694                           (flags) bnfdebug }
    00695
    00696 #define lrefdbg(qqnme,qqref) \
    00697 bnfLref_struct qqnme = { bnfL, #qqnme, (bnfdef_struct *) &qqref, \
    00698                           (flags) bnfdebug }
    00699
    00700 #endif /* DYLP_NDEBUG */
    00701
    00702
    00703
    00704 /*
    00705   Last, but not least, some declarations to allow the use of the bnf reader.
    00706   rdrinit and rdrclear initialize and clear the reader; they should bracket
    00707   related groups of calls. parse is the main parsing routine. The union type
    00708   parse_any is the appropriate thing to hold the result.
    00709 */
    00710
    00711 typedef union { void *g ;
    00712                 char *c ; } parse_any ;
    00713
    00714 extern void rdrinit(void),rdrclear(void) ;
    00715 extern bool parse(ioid chn, struct bnfref_type3 *bnfid, parse_any *result) ;
    00716
    00717 #ifndef DYLP_NDEBUG
    00718 /*
    00719   The control routine for the bnf debugging trace output. See the comments
    00720   in bnfrdr.c for the proper use of the parameters.
    00721 */
    00722
    00723 extern void bnfdbgctl(ioid dbgchn, bool dbgecho, bool warnzlbl, bool numlvl,
    00724                       bool tablvl) ;
    00725 #else
    00726 #define bnfdbgctl(dgbchn,dbgecho,warnzlbl,numlvl,tablvl)
    00727 #endif
    00728
    00729 /*
    00730   Utility print routines from bnfrdrio.c.
    00731 */
    00732
    00733 extern void prtbnfref(ioid chn, bool echo, bnfref_struct *ref),
    00734             prtbnfdef(ioid chn, bool echo, bnfdef_struct *def) ;
    00735
    00736 #endif /* _DYLIB_BNFRDR_H */