1 /*===========================================================================
2 *
3 *                            PUBLIC DOMAIN NOTICE
4 *               National Center for Biotechnology Information
5 *
6 *  This software/database is a "United States Government Work" under the
7 *  terms of the United States Copyright Act.  It was written as part of
8 *  the author's official duties as a United States Government employee and
9 *  thus cannot be copyrighted.  This software/database is freely available
10 *  to the public for use. The National Library of Medicine and the U.S.
11 *  Government have not placed any restriction on its use or reproduction.
12 *
13 *  Although all reasonable efforts have been taken to ensure the accuracy
14 *  and reliability of the software and data, the NLM and the U.S.
15 *  Government do not and cannot warrant the performance or results that
16 *  may be obtained by using this software or data. The NLM and the U.S.
17 *  Government disclaim all warranties, express or implied, including
18 *  warranties of performance, merchantability or fitness for any particular
19 *  purpose.
20 *
21 *  Please cite the author in any work or product based on this material.
22 *
23 * ===========================================================================
24 *
25 */
26 
27 #ifndef _h_schema_parse_
28 #define _h_schema_parse_
29 
30 #ifndef _h_schema_priv_
31 #include "schema-priv.h"
32 #endif
33 
34 #ifndef _h_schema_tok_
35 #include "schema-tok.h"
36 #endif
37 
38 #ifndef _h_klib_symtab_
39 #include <klib/symtab.h>
40 #endif
41 
42 #ifndef _h_klib_debug_
43 #include <klib/debug.h>
44 #endif
45 
46 #ifdef __cplusplus
47 extern "C" {
48 #endif
49 
50 
51 /*--------------------------------------------------------------------------
52  * defines
53  */
54 #define PARSE_DEBUG( msg ) \
55     DBGMSG ( DBG_VDB, DBG_FLAG ( DBG_VDB_PARSE ), msg )
56 
57 
58 /*--------------------------------------------------------------------------
59  * forwards
60  */
61 struct SVector;
62 struct STable;
63 struct SDatabase;
64 struct SFunction;
65 struct SConstExpr;
66 struct SFormParmlist;
67 struct SExpression;
68 struct STypeExpr;
69 
70 /*--------------------------------------------------------------------------
71  * extension of token ids
72  */
73 enum
74 {
75     /* a symbolic constant */
76     eConstant = eNumSymtabIDs,
77 
78     /* format type */
79     eFormat,
80 
81     /* dynamic data type */
82     eDatatype,
83 
84     /* typeset */
85     eTypeset,
86 
87     /* factory */
88     eFactory,
89 
90     /* external C function */
91     eFunction,
92     eUntypedFunc,
93     eRowLengthFunc,
94 
95     /* script function */
96     eScriptFunc,
97 
98     /* schema type and param
99        a schema type is a templatized type, basically
100        a name without a completed definition
101 
102        a schema param is a parameterized constant that
103        can be used in defining type vector dimensions */
104     eSchemaType,
105     eSchemaParam,
106 
107     /* factory param and name
108        a factory param is a templatized constant, but
109        cannot be used to define type dimensions */
110     eFactParam,
111 
112     /* function param */
113     eFuncParam,
114 
115     /* intermediate production */
116     eProduction,
117 
118     /* physical column */
119     ePhysical,
120 
121     /* physical column member */
122     ePhysMember,
123 
124     /* external column */
125     eColumn,
126 
127     /* forward declaration */
128     eForward,
129 
130     /* purely virtual production */
131     eVirtual,
132 
133     /* table */
134     eTable,
135 
136     /* table member */
137     eTblMember,
138 
139     /* database */
140     eDatabase,
141 
142     /* database member */
143     eDBMember,
144 
145     /* view */
146     eView,
147 
148     /* keywords */
149     eFirstKeyword,
150 
151     kw_alias = eFirstKeyword,
152     kw_column,
153     kw_const,
154     kw_control,
155     kw_database,
156     kw_decode,
157     kw_default,
158     kw_encode,
159     kw_extern,
160     kw_false,
161     kw_fmtdef,
162     kw_function,
163     kw_include,
164     kw_index,
165     kw_limit,
166     kw_physical,
167     kw_read,
168     kw_readonly,
169     kw_return,
170     kw_schema,
171     kw_static,
172     kw_table,
173     kw_template,
174     kw_trigger,
175     kw_true,
176     kw_type,
177     kw_typedef,
178     kw_typeset,
179     kw_validate,
180     kw_version,
181     kw_view,
182     kw_virtual,
183     kw_void,
184     kw_writeonly,
185 
186     /* special keywords */
187     kw___untyped,
188     kw___row_length,
189     kw___no_header
190 
191 };
192 
193 /* SchemaEnv
194  *  states the schema language version
195  *  gives switches as to features, errors, warnings, etc.
196  */
197 typedef struct SchemaEnv SchemaEnv;
198 struct SchemaEnv
199 {
200     /* maj.min.rel format,
201        only maj.min supported */
202     uint32_t version;
203 
204     /* V0 COMPATIBILITY SWITCHES */
205     uint32_t schema_param_types_absent : 1;
206     uint32_t mixed_fact_param_list : 1;
207     uint32_t script_function_called_schema : 1;
208 
209     /* V1 SWITCHES */
210     uint32_t default_view_decl : 1;
211     uint32_t has_view_keyword : 1;
212 };
213 
214 /* SCHEMA_LANG_VERSION
215  *  version numbers of schema language
216  */
217 #define CUR_SCHEMA_LANG_VERSION 0x01000000
218 #define EXT_SCHEMA_LANG_VERSION 0x01000000
219 
220 /* Init
221  *  initialize to current version
222  */
223 void SchemaEnvInit ( SchemaEnv *env, uint32_t version );
224 
225 /*--------------------------------------------------------------------------
226  * schema-parse.c
227  */
228 
229 /*
230  * schema             = [ <schema-version> ';' ] [ <schema-decl-list> ]
231  *
232  * schema-decl-list   = <schema-decl> [ <schema-decl-list> ]
233  *
234  * schema-decl        = <type-definition> ';'
235  *                    | <typeset-definition> ';'
236  *                    | <format-definition> ';'
237  *                    | <function-decl> ';'
238  *                    | <schema-decl>
239  *                    | <table-decl>
240  *
241  * schema-version     = 'version' <maj-min>
242  */
243 rc_t schema ( KTokenSource *src, VSchema *self );
244 
245 /*
246  * init_symtab
247  *  initializes "tbl"
248  *  places schema and parents into scope
249  *  must be balanced by KSymTableWhack
250  */
251 rc_t init_symtab ( KSymTable *tbl, const VSchema *self );
252 
253 /* next_token
254  *  gets next token
255  *  looks up any identifier in symbol table
256  *  converts token id to found symbol type
257  * next_shallow_token
258  *  only searches current scope, and optionally intrinsic scope
259  */
260 #define next_token vdb_next_token
261 #define next_shallow_token vdb_next_shallow_token
262 KToken *next_token ( const KSymTable *tbl, KTokenSource *src, KToken *t );
263 KToken *next_shallow_token ( const KSymTable *tbl,
264     KTokenSource *src, KToken *t, bool plus_intrinsic );
265 
266 /* expect
267  *  performs a comparison of t->id against id, and takes one of 3 actions:
268  *  1) when ids match, advance to next token and return 0
269  *  2) when ids don't match but the expected token is not required,
270  *     issue a KTokenExpected warning using expected text and return 0
271  *  3) when ids don't match and the expected token is required,
272  *     issue a KTokenExpected error using expected text and return its rc_t
273  */
274 rc_t expect ( const KSymTable *tbl, KTokenSource *src, KToken *t,
275     int id, const char *expected, bool required );
276 
277 /*
278  * maj-min            = <uint-expr> [ '.' <uint-expr> ]
279  * maj-min-rel        = <uint-expr> [ '.' <uint-expr> [ '.' <uint-expr> ] ]
280  */
281 rc_t maj_min_rel ( const KSymTable *tbl, KTokenSource *src, KToken *t,
282     const SchemaEnv *env, const VSchema *self, uint32_t *version, bool accept_release );
283 
284 rc_t next_uint ( const KSymTable *tbl, KTokenSource *src, KToken *t,
285     const SchemaEnv *env, const VSchema *self, uint32_t *val );
286 
287 /* resolve_object
288  *  generic object find
289  *
290  *  "td" [ OUT, NULL OKAY ] - returns cast type expression
291  *  if given or "any" if not
292  *
293  *  "name" [ OUT ] - returns list of overloaded objects if found
294  *
295  *  "type" [ OUT ] - returns object type id, e.g.:
296  *    eDatatype, eTypeset, eFormat, eFunction, ePhysical, eTable, ...
297  *
298  *  "expr" [ IN ] - NUL terminated name expression identifying object
299  *
300  *  "ctx" [ IN ] - NUL terminated context string for evaluation,
301  *  substitutes for filename in logging reports
302  *
303  *  "dflt" [ IN ] - if true, resolve default value
304  *
305  *  returns principal object identified. if NULL but "name" is not
306  *  NULL, then the object was only partially identified.
307  */
308 const void *resolve_object ( const KSymTable *tbl,
309     const VSchema *self, VTypedecl *td, const SNameOverload **name,
310     uint32_t *type, const char *expr, const char *ctx, bool dflt );
311 
312 
313 /*--------------------------------------------------------------------------
314  * schema-type.c
315  */
316 
317 
318 /*
319  * fqn                = ID [ <nested-name> ]
320  * nested-name        = ':' NAME [ <nested-name> ]
321  */
322 rc_t next_fqn ( const KSymTable *tbl, KTokenSource *src, KToken *t,
323     const SchemaEnv *env );
324 rc_t create_fqn ( KSymTable *tbl, KTokenSource *src, KToken *t,
325     const SchemaEnv *env, uint32_t id, const void *obj );
326 
327 
328 /*
329  * dim                = '[' <uint-expr> ']'
330  */
331 rc_t dim ( const KSymTable *tbl, KTokenSource *src, KToken *t,
332     const SchemaEnv *env, const VSchema *self, uint32_t *dim, bool required );
333 
334 /*
335  * typename           = <fqn>
336  * typedecl           = <typename> [ <dim> ]
337  */
338 rc_t type_name ( const KSymTable *tbl, KTokenSource *src, KToken *t,
339     const SchemaEnv *env, uint32_t *id );
340 rc_t typedecl ( const KSymTable *tbl, KTokenSource *src, KToken *t,
341     const SchemaEnv *env, const VSchema *self, VTypedecl *td );
342 
343 /*
344  * typeset            = <fqn>
345  * typespec           = <typedecl>
346  *                    | <typeset> [ <dim> ]
347  */
348 rc_t typeset ( const KSymTable *tbl, KTokenSource *src, KToken *t,
349     const SchemaEnv *env, uint32_t *id );
350 rc_t typespec ( const KSymTable *tbl, KTokenSource *src, KToken *t,
351     const SchemaEnv *env, const VSchema *self, VTypedecl *td );
352 
353 /*
354  * fmtname            = <fqn>
355  * fmtdecl            = <fmtname> [ '/' <typedecl> ]
356  *                    | <typedecl>
357  * fmtspec            = <fmtname> [ '/' <typedecl> ]
358  *                    | <typespec>
359  */
360 rc_t fmtname ( const KSymTable *tbl, KTokenSource *src, KToken *t,
361     const SchemaEnv *env, uint32_t *id );
362 rc_t fmtdecl ( const KSymTable *tbl, KTokenSource *src, KToken *t,
363     const SchemaEnv *env, const VSchema *self, VFormatdecl *fd );
364 rc_t fmtspec ( const KSymTable *tbl, KTokenSource *src, KToken *t,
365     const SchemaEnv *env, const VSchema *self, VFormatdecl *fd );
366 
367 /*
368  * type-definition    = 'typedef' <typename> <typedef-list>
369  * typedef-list       = <typedef-decl> [ ',' <typedef-list> ]
370  * typedef-decl       = <fqn> [ <dim> ]
371  */
372 rc_t type_definition ( KSymTable *tbl, KTokenSource *src, KToken *t,
373     const SchemaEnv *env, VSchema *self );
374 
375 /*
376  * typeset-definition = 'typeset' <typeset> '{' <typespec-list> '}'
377  * typespec-list      = <typespec> [ ',' <typespec-list> ]
378  */
379 rc_t typeset_definition ( KSymTable *tbl, KTokenSource *src, KToken *t,
380     const SchemaEnv *env, VSchema *self );
381 
382 /*
383  * format-definition  = 'fmtdef' [ <fmtname> ] <fqn>
384  */
385 rc_t format_definition ( KSymTable *tbl, KTokenSource *src, KToken *t,
386     const SchemaEnv *env, VSchema *self );
387 
388 
389 /*--------------------------------------------------------------------------
390  * schema-func.c
391  */
392 
393 /*
394  * function-decl      = [ 'extern' ] 'function' <ext-function-decl> ';'
395  *                    | 'validate' 'function' <validate-function-decl> ';'
396  *                    | 'schema' [ 'function' ] <sch-func-decl>
397  *                    | 'function' <ext-func-decl> ';'
398  *                    | 'function' <sch-func-decl>
399  */
400 rc_t function_declaration ( KSymTable *tbl, KTokenSource *src, KToken *t,
401     const SchemaEnv *env, VSchema *self );
402 rc_t extfunc_declaration ( KSymTable *tbl, KTokenSource *src, KToken *t,
403     const SchemaEnv *env, VSchema *self );
404 rc_t valfunc_declaration ( KSymTable *tbl, KTokenSource *src, KToken *t,
405     const SchemaEnv *env, VSchema *self );
406 rc_t script_declaration ( KSymTable *tbl, KTokenSource *src, KToken *t,
407     const SchemaEnv *env, VSchema *self );
408 
409 /*
410  * schema-signature   = <schema-formals>
411  * schema-formals     = <schema-formal> [ ',' <schema-formals> ]
412  * schema-formal      = <schema-typedecl> ID
413  * schema-parmname    = ID
414  */
415 rc_t schema_signature ( KSymTable *tbl, KTokenSource *src, KToken *t,
416     const SchemaEnv *env, VSchema *self, struct SFunction *sig );
417 
418 /*
419  * fact-signature     = <fact-formals> [ '*' <fact-formals> ] [ ',' '...' ]
420  *                    | '*' <fact-formals> [ ',' '...' ]
421  *                    | '...'
422  */
423 rc_t fact_signature ( KSymTable *tbl, KTokenSource *src, KToken *t,
424     const SchemaEnv *env, VSchema *self, struct SFormParmlist *sig );
425 
426 
427 /*--------------------------------------------------------------------------
428  * schema-prod.c
429  */
430 
431 /*
432  * production-stmt    = <func-fmtdecl> ID <assign-expr>
433  *                    | 'trigger' ID <assign-expr>
434  */
435 rc_t production_stmt ( KSymTable *tbl, KTokenSource *src, KToken *t,
436     const SchemaEnv *env, VSchema *self, struct Vector *v, uint32_t ptype );
437 
438 /*
439  * script-body        = '{' <script-stmts> '}'
440  */
441 rc_t script_body ( KSymTable *tbl, KTokenSource *src, KToken *t,
442     const SchemaEnv *env, VSchema *self, struct SFunction *f );
443 
444 /*
445  * physical-decl      = 'physical' [ 'column' ] <typedecl>
446  *                       <fqn> '#' <maj-min-rel> <phys-body>
447  */
448 rc_t physical_declaration ( KSymTable *tbl, KTokenSource *src, KToken *t,
449     const SchemaEnv *env, VSchema *self );
450 
451 
452 /*--------------------------------------------------------------------------
453  * schema-expr.c
454  */
455 
456 /*
457  * dim-expr           = '[' <uint-expr> ']'
458  */
459 rc_t dim_expr ( const KSymTable *tbl, KTokenSource *src, KToken *t,
460     const SchemaEnv *env, struct SExpression const **dim, bool required );
461 
462 
463 /*
464  * cond-expr          = <expression> [ '|' <cond-expr> ]
465  */
466 rc_t cond_expr ( KSymTable *tbl, KTokenSource *src, KToken *t,
467     const SchemaEnv *env, VSchema *self, struct SExpression const **expr );
468 
469 /*
470  * expression         = <param-value>
471  *                    | <func-expr>
472  *                    | '(' <func-fmtdecl> ')' <expression>
473  */
474 rc_t expression ( KSymTable *tbl, KTokenSource *src, KToken *t,
475     const SchemaEnv *env, VSchema *self, struct SExpression const **expr );
476 
477 /*
478  * type-expr          = <typeset>
479  *                    | <fmtdecl>
480  *                    | <fmtname> '/' <typeset>
481  */
482 rc_t type_expr ( const KSymTable *tbl, KTokenSource *src, KToken *t,
483     const SchemaEnv *env, const VSchema *self, struct SExpression const **fd );
484 rc_t vardim_type_expr ( const KSymTable *tbl, KTokenSource *src, KToken *t,
485     const SchemaEnv *env, const VSchema *self, struct SExpression const **fd );
486 
487 /*
488  * const-expr         = <constname>
489  *                    | CONST-VALUE
490  */
491 rc_t const_expr ( const KSymTable *tbl, KTokenSource *src, KToken *t,
492     const SchemaEnv *env, const VSchema *self, struct SExpression const **expr );
493 
494 /*
495  * phys-encoding-expr = [ '<' <schema-parms> '>' ]
496  *                      <phys-encoding-name> [ '#' <maj-min-rel> ]
497  *                      [ '<' <fact-params> '>' ]
498  */
499 rc_t phys_encoding_expr ( KSymTable *tbl, KTokenSource *src, KToken *t,
500     const SchemaEnv *env, VSchema *self, VTypedecl *td, struct SExpression const **expr );
501 
502 
503 /*--------------------------------------------------------------------------
504  * schema-eval.c
505  */
506 
507 /* eval-const-expr
508  *  tries to evaluate a constant expression against type
509  *  returns non-zero error code if failed
510  */
511 rc_t eval_const_expr ( const VSchema *self, const VTypedecl *td,
512     struct SExpression const *expr, struct SExpression **value, Vector *cx_bind );
513 
514 /* eval-uint-expr
515  *  special const expression evaluator for uint32_t
516  */
517 rc_t eval_uint_expr ( const VSchema *self,
518     struct SExpression const *expr, uint32_t *value, Vector *cx_bind );
519 
520 /* eval-uint64-expr
521  *  special const expression evaluator for uint64_t
522  */
523 rc_t eval_uint64_expr ( const VSchema *self,
524     struct SExpression const *expr, uint64_t *value, Vector *cx_bind );
525 
526 /* eval-expr-syntax
527  *  examine expression syntax
528  *  fixes forward references
529  */
530 rc_t eval_expr_syntax ( struct SExpression const *expr );
531 
532 
533 /*--------------------------------------------------------------------------
534  * schema-tbl.c
535  */
536 
537 /*
538  * physical-name      = '.' ID
539  */
540 void physical_name ( const KSymTable *tbl,
541     KTokenSource *src, KToken *t, const SchemaEnv *env );
542 
543 /*
544  * push-tbl-scope
545  * pop-tbl-scope
546  */
547 rc_t push_tbl_scope ( KSymTable *tbl, struct STable const *table );
548 void pop_tbl_scope ( KSymTable *tbl, struct STable const *table );
549 
550 /*
551  * init-tbl-symtab
552  *  initializes "tbl"
553  *  places table in scope
554  *  must be balanced by KSymTableWhack
555  */
556 rc_t init_tbl_symtab ( KSymTable *tbl, const VSchema *schema, struct STable const *table );
557 
558 /*
559  * table-decl         = 'table' <fqn> <table-def>
560  * table-def          = [ <table-dad> ] <table-body>
561  *                    | <table-dad> ';'
562  *
563  * table-dad          = '=' <table-name>
564  *
565  * table-body         = '{' [ <table-decl-list> ] '}'
566  * table-decl-list    = <tbl-local-decl> ';' [ <table-decl-list> ]
567  */
568 rc_t table_declaration ( KSymTable *tbl, KTokenSource *src, KToken *t,
569     const SchemaEnv *env, VSchema *self );
570 
571 
572 /*--------------------------------------------------------------------------
573  * schema-db.c
574  */
575 
576 /*
577  * push-db-scope
578  * pop-db-scope
579  */
580 rc_t push_db_scope ( KSymTable *tbl, struct SDatabase const *db );
581 void pop_db_scope ( KSymTable *tbl, struct SDatabase const *db );
582 
583 /*
584  * init-db-symtab
585  *  initializes "tbl"
586  *  places db in scope
587  *  must be balanced by KSymTableWhack
588  */
589 rc_t init_db_symtab ( KSymTable *tbl, const VSchema *schema, struct SDatabase const *db );
590 
591 /*
592  * database-decl      = 'database' <fqn> <database-def>
593  * database-def       = [ <database-dad> ] <database-body>
594  *                    | <database-dad> ';'
595  *
596  * database-dad       = '=' <database-name>
597  *
598  * database-body      = '{' [ <db-decl-list> ] '}'
599  * db-decl-list       = <database-decl>
600  *                    | <table-decl>
601  */
602 rc_t database_declaration ( KSymTable *tbl, KTokenSource *src, KToken *t,
603     const SchemaEnv *env, VSchema *self );
604 
605 
606 #ifdef __cplusplus
607 }
608 #endif
609 
610 #endif /* _h_schema_int_ */
611