DyLP  trunk
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
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 Eclipse Public License (EPL).
00015 */
00016 
00017 #include "dylib_io.h"
00018 
00019 /*
00020   sccs: @(#)bnfrdr.h    3.5     09/01/99
00021   svn/cvs: "$Id$" ;
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
00544   of the 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
00546   the user aware of when and when not to use &.
00547 
00548   mkoff simply produces the offset of a given field in a structure type. But
00549   it's not quite that simple in the world of mixed 64- and 32-bit platforms.
00550   The cast to size_t leaves us with either a 64- or 32-bit int, depending
00551   on the size of addresses, but at least it's an int instead of a pointer,
00552   and that's sufficient to suppress warnings in other places when the result
00553   is converted to an int. And the result here should always be a small
00554   integer.
00555 */
00556 
00557 #define NULLP (*((char *) 0))
00558 #define mksav(qqoff) (*((char *) qqoff))
00559 #define mkoff(qqtype,qqfield) ((size_t) (&((qqtype *) 0)->qqfield))
00560 
00561 /*
00562   Macros for alternative and component lists. These just generate the headers;
00563   the actual lists have to be typed out, as:
00564 
00565   althd(arule_alts) = { altcnt(3),
00566                         mkaref(arule_alt1), mkaref(arule_alt2),
00567                         mkaref(arule_alt3) } ;
00568 
00569   comphd(arule_alt1) = { compcnt(2),
00570                          mkcref(brule_ref), mkcref(crule_ref) } ;
00571 
00572   where brule_ref and crule_ref are bnf references (most likely constructed
00573   using the gref, npref, etc. macros).
00574 */
00575 
00576 #define althd(qqnme) bnfref_struct **qqnme[]
00577 #define altcnt(qqcnt) (bnfref_struct **) (qqcnt)
00578 #define mkaref(qqref) (bnfref_struct **) (qqref)
00579 
00580 #define comphd(qqnme) bnfref_struct *qqnme[]
00581 #define compcnt(qqcnt) (bnfref_struct *) (qqcnt)
00582 #define mkcref(qqref) (bnfref_struct *) (&qqref)
00583 
00584 /*
00585   Macros to initialise bnf definitions. Note the use of the ANSI C
00586   'stringisation' operator, '#', to get a text string for the name. For
00587   non-ANSI implementations, replacing #qqnme with "qqnme" usually works (but
00588   not all non-ANSI preprocessor implementations will see the macro parameter
00589   inside a string, and ANSI C explicitly disallows it).
00590 */
00591 
00592 #define gdef(qqnme,qqsze,qqlnk,qqcomps) \
00593 bnfGdef_struct qqnme = { bnfG, #qqnme, (int) (qqsze), (int) (qqlnk), \
00594                          (bnfref_struct **) qqcomps }
00595 
00596 #define npdef(qqnme,qqalts) \
00597 bnfNPdef_struct qqnme = { bnfNP, #qqnme, (bnfref_struct ***) qqalts }
00598 
00599 #define pdef(qqnme,qqalts) \
00600 bnfPdef_struct qqnme = { bnfP, #qqnme, (bnfref_struct ***) qqalts }
00601 
00602 #define tdef(qqnme,qqttype,qqparm,qqval) \
00603 bnfTdef_struct qqnme = { bnfT, #qqnme, qqttype, '\0', '\0', \
00604                          (int) (qqparm), (const char *) (qqval) }
00605 
00606 #define tqdef(qqnme,qqschr,qqechr,qqval) \
00607 bnfTdef_struct qqnme = { bnfT, #qqnme, bnfttQ, (char) qqschr, (char) qqechr,\
00608                          0, (char *) (qqval) }
00609 
00610 #define dfdef(qqnme,qqdflgs,qqnmcd,qqnm,qqsavnm,qqndcd,qqnd,qqsavnd,qqoff) \
00611 bnfLBdef_struct qqnme = { bnfDS, #qqnme, (flags) (qqdflgs), qqnmcd, qqndcd, \
00612                           (int) (qqsavnm), (bnfref_struct *) &qqnm, \
00613                           (int) (qqsavnd), (bnfref_struct *) &qqnd, \
00614                           (int) (qqoff), 0 }
00615 
00616 #define dbdef(qqnme,qqdflgs,qqnmcd,qqnm,qqsavnm,qqndcd,qqnd,qqsavnd,qqoff) \
00617 bnfLBdef_struct qqnme = { bnfDL, #qqnme, (flags) (qqdflgs), qqnmcd, qqndcd, \
00618                           (int) (qqsavnm), (bnfref_struct *) &qqnm, \
00619                           (int) (qqsavnd), (bnfref_struct *) &qqnd, \
00620                           (int) (qqoff), 0 }
00621 
00622 #define rfdef(qqnme,qqdflgs,qqnmcd,qqnm,qqsavnm,qqoff,qqndcd,qqnd,qqsavnd,qqoff2) \
00623 bnfLBdef_struct qqnme = { bnfRS, #qqnme, (flags) (qqdflgs), qqnmcd, qqndcd, \
00624                           (int) (qqsavnm), (bnfref_struct *) &qqnm, \
00625                           (int) (qqsavnd), (bnfref_struct *) &qqnd, \
00626                           (int) (qqoff), (int) (qqoff2) }
00627 
00628 #define rbdef(qqnme,qqdflgs,qqnmcd,qqnm,qqsavnm,qqoff,qqndcd,qqnd,qqsavnd,qqoff2) \
00629 bnfLBdef_struct qqnme = { bnfRL, #qqnme, (flags) (qqdflgs), qqnmcd, qqndcd, \
00630                           (int) (qqsavnm), (bnfref_struct *) &qqnm, \
00631                           (int) (qqsavnd), (bnfref_struct *) &qqnd, \
00632                           (int) (qqoff), (int) (qqoff2) }
00633 
00634 #define idef(qqnme,qqval) \
00635 bnfIdef_struct qqnme = { bnfI, #qqnme, (int) (qqval) }
00636 
00637 #define ldef(qqnme,qqdflgs,qqtxt) \
00638 bnfLdef_struct qqnme = { bnfL, #qqnme, (flags) (qqdflgs), (char *) (qqtxt) }
00639 
00640 
00641 
00642 #define gref(qqnme,qqref,qquflgs,qqoff,qqsep) \
00643 bnfGref_struct qqnme = { bnfG, #qqnme, (bnfdef_struct *) &qqref, \
00644                          (flags) (qquflgs), (int) (qqoff), \
00645                          (bnfref_struct *) &qqsep }
00646 
00647 #define npref(qqnme,qqref,qquflgs,qqsep) \
00648 bnfNPref_struct qqnme = { bnfNP, #qqnme, (bnfdef_struct *) &qqref, \
00649                          (flags) (qquflgs), (int) 0, (bnfref_struct *) &qqsep }
00650 
00651 #define pref(qqnme,qqref,qquflgs,qqoff,qqsep) \
00652 bnfPref_struct qqnme = { bnfP, #qqnme, (bnfdef_struct *) &qqref, \
00653                          (flags) (qquflgs), (int) (qqoff), \
00654                          (bnfref_struct *) &qqsep }
00655 
00656 #define tref(qqnme,qqref,qquflgs,qqoff) \
00657 bnfTref_struct qqnme = { bnfT, #qqnme, (bnfdef_struct *) &qqref, \
00658                          (flags) qquflgs, (int) qqoff }
00659 
00660 #define dfref(qqnme,qqref) \
00661 bnfLBref_struct qqnme = { bnfDS, #qqnme, (bnfdef_struct *) &qqref, (flags) 0 }
00662 
00663 #define dbref(qqnme,qqref) \
00664 bnfLBref_struct qqnme = { bnfDL, #qqnme, (bnfdef_struct *) &qqref, (flags) 0 }
00665 
00666 #define rfref(qqnme,qqref) \
00667 bnfLBref_struct qqnme = { bnfRS, #qqnme, (bnfdef_struct *) &qqref, (flags) 0 }
00668 
00669 #define rbref(qqnme,qqref) \
00670 bnfLBref_struct qqnme = { bnfRL, #qqnme, (bnfdef_struct *) &qqref, (flags) 0 }
00671 
00672 #define iref(qqnme,qqref,qqoff) \
00673 bnfIref_struct qqnme = { bnfI, #qqnme, (bnfdef_struct *) &qqref, \
00674                         (flags) 0, (int) qqoff }
00675 
00676 #define lref(qqnme,qqref) \
00677 bnfLref_struct qqnme = { bnfL, #qqnme, (bnfdef_struct *) &qqref, (flags) 0 }
00678 
00679 #ifndef DYLP_NDEBUG
00680 
00681 /*
00682   This set of definitions sets the bnfdebug flag, but doesn't add a separate
00683   uflgs parameter (we don't want to lead the user to think any of the others
00684   are valid).
00685 */
00686 
00687 #define dfrefdbg(qqnme,qqref) \
00688 bnfLBref_struct qqnme = { bnfDS, #qqnme, (bnfdef_struct *) &qqref, \
00689                           (flags) bnfdebug }
00690 
00691 #define dbrefdbg(qqnme,qqref) \
00692 bnfLBref_struct qqnme = { bnfDL, #qqnme, (bnfdef_struct *) &qqref, \
00693                           (flags) bnfdebug }
00694 
00695 #define rfrefdbg(qqnme,qqref) \
00696 bnfLBref_struct qqnme = { bnfRS, #qqnme, (bnfdef_struct *) &qqref, \
00697                           (flags) bnfdebug }
00698 
00699 #define rbrefdbg(qqnme,qqref) \
00700 bnfLBref_struct qqnme = { bnfRL, #qqnme, (bnfdef_struct *) &qqref, \
00701                           (flags) bnfdebug }
00702 
00703 #define lrefdbg(qqnme,qqref) \
00704 bnfLref_struct qqnme = { bnfL, #qqnme, (bnfdef_struct *) &qqref, \
00705                           (flags) bnfdebug }
00706 
00707 #endif /* DYLP_NDEBUG */
00708 
00709 
00710 
00711 /*
00712   Last, but not least, some declarations to allow the use of the bnf reader.
00713   rdrinit and rdrclear initialize and clear the reader; they should bracket
00714   related groups of calls. parse is the main parsing routine. The union type
00715   parse_any is the appropriate thing to hold the result.
00716 */
00717 
00718 typedef union { void *g ;
00719                 char *c ; } parse_any ;
00720 
00721 extern void rdrinit(void),rdrclear(void) ;
00722 extern bool parse(ioid chn, struct bnfref_type3 *bnfid, parse_any *result) ;
00723 
00724 #ifndef DYLP_NDEBUG
00725 /*
00726   The control routine for the bnf debugging trace output. See the comments
00727   in bnfrdr.c for the proper use of the parameters.
00728 */
00729   
00730 extern void bnfdbgctl(ioid dbgchn, bool dbgecho, bool warnzlbl, bool numlvl,
00731                       bool tablvl) ;
00732 #else
00733 #define bnfdbgctl(dgbchn,dbgecho,warnzlbl,numlvl,tablvl)
00734 #endif
00735 
00736 /*
00737   Utility print routines from bnfrdrio.c.
00738 */
00739 
00740 extern void prtbnfref(ioid chn, bool echo, bnfref_struct *ref),
00741             prtbnfdef(ioid chn, bool echo, bnfdef_struct *def) ;
00742 
00743 #endif /* _DYLIB_BNFRDR_H */
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines