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 150 2007-06-13 22:53:34Z 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 Data structures used for bnf definitions. There are three types of things 00221 here: individual structures for the various definition types, a common 00222 structure which consists only of the fields common to all of the individual 00223 structures, and a pointer union which is handy when walking around in a bnf. 00224 00225 Just to keep the explanation in hand a bit, let's define components and 00226 alternatives. The body of a bnf definition consists of alternatives 00227 (alternative parses), each of which has a number of components. A component 00228 array is an array of pointers to bnf reference structures, each of which in 00229 turn references a bnf definition structure. An alternative array is an array 00230 of pointers to component arrays. I know this is ugly and involves a lot of 00231 dereferencing but it seems to be the only way to handle the variable lengths 00232 involved. 00233 00234 NOTE: To keep things from getting completely out of hand, the first entry in 00235 a component or alternative array specifies the number of pointers that 00236 follow. This is one of the (ab)uses of the int - pointer - int cast. 00237 */ 00238 00239 /* 00240 The common portion. 00241 00242 Field Description 00243 ----- ----------- 00244 type Type code identifying what sort of definition this is. 00245 name The name of the rule (derived from the C variable name; 00246 see the macros gdef, npdef, etc.) 00247 */ 00248 00249 #define bnfdef_common bnftype_enum type ; \ 00250 const char *name ; 00251 00252 typedef struct { bnfdef_common } bnfdef_struct ; 00253 00254 00255 /* 00256 Data structure for a generator definition. Generators cause the creation of a 00257 node in the data structure being built for the user. For simplicity, they may 00258 not have alternative parses, but since they can reference non-primitives no 00259 flexibility is lost. 00260 00261 Field Description 00262 ----- ----------- 00263 bnfdef_common As above. 00264 size Size (in bytes) of the node to be created. 00265 link Offset (in bytes) from the base of the node created by the 00266 generator to the field used as a link field when this node is 00267 in a linked list. 00268 comps Pointer to a component array. 00269 */ 00270 00271 typedef struct { bnfdef_common 00272 int size ; 00273 int link ; 00274 struct bnfref_struct_tag **comps ; } bnfGdef_struct ; 00275 00276 00277 /* 00278 Data structure for a non-primitive definition. Non-primitives are simply a 00279 device for defining alternative parses. They don't directly create anything. 00280 00281 Field Description 00282 ----- ----------- 00283 bnfdef_common As above. 00284 alts Pointer to an alternative array. 00285 */ 00286 00287 typedef struct {bnfdef_common 00288 struct bnfref_struct_tag ***alts ; } bnfNPdef_struct ; 00289 00290 00291 00292 /* 00293 Data structure for a primitive definition. The distinction between a 00294 primitive and a non-primitive is that a primitive constructs a string which 00295 is the concatenation of the strings returned by the bnf's referenced in the 00296 primitive's body. The data structure is identical to that for non-primitives. 00297 */ 00298 00299 typedef bnfNPdef_struct bnfPdef_struct ; 00300 00301 00302 /* 00303 Data structure for a terminal. Terminals are used to specify specific things 00304 to be obtained from the input stream. The various parameters required to 00305 describe a terminal should really be mushed into a union, but then the bnf 00306 data structure would have to be built dynamically, since unions can't be 00307 initialized. 00308 00309 Field Description 00310 ----- ----------- 00311 bnfdef_common As above. 00312 ttype Code identifying the type of terminal to be obtained. 00313 qschr Starting character for a quoted string. 00314 qechr Ending character for a quoted string. 00315 parm1 Overloaded field, interpreted as follows: 00316 numbers: specifies the radix 00317 fixed-length strings: specifies the string length 00318 val Expected value of the string obtained from the input stream. 00319 (This test is applied before the string is converted to the 00320 internal form appropriate for whatever is specified in ttype.) 00321 */ 00322 00323 typedef struct { bnfdef_common 00324 bnfttype_enum ttype ; 00325 char qschr ; 00326 char qechr ; 00327 int parm1 ; 00328 const char *val ; } bnfTdef_struct ; 00329 00330 00331 /* 00332 Data structure for an immediate value. Immediates are used to jam a code into 00333 the data structure being built. 00334 00335 Field Description 00336 ----- ----------- 00337 bnfdef_common As above. 00338 ival Integer value. 00339 */ 00340 00341 typedef struct {bnfdef_common 00342 int ival ; } bnfIdef_struct ; 00343 00344 00345 /* 00346 Data structure for a literal. Literals are used to insert characters into the 00347 input stream. (Handy for generating label names, for instance.) 00348 00349 Field Description 00350 ----- ----------- 00351 bnfdef_common As above. 00352 dflgs Flags. 00353 txt The string to be inserted. This field is also used to index 00354 into the saved text array by casting it to an int. 00355 */ 00356 00357 typedef struct { bnfdef_common 00358 flags dflgs ; 00359 char *txt ; } bnfLdef_struct ; 00360 00361 00362 /* 00363 Last but not least, the data structure used to define socket/label 00364 definitions and references. (Definitions, mind you - there is another 00365 structure to reference socket/label definitions and references.) A 00366 socket/label definition associates of a name (a text string) with a value 00367 (almost always an address). A socket/label reference specifies a socket 00368 and a label. The label is inserted into the socket. Fields prefixed by nm 00369 are the name in a socket/label definition and the socket in a socket/label 00370 reference. Fields prefixed by nd are the value in a socket/label definition 00371 and the label in a socket/label reference. 00372 00373 Field Description 00374 ----- ----------- 00375 bnfdef_common As above. 00376 dflgs Flags. 00377 nmcd Specifies how name/socket will be obtained. 00378 ndcd Specifies how value/label will be obtained. 00379 savnm Specifies location in saved text array where string associated 00380 with nm will be stored. 00381 nmsrc Pointer to bnf which will produce string for nm, or cast into 00382 an int and used as a location in the saved text array. 00383 savnd Specifies location in saved text array where string associated 00384 with nd will be stored. 00385 ndsrc Pointer to bnf which will produce string for nd, or cast into 00386 an int and used as a location in the saved text array. 00387 offset Correction (in bytes) to socket/label value (socket/label 00388 definitions) or socket (socket/label references). 00389 offset2 Correction (in bytes) to label (socket/label references). 00390 */ 00391 00392 typedef struct { bnfdef_common 00393 flags dflgs ; 00394 bnflblsrc_enum nmcd ; 00395 bnflblsrc_enum ndcd ; 00396 int savnm ; 00397 struct bnfref_struct_tag *nmsrc ; 00398 int savnd ; 00399 struct bnfref_struct_tag *ndsrc ; 00400 int offset ; 00401 int offset2 ; } bnfLBdef_struct ; 00402 00403 00404 /* 00405 And finally, the handy union of pointers promised back at the start. We 00406 really should be using this in the bnf reference structure declarations, 00407 rather than (bnfdef_struct *), but since references and definitions are 00408 mutually recursive we get into ugliness. There's also the point that we 00409 want to be able to create bnfs at compile time and you can't initialize 00410 unions. 00411 */ 00412 00413 typedef union { bnfdef_struct *com ; 00414 bnfGdef_struct *G ; 00415 bnfNPdef_struct *NP ; 00416 bnfPdef_struct *P ; 00417 bnfTdef_struct *T ; 00418 bnfIdef_struct *I ; 00419 bnfLdef_struct *L ; 00420 bnfLBdef_struct *LB ; } bnfdef_any ; 00421 00422 00423 00424 /* 00425 Now, on to the data structures used to reference bnf definitions. Recall if 00426 you will the introductory comments about component and alternative arrays and 00427 the general setup of the bnf data structure. We have the same three types of 00428 data structures here as for bnf definitions. 00429 */ 00430 00431 /* 00432 The common portion. It includes a type code, a name, usage flags, and a 00433 pointer to the bnf definition. 00434 00435 Field Description 00436 ----- ----------- 00437 type Type code identifying what sort of definition this reference 00438 points to. 00439 name The name of the reference (derived from the C variable name; 00440 see the macros qref, npref, pref, etc.) 00441 uflgs Usage flags. 00442 defn Pointer to a bnf definition structure. 00443 */ 00444 00445 #define bnfref_common bnftype_enum type ; \ 00446 const char *name ; \ 00447 bnfdef_struct *defn ; \ 00448 flags uflgs ; 00449 00450 typedef struct bnfref_struct_tag { bnfref_common } bnfref_struct ; 00451 00452 00453 /* 00454 References to labels of all flavours and to literals require only the 00455 common fields. The only reason we need the uflgs field is for the bnfdebug 00456 flag. 00457 */ 00458 00459 typedef bnfref_struct bnfLBref_struct ; 00460 typedef bnfref_struct bnfLref_struct ; 00461 00462 00463 /* 00464 References to terminals and immediates require an offset for storage. 00465 00466 Field Description 00467 ----- ----------- 00468 bnfref_common As above. 00469 offset Offset (in bytes) into current node to the field where the 00470 value produced by the referenced bnf will be stored. 00471 */ 00472 00473 struct bnfref_type2 { bnfref_common 00474 int offset ; } ; 00475 00476 typedef struct bnfref_type2 bnfTref_struct ; 00477 typedef struct bnfref_type2 bnfIref_struct ; 00478 00479 00480 /* 00481 References to generators, non-primitives, and primitives can be in lists and 00482 require a separator specification in addition to the offset. Non-primitives 00483 do not make use of the offset field. 00484 00485 Field Description 00486 ----- ----------- 00487 bnfref_common As above. 00488 offset Offset (in bytes) into current node to the field where the 00489 value produced by the referenced bnf will be stored. 00490 sep A reference to a bnf definition describing the separator 00491 between list elements in the input stream. 00492 */ 00493 00494 struct bnfref_type3 { bnfref_common 00495 int offset ; 00496 bnfref_struct *sep ; } ; 00497 00498 typedef struct bnfref_type3 bnfGref_struct ; 00499 typedef struct bnfref_type3 bnfNPref_struct ; 00500 typedef struct bnfref_type3 bnfPref_struct ; 00501 00502 00503 /* 00504 And the handy union pointer type. Same general comments as for the 00505 declaration of bnfdef_any. 00506 */ 00507 00508 typedef union { bnfref_struct *com ; 00509 struct bnfref_type1 *t1 ; 00510 struct bnfref_type2 *t2 ; 00511 struct bnfref_type3 *t3 ; 00512 bnfGref_struct *G ; 00513 bnfNPref_struct *NP ; 00514 bnfPref_struct *P ; 00515 bnfTref_struct *T ; 00516 bnfIref_struct *I ; 00517 bnfLref_struct *L ; 00518 bnfLBref_struct *LB ; } bnfref_any ; 00519 00520 00521 00522 /* 00523 The macros that make defining the bnf data structures marginally 00524 less painful. 00525 */ 00526 00527 /* 00528 Macros to help with constructing field offsets. NULLP is specially designed 00529 to produce a NULL value when used as &NULLP. This is required for some of the 00530 macros where one must fill the field with either the address of a 00531 bnfref_struct or the value NULL. By this device we avoid having to make the 00532 user aware of when and when not to use &. mkoff simply produces the offset of 00533 a given field in a structure type. 00534 */ 00535 00536 #define NULLP (*((char *) 0)) 00537 #define mksav(qqoff) (*((char *) qqoff)) 00538 #define mkoff(qqtype,qqfield) (&((qqtype *) 0)->qqfield) 00539 00540 /* 00541 Macros for alternative and component lists. These just generate the headers; 00542 the actual lists have to be typed out, as: 00543 00544 althd(arule_alts) = { altcnt(3), 00545 mkaref(arule_alt1), mkaref(arule_alt2), 00546 mkaref(arule_alt3) } ; 00547 00548 comphd(arule_alt1) = { compcnt(2), 00549 mkcref(brule_ref), mkcref(crule_ref) } ; 00550 00551 where brule_ref and crule_ref are bnf references (most likely constructed 00552 using the gref, npref, etc. macros). 00553 */ 00554 00555 #define althd(qqnme) bnfref_struct **qqnme[] 00556 #define altcnt(qqcnt) (bnfref_struct **) (qqcnt) 00557 #define mkaref(qqref) (bnfref_struct **) (qqref) 00558 00559 #define comphd(qqnme) bnfref_struct *qqnme[] 00560 #define compcnt(qqcnt) (bnfref_struct *) (qqcnt) 00561 #define mkcref(qqref) (bnfref_struct *) (&qqref) 00562 00563 /* 00564 Macros to initialise bnf definitions. Note the use of the ANSI C 00565 'stringisation' operator, '#', to get a text string for the name. For 00566 non-ANSI implementations, replacing #qqnme with "qqnme" usually works (but 00567 not all non-ANSI preprocessor implementations will see the macro parameter 00568 inside a string, and ANSI C explicitly disallows it). 00569 */ 00570 00571 #define gdef(qqnme,qqsze,qqlnk,qqcomps) \ 00572 bnfGdef_struct qqnme = { bnfG, #qqnme, (int) (qqsze), (int) (qqlnk), \ 00573 (bnfref_struct **) qqcomps } 00574 00575 #define npdef(qqnme,qqalts) \ 00576 bnfNPdef_struct qqnme = { bnfNP, #qqnme, (bnfref_struct ***) qqalts } 00577 00578 #define pdef(qqnme,qqalts) \ 00579 bnfPdef_struct qqnme = { bnfP, #qqnme, (bnfref_struct ***) qqalts } 00580 00581 #define tdef(qqnme,qqttype,qqparm,qqval) \ 00582 bnfTdef_struct qqnme = { bnfT, #qqnme, qqttype, '\0', '\0', \ 00583 (int) (qqparm), (const char *) (qqval) } 00584 00585 #define tqdef(qqnme,qqschr,qqechr,qqval) \ 00586 bnfTdef_struct qqnme = { bnfT, #qqnme, bnfttQ, (char) qqschr, (char) qqechr,\ 00587 0, (char *) (qqval) } 00588 00589 #define dfdef(qqnme,qqdflgs,qqnmcd,qqnm,qqsavnm,qqndcd,qqnd,qqsavnd,qqoff) \ 00590 bnfLBdef_struct qqnme = { bnfDS, #qqnme, (flags) (qqdflgs), qqnmcd, qqndcd, \ 00591 (int) (qqsavnm), (bnfref_struct *) &qqnm, \ 00592 (int) (qqsavnd), (bnfref_struct *) &qqnd, \ 00593 (int) (qqoff), 0 } 00594 00595 #define dbdef(qqnme,qqdflgs,qqnmcd,qqnm,qqsavnm,qqndcd,qqnd,qqsavnd,qqoff) \ 00596 bnfLBdef_struct qqnme = { bnfDL, #qqnme, (flags) (qqdflgs), qqnmcd, qqndcd, \ 00597 (int) (qqsavnm), (bnfref_struct *) &qqnm, \ 00598 (int) (qqsavnd), (bnfref_struct *) &qqnd, \ 00599 (int) (qqoff), 0 } 00600 00601 #define rfdef(qqnme,qqdflgs,qqnmcd,qqnm,qqsavnm,qqoff,qqndcd,qqnd,qqsavnd,qqoff2) \ 00602 bnfLBdef_struct qqnme = { bnfRS, #qqnme, (flags) (qqdflgs), qqnmcd, qqndcd, \ 00603 (int) (qqsavnm), (bnfref_struct *) &qqnm, \ 00604 (int) (qqsavnd), (bnfref_struct *) &qqnd, \ 00605 (int) (qqoff), (int) (qqoff2) } 00606 00607 #define rbdef(qqnme,qqdflgs,qqnmcd,qqnm,qqsavnm,qqoff,qqndcd,qqnd,qqsavnd,qqoff2) \ 00608 bnfLBdef_struct qqnme = { bnfRL, #qqnme, (flags) (qqdflgs), qqnmcd, qqndcd, \ 00609 (int) (qqsavnm), (bnfref_struct *) &qqnm, \ 00610 (int) (qqsavnd), (bnfref_struct *) &qqnd, \ 00611 (int) (qqoff), (int) (qqoff2) } 00612 00613 #define idef(qqnme,qqval) \ 00614 bnfIdef_struct qqnme = { bnfI, #qqnme, (int) (qqval) } 00615 00616 #define ldef(qqnme,qqdflgs,qqtxt) \ 00617 bnfLdef_struct qqnme = { bnfL, #qqnme, (flags) (qqdflgs), (char *) (qqtxt) } 00618 00619 00620 00621 #define gref(qqnme,qqref,qquflgs,qqoff,qqsep) \ 00622 bnfGref_struct qqnme = { bnfG, #qqnme, (bnfdef_struct *) &qqref, \ 00623 (flags) (qquflgs), (int) (qqoff), \ 00624 (bnfref_struct *) &qqsep } 00625 00626 #define npref(qqnme,qqref,qquflgs,qqsep) \ 00627 bnfNPref_struct qqnme = { bnfNP, #qqnme, (bnfdef_struct *) &qqref, \ 00628 (flags) (qquflgs), (int) 0, (bnfref_struct *) &qqsep } 00629 00630 #define pref(qqnme,qqref,qquflgs,qqoff,qqsep) \ 00631 bnfPref_struct qqnme = { bnfP, #qqnme, (bnfdef_struct *) &qqref, \ 00632 (flags) (qquflgs), (int) (qqoff), \ 00633 (bnfref_struct *) &qqsep } 00634 00635 #define tref(qqnme,qqref,qquflgs,qqoff) \ 00636 bnfTref_struct qqnme = { bnfT, #qqnme, (bnfdef_struct *) &qqref, \ 00637 (flags) qquflgs, (int) qqoff } 00638 00639 #define dfref(qqnme,qqref) \ 00640 bnfLBref_struct qqnme = { bnfDS, #qqnme, (bnfdef_struct *) &qqref, (flags) 0 } 00641 00642 #define dbref(qqnme,qqref) \ 00643 bnfLBref_struct qqnme = { bnfDL, #qqnme, (bnfdef_struct *) &qqref, (flags) 0 } 00644 00645 #define rfref(qqnme,qqref) \ 00646 bnfLBref_struct qqnme = { bnfRS, #qqnme, (bnfdef_struct *) &qqref, (flags) 0 } 00647 00648 #define rbref(qqnme,qqref) \ 00649 bnfLBref_struct qqnme = { bnfRL, #qqnme, (bnfdef_struct *) &qqref, (flags) 0 } 00650 00651 #define iref(qqnme,qqref,qqoff) \ 00652 bnfIref_struct qqnme = { bnfI, #qqnme, (bnfdef_struct *) &qqref, \ 00653 (flags) 0, (int) qqoff } 00654 00655 #define lref(qqnme,qqref) \ 00656 bnfLref_struct qqnme = { bnfL, #qqnme, (bnfdef_struct *) &qqref, (flags) 0 } 00657 00658 #ifndef DYLP_NDEBUG 00659 00660 /* 00661 This set of definitions sets the bnfdebug flag, but doesn't add a separate 00662 uflgs parameter (we don't want to lead the user to think any of the others 00663 are valid). 00664 */ 00665 00666 #define dfrefdbg(qqnme,qqref) \ 00667 bnfLBref_struct qqnme = { bnfDS, #qqnme, (bnfdef_struct *) &qqref, \ 00668 (flags) bnfdebug } 00669 00670 #define dbrefdbg(qqnme,qqref) \ 00671 bnfLBref_struct qqnme = { bnfDL, #qqnme, (bnfdef_struct *) &qqref, \ 00672 (flags) bnfdebug } 00673 00674 #define rfrefdbg(qqnme,qqref) \ 00675 bnfLBref_struct qqnme = { bnfRS, #qqnme, (bnfdef_struct *) &qqref, \ 00676 (flags) bnfdebug } 00677 00678 #define rbrefdbg(qqnme,qqref) \ 00679 bnfLBref_struct qqnme = { bnfRL, #qqnme, (bnfdef_struct *) &qqref, \ 00680 (flags) bnfdebug } 00681 00682 #define lrefdbg(qqnme,qqref) \ 00683 bnfLref_struct qqnme = { bnfL, #qqnme, (bnfdef_struct *) &qqref, \ 00684 (flags) bnfdebug } 00685 00686 #endif /* DYLP_NDEBUG */ 00687 00688 00689 00690 /* 00691 Last, but not least, some declarations to allow the use of the bnf reader. 00692 rdrinit and rdrclear initialize and clear the reader; they should bracket 00693 related groups of calls. parse is the main parsing routine. The union type 00694 parse_any is the appropriate thing to hold the result. 00695 */ 00696 00697 typedef union { void *g ; 00698 char *c ; } parse_any ; 00699 00700 extern void rdrinit(void),rdrclear(void) ; 00701 extern bool parse(ioid chn, struct bnfref_type3 *bnfid, parse_any *result) ; 00702 00703 #ifndef DYLP_NDEBUG 00704 /* 00705 The control routine for the bnf debugging trace output. See the comments 00706 in bnfrdr.c for the proper use of the parameters. 00707 */ 00708 00709 extern void bnfdbgctl(ioid dbgchn, bool dbgecho, bool warnzlbl, bool numlvl, 00710 bool tablvl) ; 00711 #else 00712 #define bnfdbgctl(dgbchn,dbgecho,warnzlbl,numlvl,tablvl) 00713 #endif 00714 00715 /* 00716 Utility print routines from bnfrdrio.c. 00717 */ 00718 00719 extern void prtbnfref(ioid chn, bool echo, bnfref_struct *ref), 00720 prtbnfdef(ioid chn, bool echo, bnfdef_struct *def) ; 00721 00722 #endif /* _DYLIB_BNFRDR_H */