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 %{
28     #define YYDEBUG 1
29 
30     #include <stdio.h>
31 
32     #include "ASTBuilder.hpp"
33     using namespace ncbi::SchemaParser;
34 
35     #include "schema-ast-tokens.h"
36 
37     #define AST_lex NextToken
NextToken(YYSTYPE * p_token,ParseTreeScanner & p_sb)38     static int NextToken ( YYSTYPE * p_token, ParseTreeScanner & p_sb )
39     {
40         return p_sb . NextToken ( p_token -> tok );
41     }
42 
AST_error(void * p_parser,ASTBuilder & p_builder,ParseTreeScanner & p_sb,const char * p_msg)43     void AST_error ( void * p_parser, ASTBuilder & p_builder, ParseTreeScanner & p_sb, const char * p_msg )
44     {
45         p_builder . ReportInternalError ( p_msg, p_sb . GetSourceFileName () );
46     }
47 
48 %}
49 
50 %name-prefix "AST_"
51 %parse-param { AST*& p_ast }
52 %parse-param { ASTBuilder& p_builder }
53 %param { ParseTreeScanner& p_sb }
54 
55  /*%define api.value.type { const Token* }*/
56 
57 %union {
58   const Token*  tok;
59   AST*          node;
60   AST_FQN*      fqn;
61   AST_Expr*     expr;
62 }
63 
64 %define parse.error verbose
65 
66 %define api.pure full
67 
68  /* !!! Keep token declarations in synch with schema-grammar.y */
69 
70 %token END_SOURCE 0 "end of source"
71 
72 %token UNRECOGNIZED
73 
74 %token ELLIPSIS
75 %token INCREMENT
76 
77 %token DECIMAL
78 %token OCTAL
79 %token HEX
80 %token FLOAT_
81 %token EXP_FLOAT
82 %token STRING
83 %token ESCAPED_STRING
84 
85 %token IDENTIFIER_1_0
86 %token PHYSICAL_IDENTIFIER_1_0
87 %token VERSION
88 
89 /* unterminated strings are dealt with by flex */
90 %token UNTERM_STRING
91 %token UNTERM_ESCAPED_STRING
92 
93 /* version numbers recognized under special flex state */
94 %token VERS_1_0
95 %token VERS_2_0
96 
97 %token KW___no_header
98 %token KW___row_length
99 %token KW___untyped
100 %token KW_alias
101 %token KW_column
102 %token KW_const
103 %token KW_control
104 %token KW_database
105 %token KW_decode
106 %token KW_default
107 %token KW_encode
108 %token KW_extern
109 %token KW_false
110 %token KW_fmtdef
111 %token KW_function
112 %token KW_include
113 %token KW_limit
114 %token KW_physical
115 %token KW_read
116 %token KW_readonly
117 %token KW_return
118 %token KW_schema
119 %token KW_static
120 %token KW_table
121 %token KW_template
122 %token KW_trigger
123 %token KW_true
124 %token KW_type
125 %token KW_typedef
126 %token KW_typeset
127 %token KW_validate
128 %token KW_version
129 %token KW_view
130 %token KW_virtual
131 %token KW_void
132 %token KW_write
133 
134     /* Parse tree nodes */
135 %token PT_ASTLIST
136 %token PT_PARSE
137 %token PT_SOURCE
138 %token PT_VERSION_1_0
139 %token PT_VERSION_2
140 %token PT_SCHEMA_1_0
141 %token PT_SCHEMA_2_0
142 %token PT_INCLUDE
143 %token PT_TYPEDEF
144 %token PT_FQN
145 %token PT_IDENT
146 %token PT_PHYSIDENT
147 %token PT_UINT
148 %token PT_TYPESET
149 %token PT_TYPESETDEF
150 %token PT_FORMAT
151 %token PT_CONST
152 %token PT_ALIAS
153 %token PT_EXTERN
154 %token PT_FUNCTION
155 %token PT_UNTYPED
156 %token PT_ROWLENGTH
157 %token PT_FUNCDECL
158 %token PT_EMPTY
159 %token PT_SCHEMASIG
160 %token PT_SCHEMAFORMAL
161 %token PT_RETURNTYPE
162 %token PT_FACTSIG
163 %token PT_FUNCSIG
164 %token PT_FUNCPARAMS
165 %token PT_FORMALPARAM
166 %token PT_ELLIPSIS
167 %token PT_FUNCPROLOGUE
168 %token PT_RETURN
169 %token PT_PRODSTMT
170 %token PT_PRODTRIGGER
171 %token PT_SCHEMA
172 %token PT_VALIDATE
173 %token PT_PHYSICAL
174 %token PT_PHYSPROLOGUE
175 %token PT_PHYSSTMT
176 %token PT_PHYSBODYSTMT
177 %token PT_TABLE
178 %token PT_TABLEPARENTS
179 %token PT_TABLEBODY
180 %token PT_FUNCEXPR
181 %token PT_FACTPARMS
182 %token PT_COLUMN
183 %token PT_COLUMNEXPR
184 %token PT_COLDECL
185 %token PT_TYPEDCOL
186 %token PT_COLSTMT
187 %token PT_DFLTVIEW
188 %token PT_PHYSMBR
189 %token PT_PHYSCOL
190 %token PT_PHYSCOLDEF
191 %token PT_COLSCHEMAPARMS
192 %token PT_COLSCHEMAPARAM
193 %token PT_COLUNTYPED
194 %token PT_DATABASE
195 %token PT_TYPEEXPR
196 %token PT_DBBODY
197 %token PT_DBDAD
198 %token PT_DBMEMBER
199 %token PT_TBLMEMBER
200 %token PT_NOHEADER
201 %token PT_CASTEXPR
202 %token PT_CONSTVECT
203 %token PT_NEGATE
204 %token PT_UNARYPLUS
205 %token PT_VERSNAME
206 %token PT_ARRAY
207 %token PT_PHYSENCREF
208 %token PT_TYPEDCOLEXPR
209 %token PT_VIEW
210 %token PT_VIEWPARAM
211 %token PT_VIEWPARENTS
212 %token PT_VIEWPARENT
213 %token PT_MEMBEREXPR
214 %token PT_JOINEXPR
215 
216  /* !!! Keep token declarations above in synch with schema-grammar.y */
217 
218 %start parse
219 
220 %type <node> source schema_1 schema_decls schema_decl schema_2 typedef new_type_names
221 %type <node> typeset typeset_spec typespec dim fmtdef const alias function func_decl
222 %type <node> schema_sig_opt return_type prologue formals_list
223 %type <node> schema_formals schema_formal type_expr formals formal
224 %type <node> script_stmts script_stmt extern_function script script_decl validate
225 %type <node> script_prologue physical phys_prologue phys_body phys_body_stmt
226 %type <node> phys_return_type table parents_opt tbl_body tbl_stmts tbl_stmt
227 %type <node> tbl_parents production column_decl col_modifiers_opt col_modifiers
228 %type <node> col_modifier col_decl col_ident col_body col_stmt typed_col
229 %type <node> factory_parms factory_parms_opt schema_parm schema_parms arrayspec
230 %type <node> phys_enc_ref col_body_opt database dbdad_opt dbbody db_members
231 %type <node> db_member template_opt include func_parms_opt expr_list schema_parts_opt
232 %type <node> physmbr_decl col_schema_parms_opt col_schema_parms
233 %type <node> col_schema_value col_schema_parm phys_coldef factory_parms_list
234 %type <node> vararg param_sig param_signature fact_sig
235 %type <node> view view_parms view_parm view_body_opt view_body view_member
236 %type <node> view_parents_opt view_parents view_parent view_parent_parms
237 
238 %type <fqn> fqn qualnames fqn_opt_vers ident fqn_vers
239 
240 %type <expr> expr cond_expr cond_chain uint_expr func_expr float_expr string_expr const_vect_expr
241 %type <expr> bool_expr negate_expr cast_expr member_expr join_expr
242 
243 %type <tok> END_SOURCE version_1 PT_VERSION_1_0 PT_VERSION_2 PT_SCHEMA_1_0 FLOAT_ version_2
244 %type <tok> PT_TYPEDEF PT_IDENT IDENTIFIER_1_0 DECIMAL PT_ASTLIST PT_ARRAY PT_TYPESET
245 %type <tok> PT_FORMAT PT_CONST PT_UINT PT_ALIAS PT_EMPTY PT_ELLIPSIS KW_return
246 %type <tok> VERSION PT_UNTYPED PT_ROWLENGTH PT_FUNCDECL PT_FUNCPARAMS PT_FORMALPARAM
247 %type <tok> PT_VALIDATE PT_PHYSICAL PT_PHYSSTMT PT_TABLE PT_COLUMN PT_COLUMNEXPR
248 %type <tok> KW_default KW_extern KW_readonly PHYSICAL_IDENTIFIER_1_0 HEX OCTAL PT_COLSTMT
249 %type <tok> KW_read KW_validate KW_limit PT_SCHEMAFORMAL PT_PRODSTMT PT_PRODTRIGGER
250 %type <tok> PT_NOHEADER KW_decode KW_encode KW___row_length PT_COLDECL PT_TYPEDCOL PT_TYPEEXPR
251 %type <tok> PT_PHYSENCREF KW_column PT_TYPEDCOLEXPR PT_DATABASE PT_DBBODY
252 %type <tok> KW_template KW_database PT_DBMEMBER PT_TBLMEMBER KW_include STRING
253 %type <tok> PT_FUNCEXPR PT_COLSCHEMAPARMS KW_static PT_PHYSMBR PT_PHYSCOLDEF PT_COLSCHEMAPARAM
254 %type <tok> KW_physical PT_COLUNTYPED EXP_FLOAT ESCAPED_STRING PT_CONSTVECT KW_true KW_false
255 %type <tok> PT_NEGATE PT_CASTEXPR '@' KW_control PT_SCHEMA_2_0
256 %type <tok> PT_VIEW PT_VIEWPARAM PT_VIEWPARENTS PT_MEMBEREXPR PT_VIEWPARENT PT_JOINEXPR
257 
258 %%
259 
260 parse
261     : PT_PARSE '(' END_SOURCE ')'                   { p_ast = new AST ( $3 ); }
262     | PT_PARSE '(' source END_SOURCE ')'            { p_ast = $3; }
263     ;
264 
265 source
266     : PT_SOURCE '(' schema_1 ')'                    { $$ = $3; }
267     | PT_SOURCE '(' version_1 schema_1 ')'          { $$ = $4; $$ -> AddNode ( $3 ); }
268     | PT_SOURCE '(' version_2 schema_2 ')'          { $$ = $4; $$ -> AddNode ( $3 ); }
269     ;
270 
271 version_1
272     : PT_VERSION_1_0 '(' KW_version VERS_1_0 ';' ')'    { $$ = $1; }
273     ;
274 
275 version_2
276     : PT_VERSION_2 '(' KW_version VERS_2_0 ';' ')'     { $$ = $1; }
277     ;
278 
279 schema_1
280     : PT_SCHEMA_1_0 '(' schema_decls ')'            { $$ = new AST ( $1, $3 ); }
281     ;
282 
283  schema_2
284     : PT_SCHEMA_2_0 '(' schema_decls ')'            { $$ = new AST ( $1, $3 ); }
285     ;
286 
287 
288 schema_decls
289     : schema_decl                                   { $$ = new AST (); $$ -> AddNode ( $1 ); }
290     | schema_decls schema_decl                      { $$ = $1; $$ -> AddNode ( $2 ); }
291     ;
292 
293 /* declarations */
294 
295 schema_decl
296     : typedef           { $$ = $1; }
297     | typeset           { $$ = $1; }
298     | fmtdef            { $$ = $1; }
299     | const             { $$ = $1; }
300     | alias             { $$ = $1; }
301     | function          { $$ = $1; }
302     | extern_function   { $$ = $1; }
303     | script            { $$ = $1; }
304     | validate          { $$ = $1; }
305     | physical          { $$ = $1; }
306     | table             { $$ = $1; }
307     | database          { $$ = $1; }
308     | include           { $$ = $1; }
309     | view              { $$ = $1; }
310     | ';'               { $$ = new AST (); }
311     ;
312 
313 typedef
314     : PT_TYPEDEF '(' KW_typedef fqn PT_ASTLIST '(' new_type_names ')' ';' ')'
315                                             { $$ = p_builder . TypeDef ( $1, $4, $7 ); }
316     ;
317 
318 new_type_names
319     : typespec                         { $$ = new AST (); $$ -> AddNode ( $1 ); }
320     | new_type_names ',' typespec      { $$ = $1; $$ -> AddNode ( $3 ); }
321     ;
322 
323 typespec
324     : fqn       { $$ = $1; }
325     | arrayspec { $$ = $1; }
326     ;
327 
328 arrayspec
329     : PT_ARRAY '(' fqn '[' dim ']' ')'  { $$ = new AST ( $1, $3, $5 ); }
330     ;
331 
332 dim
333     : expr   { $$ = $1; }
334     | '*'    { $$ = new AST ( PT_EMPTY ); }
335     ;
336 
337 typeset
338     :  PT_TYPESET '(' KW_typeset fqn PT_TYPESETDEF '(' '{' PT_ASTLIST '(' typeset_spec ')' '}' ')' ';' ')'
339                 { $$ = p_builder . TypeSet ( $1, $4, $10 ); }
340     ;
341 
342 typeset_spec
343     : typespec                      { $$ = new AST (); $$ -> AddNode ( $1 ); }
344     | typeset_spec ',' typespec     { $$ = $1; $$ -> AddNode ( $3 ); }
345     ;
346 
347 fmtdef
348     : PT_FORMAT '(' KW_fmtdef fqn ';' ')'       { $$ = p_builder . FmtDef ( $1, $4, 0 ); }
349     | PT_FORMAT '(' KW_fmtdef fqn fqn ';' ')'   { $$ = p_builder . FmtDef ( $1, $5, $4 ); } /* note the flipped order */
350     ;
351 
352 const
353     : PT_CONST '(' KW_const typespec fqn '=' expr ';' ')'        { $$ = p_builder . ConstDef ( $1, $4, $5, $7 ); }
354     ;
355 
356 alias
357     : PT_ALIAS '(' KW_alias fqn fqn ';' ')'  { $$ = p_builder . AliasDef ( $1, $4, $5 ); }
358     ;
359 
360 function
361     : PT_FUNCTION '(' KW_function func_decl ')' { $$ = $4; }
362     ;
363 
364 func_decl
365     : PT_UNTYPED '(' KW___untyped fqn '(' ')' ')'      { $$ = p_builder . UntypedFunctionDecl ( $1, $4 ); }
366     | PT_ROWLENGTH '(' KW___row_length fqn '(' ')' ')' { $$ = p_builder . RowlenFunctionDecl ( $1, $4 ); }
367     | PT_FUNCDECL '(' schema_sig_opt return_type fqn_opt_vers fact_sig param_sig prologue ')'
368                 { $$ = p_builder . FunctionDecl ( $1, false, $3, $4, $5, $6, $7, $8 ); }
369     ;
370 
371 schema_sig_opt
372     : PT_EMPTY                                                          { $$ = new AST ( $1 ); }
373     | PT_SCHEMASIG '(' '<' PT_ASTLIST '(' schema_formals ')' '>' ')'    { $$ = $6; }
374     ;
375 
376 schema_formals
377     : schema_formal                     { $$ = new AST (); $$ -> AddNode ( $1 ); }
378     | schema_formals ',' schema_formal  { $$ = $1; $$ -> AddNode ( $3 ); }
379     ;
380 
381 schema_formal
382     : PT_SCHEMAFORMAL '(' KW_type ident ')'     { $$ = new AST ( $1, $4 ); }
383     | PT_SCHEMAFORMAL '(' type_expr ident ')'   { $$ = new AST ( $1, $3, $4 ); }
384     ;
385 
386 return_type
387     : PT_RETURNTYPE '(' KW_void ')'     { $$ = new AST (); }
388     | PT_RETURNTYPE '(' type_expr ')'   { $$ = $3; }
389     ;
390 
391 fact_sig
392     : PT_EMPTY                                   { $$ = new AST ( $1 ); }
393     | PT_FACTSIG '(' '<' param_signature '>' ')' { $$ = $4; }
394     ;
395 
396 param_sig
397     :  PT_FUNCSIG '(' '(' param_signature ')' ')' { $$ = $4; }
398     ;
399 
400 param_signature
401     : PT_EMPTY                                                          { $$ = new AST ( $1 ); }
402     | PT_FUNCPARAMS '(' formals_list vararg ')'                         { $$ = new AST ( $1, $3, new AST (), $4 ); }
403     | PT_FUNCPARAMS '(' '*' formals_list vararg ')'                     { $$ = new AST ( $1, new AST (), $4, $5 ); }
404     | PT_FUNCPARAMS '(' formals_list '*' formals_list vararg ')'        { $$ = new AST ( $1, $3, $5, $6 ); }
405     | PT_FUNCPARAMS '(' formals_list ',' '*' formals_list vararg ')'    { $$ = new AST ( $1, $3, $6, $7 ); }
406     ;
407 
408 formals_list
409     : PT_ASTLIST '(' formals ')'    { $$ = $3; }
410     ;
411 
412 formals
413     : formal                { $$ = new AST (); $$ -> AddNode ( $1 ); }
414     | formals ',' formal    { $$ = $1; $$ -> AddNode ( $3 ); }
415     ;
416 
417 formal
418     : PT_FORMALPARAM '(' typespec IDENTIFIER_1_0 ')'            { $$ = new AST ( $1, $3, new AST ( $4 ), new AST () ); }
419     | PT_FORMALPARAM '(' KW_control typespec IDENTIFIER_1_0 ')' { $$ = new AST ( $1, $4, new AST ( $5 ), new AST ( $3 ) ); }
420     ;
421 
422 vararg
423     : PT_EMPTY                          { $$ = new AST ( $1 ); }
424     | PT_ELLIPSIS '(' ',' ELLIPSIS ')'  { $$ = new AST ( $1 ); }
425     ;
426 
427 prologue
428     : PT_FUNCPROLOGUE '(' ';' ')'           { $$ = new AST ( PT_EMPTY ); }
429     | PT_FUNCPROLOGUE '(' '=' fqn ';' ')'   { $$ = $4; }
430     | script_prologue
431     ;
432 
433 script_prologue
434     : PT_FUNCPROLOGUE '(' '{' PT_ASTLIST '(' script_stmts ')' '}' ')'   { $$ = $6; }
435     ;
436 
437 script_stmts
438     : script_stmt               { $$ = new AST (); $$ -> AddNode ( $1 ); }
439     | script_stmts script_stmt  { $$ = $1; $$ -> AddNode ( $2 ); }
440     ;
441 
442 script_stmt
443     : PT_RETURN '(' KW_return cond_expr ';' ')'     { $$ = new AST ( $3, $4 ); }
444     | production                                    { $$ = $1; }
445     ;
446 
447 production
448     : PT_PRODSTMT '(' type_expr ident '=' cond_expr ';' ')'        { $$ = new AST ( $1, $3, $4, $6 ); }
449     | PT_PRODTRIGGER '(' KW_trigger ident '=' cond_expr ';' ')'    { $$ = new AST ( $1, $4, $6 ); }
450     ;
451 
452 extern_function
453     : PT_EXTERN '(' KW_extern function ')'    { $$ = $4; }
454 
455 script
456     : PT_SCHEMA '(' KW_schema script_decl ')'             { $$ = $4; }
457     | PT_SCHEMA '(' KW_schema KW_function script_decl ')' { $$ = $5; }
458     ;
459 
460 script_decl
461     : PT_FUNCDECL '(' schema_sig_opt return_type fqn_opt_vers fact_sig param_sig script_prologue ')'
462                 { $$ = p_builder . FunctionDecl ( $1, true, $3, $4, $5, $6, $7, $8 ); }
463     ;
464 
465 validate
466     : PT_VALIDATE '(' KW_validate
467         PT_FUNCTION '(' KW_function
468             PT_FUNCDECL '(' schema_sig_opt return_type fqn_opt_vers fact_sig param_sig prologue ')'
469         ')'
470       ')'
471         { $$ = p_builder . FunctionDecl ( $1, false, $9, $10, $11, $12, $13, $14 ); }
472     ;
473 
474 physical
475     : PT_PHYSICAL '(' KW_physical schema_sig_opt phys_return_type fqn_vers fact_sig phys_prologue ')'
476             { $$ = p_builder . PhysicalDecl ( $1, $4, $5, $6, $7, $8 ); }
477     ;
478 
479 phys_return_type
480     : return_type                                       { $$ = $1; }
481     | PT_NOHEADER '(' KW___no_header return_type ')'    { $$ = new AST ( $1, $4 ); }
482 
483 phys_prologue
484     : PT_PHYSPROLOGUE '(' '=' PT_PHYSSTMT '(' '{' PT_ASTLIST '(' script_stmts ')' '}' ')' ')'
485                 { $$ = new AST ( $4, $9 ); }
486     | PT_PHYSPROLOGUE '(' '{' PT_ASTLIST '(' phys_body ')' '}' ')'
487                 { $$ = $6; }
488     ;
489 
490 phys_body
491     : phys_body_stmt            { $$ = new AST (); $$ -> AddNode ( $1 ); }
492     | phys_body phys_body_stmt  { $$ = $1; $$ -> AddNode ( $2 ); }
493     ;
494 
495 phys_body_stmt
496     : PT_PHYSBODYSTMT '(' ';' ')'
497         { $$ = new AST ( PT_EMPTY ); }
498     | PT_PHYSBODYSTMT '(' KW_decode PT_PHYSSTMT '(' '{' PT_ASTLIST '(' script_stmts ')' '}' ')' ')'
499         { $$ = new AST ( $3, $9 ) ; }
500     | PT_PHYSBODYSTMT '(' KW_encode PT_PHYSSTMT '(' '{' PT_ASTLIST '(' script_stmts ')' '}' ')' ')'
501         { $$ = new AST ( $3, $9 ); }
502     | PT_PHYSBODYSTMT '(' KW___row_length '=' fqn '(' ')' ')'
503         { $$ = new AST ( $3, $5 ); }
504     ;
505 
506 /* tables */
507 
508 table
509     : PT_TABLE '(' KW_table fqn_vers parents_opt PT_TABLEBODY '(' '{' tbl_body '}' ')' ')'
510                 { $$ = p_builder . TableDef ( $1, $4, $5, $9 ); }
511     ;
512 
513 parents_opt
514     : PT_EMPTY                                                      { $$ = new AST ( $1 ); }
515     | PT_TABLEPARENTS '(' '=' PT_ASTLIST '(' tbl_parents ')' ')'    { $$ = $6; }
516     ;
517 
518 tbl_parents
519     : fqn_opt_vers                  { $$ = new AST (); $$ -> AddNode ( $1 ); }
520     | tbl_parents ',' fqn_opt_vers  { $$ = $1; $$ -> AddNode ( $3 ); }
521     ;
522 
523 tbl_body
524     : %empty                        { $$ = new AST ( PT_EMPTY ); }
525     | PT_ASTLIST '(' tbl_stmts ')'  { $$ = $3; }
526     ;
527 
528 tbl_stmts
529     : tbl_stmt              { $$ = new AST (); $$ -> AddNode ( $1 ); }
530     | tbl_stmts tbl_stmt    { $$ = $1; $$ -> AddNode ( $2 ); }
531     ;
532 
533 tbl_stmt
534     : production                                                        { $$ = $1; }
535     | column_decl                                                       { $$ = $1; }
536     | PT_COLUMNEXPR '(' KW_column KW_limit '=' expr ';' ')'             { $$ = new AST ( $1, $6 ); }
537     | PT_COLUMNEXPR '(' KW_column KW_default KW_limit '=' expr ';' ')'  { $$ = new AST ( $1, $7 ); }
538     | PT_PHYSCOL '(' KW_static physmbr_decl ')'                         { $$ = new AST ( $3, $4 ); }
539     | PT_PHYSCOL '(' KW_physical physmbr_decl ')'                       { $$ = new AST ( $3, $4 ); }
540     | PT_PHYSCOL '(' KW_static KW_physical physmbr_decl ')'             { $$ = new AST ( $3, $5 ); }
541     | PT_COLUNTYPED '(' KW___untyped '=' fqn '(' ')' ';' ')'            { $$ = new AST ( $1, $5 ); }
542     | ';'                                                               { $$ = new AST (); }
543 ;
544 
545 column_decl
546     : PT_COLUMN '(' col_modifiers_opt col_decl ')' { $$ = new AST ( $1, $3, $4 ); }
547     ;
548 
549 col_modifiers_opt
550     : KW_column                                     { $$ = new AST ( $1 ); }
551     | PT_ASTLIST '(' col_modifiers KW_column ')'    { $$ = $3; }
552     ;
553 
554 col_modifiers
555     : col_modifier                  { $$ = new AST (); $$ -> AddNode ( $1 ); }
556     | col_modifiers col_modifier    { $$ = $1; $$ -> AddNode ( $2 ); }
557     ;
558 
559 col_modifier
560     : KW_default    { $$ = new AST ( $1 ); }
561     | KW_extern     { $$ = new AST ( $1 ); }
562     | KW_readonly   { $$ = new AST ( $1 ); }
563     ;
564 
565 col_decl
566     : PT_COLDECL '(' typespec typed_col ')'     { $$ = new AST ( $1, $3, $4 ); }
567     | PT_COLDECL '(' phys_enc_ref typed_col ')' { $$ = new AST ( $1, $3, $4 ); }
568     ;
569 
570 phys_enc_ref
571     : PT_PHYSENCREF '(' '<' PT_ASTLIST '(' schema_parms ')' '>' fqn_opt_vers factory_parms_opt ')'
572                                                         { $$ = new AST ( $1, $6, $9, $10 ); }
573     | PT_PHYSENCREF '(' fqn_vers factory_parms_opt ')'  { $$ = new AST ( $1, $3, $4 ); }
574     | PT_PHYSENCREF '(' fqn factory_parms_list ')'      { $$ = new AST ( $1, $3, $4 ); }
575     ;
576 
577 typed_col
578     : PT_TYPEDCOL '(' col_ident '{' col_body_opt '}' ')'    {  $$ = new AST ( $1, $3, $5 ); }
579     | PT_TYPEDCOLEXPR '(' col_ident '=' cond_expr ';' ')'   {  $$ = new AST ( $1, $3, $5 ); }
580     | PT_TYPEDCOL '(' col_ident ';' ')'                     {  $$ = new AST ( $1, $3 ); }
581     ;
582 
583 col_ident
584     : ident                     { $$ = $1; }
585     | PHYSICAL_IDENTIFIER_1_0   { $$ = new AST ( $1 ); }
586     ;
587 
588 col_body_opt
589     : PT_EMPTY                      { $$ = new AST (); }
590     | PT_ASTLIST '(' col_body ')'   { $$ = $3; }
591     ;
592 
593 col_body
594     : col_stmt          { $$ = new AST (); $$ -> AddNode ( $1 ); }
595     | col_body col_stmt { $$ = $1; $$ -> AddNode ( $2 ); }
596     ;
597 
598 col_stmt
599     : ';'                                               { $$ = new AST (); }
600     | PT_COLSTMT '(' KW_read '=' cond_expr ';' ')'      { $$ = new AST ( $1, new AST ( $3 ), $5 ); }
601     | PT_COLSTMT '(' KW_validate '=' cond_expr ';' ')'  { $$ = new AST ( $1, new AST ( $3 ), $5 ); }
602     | PT_COLSTMT '(' KW_limit '=' uint_expr ';' ')'     { $$ = new AST ( $1, new AST ( $3 ), $5 ); }
603     ;
604 
605 physmbr_decl
606     : PT_PHYSMBR '(' phys_coldef PHYSICAL_IDENTIFIER_1_0 ';' ')'
607                                                 { $$ = new AST ( $1, $3, new AST ( $4 ) ); }
608     | PT_PHYSMBR '(' KW_column phys_coldef PHYSICAL_IDENTIFIER_1_0 ';' ')'
609                                                 { $$ = new AST ( $1, $4, new AST ( $5 ) ); }
610     | PT_PHYSMBR '(' phys_coldef PHYSICAL_IDENTIFIER_1_0 '=' cond_expr ';' ')'
611                                                 { $$ = new AST ( $1, $3, new AST ( $4 ), $6 ); }
612     | PT_PHYSMBR '(' KW_column phys_coldef PHYSICAL_IDENTIFIER_1_0 '=' cond_expr ';' ')'
613                                                 { $$ = new AST ( $1, $4, new AST ( $5 ), $7 ); }
614     ;
615 
616 phys_coldef
617     : PT_PHYSCOLDEF '(' col_schema_parms_opt fqn_opt_vers factory_parms_opt ')'    { $$ = new AST ( $1, $3, $4, $5 ); }
618     ;
619 
620 col_schema_parms_opt
621     : PT_EMPTY                                                              { $$ = new AST (); }
622     | PT_COLSCHEMAPARMS '(' '<' PT_ASTLIST '(' col_schema_parms ')' '>' ')' { $$ = $6; }
623     ;
624 
625 col_schema_parms
626     : col_schema_parm                   { $$ = new AST (); $$ -> AddNode ( $1 ); }
627     | col_schema_parms col_schema_parm  { $$ = $1; $$ -> AddNode ( $2 ); }
628     ;
629 
630 col_schema_parm
631     : PT_COLSCHEMAPARAM '(' fqn '=' col_schema_value ')'    { $$ = new AST ( $1, $3, $5 ); }
632     | col_schema_value                                      { $$ = $1; }
633     ;
634 
635 col_schema_value
636     : fqn       { $$ = $1; }
637     | uint_expr { $$ = $1; }
638     ;
639 
640 /* database */
641 database
642     : PT_DATABASE '(' KW_database fqn_vers dbdad_opt dbbody ')' { $$ = p_builder . DatabaseDef ( $1, $4, $5, $6 ); }
643     ;
644 
645 dbdad_opt
646     : PT_EMPTY                             { $$ = new AST ( $1 ); }
647     | PT_DBDAD '(' '=' fqn_opt_vers ')'    { $$ = $4; }
648 
649 dbbody
650     : PT_DBBODY '(' '{' PT_ASTLIST '(' db_members ')' '}' ')'   { $$ = $6; }
651     | PT_DBBODY '(' '{' '}' ')'                                 { $$ = new AST ( $1 ); }
652     ;
653 
654 db_members
655     : db_member               { $$ = new AST (); $$ -> AddNode ( $1 ); }
656     | ';'                       { $$ = new AST (); }
657     | db_members db_member    { $$ = $1; $$ -> AddNode ( $2 ); }
658     | db_members ';'            { $$ = $1; }
659     ;
660 
661 db_member
662     : PT_DBMEMBER '(' template_opt KW_database fqn_opt_vers ident ';' ')'
663         { $$ = new AST ( $1, $3, $5, $6 ); }
664     | PT_TBLMEMBER '(' template_opt KW_table fqn_opt_vers ident ';' ')'
665         { $$ = new AST ( $1, $3, $5, $6 ); }
666     ;
667 
668 template_opt
669     : PT_EMPTY      { $$ = new AST ( $1 ); }
670     | KW_template   { $$ = new AST ( $1 ); }
671     ;
672 
673 /* include */
674 
675 include
676     : PT_INCLUDE '(' KW_include STRING ')' { $$ = p_builder . Include ( $3, $4 ); }
677     ;
678 
679 /* expressions */
680 
681 cond_expr
682     : PT_ASTLIST '(' cond_chain ')' { $$ = $3; }
683     ;
684 
685 cond_chain
686     : expr                   { $$ = new AST_Expr ( $1 ); }
687     | cond_chain '|' expr    { $$ = $1; $$ -> AddNode ( $3 ); }
688     ;
689 
690 expr
691     : fqn                           { $$ = new AST_Expr ( $1 ); }
692     | PHYSICAL_IDENTIFIER_1_0       { $$ = new AST_Expr ( $1 ); }
693     | '@'                           { $$ = new AST_Expr ( $1 ); }
694     | func_expr                     { $$ = $1; }
695     | uint_expr                     { $$ = $1; }
696     | float_expr                    { $$ = $1; }
697     | string_expr                   { $$ = $1; }
698     | const_vect_expr               { $$ = $1; }
699     | bool_expr                     { $$ = $1; }
700     | negate_expr                   { $$ = $1; }
701     | PT_UNARYPLUS '(' '+' expr ')' { $$ = $4; }
702     | cast_expr                     { $$ = $1; }
703     | member_expr                   { $$ = $1; }
704     | join_expr                     { $$ = $1; }
705     ;
706 
707 func_expr
708     : PT_FUNCEXPR '(' schema_parts_opt fqn_opt_vers factory_parms_opt '(' func_parms_opt ')' ')'
709         { $$ = new AST_Expr ( $1 ); $$ -> AddNode ( $3 ); $$ -> AddNode ( $4 ); $$ -> AddNode ( $5 ); $$ -> AddNode ( $7 ); }
710     ;
711 
712 schema_parts_opt
713     : %empty                                    { $$ = new AST ( PT_EMPTY ); }
714     | '<' PT_ASTLIST '(' schema_parms ')' '>'   { $$ = $4; }
715 
716 schema_parms
717     : schema_parm                   { $$ = new AST (); $$ -> AddNode ( $1 ); }
718     | schema_parms ',' schema_parm  { $$ = $1; $$ -> AddNode ( $3 ); }
719     ;
720 
721 schema_parm
722     : fqn           { $$ = $1; }
723     | arrayspec     { $$ = $1; }
724     | uint_expr     { $$ = $1; }
725     ;
726 
727 factory_parms_opt
728     : PT_EMPTY              { $$ = new AST ( $1 ); }
729     | factory_parms_list    { $$ = $1; }
730     ;
731 
732 factory_parms_list
733     : PT_FACTPARMS '(' '<' PT_ASTLIST '(' factory_parms ')' '>' ')'     { $$ = $6; }
734     ;
735 
736 factory_parms
737     : expr                      { $$ = new AST (); $$ -> AddNode ( $1 ); }
738     | factory_parms ',' expr    { $$ = $1; $$ -> AddNode ( $3 ); }
739     ;
740 
741 func_parms_opt
742     : PT_EMPTY                      { $$ = new AST ( $1 ); }
743     | PT_ASTLIST '(' expr_list ')'  { $$ = $3; }
744     ;
745 
746 expr_list
747     : expr                  { $$ = new AST (); $$ -> AddNode ( $1 ); }
748     | expr_list ',' expr    { $$ = $1; $$ -> AddNode ( $3 ); }
749     ;
750 
751 uint_expr
752     : PT_UINT '(' DECIMAL ')'   { $$ = new AST_Expr ( $1 ); $$ -> AddNode ( $3 ); }
753     | PT_UINT '(' HEX ')'       { $$ = new AST_Expr ( $1 ); $$ -> AddNode ( $3 ); }
754     | PT_UINT '(' OCTAL ')'     { $$ = new AST_Expr ( $1 ); $$ -> AddNode ( $3 ); }
755     ;
756 
757 float_expr
758     : FLOAT_     { $$ = new AST_Expr ( $1 ); }
759     | EXP_FLOAT { $$ = new AST_Expr ( $1 ); }
760     ;
761 
762 string_expr
763     : STRING            { $$ = new AST_Expr ( $1 ); }
764     | ESCAPED_STRING    { $$ = new AST_Expr ( $1 ); }
765     ;
766 
767 const_vect_expr
768     : PT_CONSTVECT '(' '[' PT_ASTLIST '(' expr_list ')' ']' ')'     { $$ = new AST_Expr ( $1 ); $$ -> AddNode ( $6 ); }
769     ;
770 
771 bool_expr
772     : KW_true   { $$ = new AST_Expr ( $1 ); }
773     | KW_false  { $$ = new AST_Expr ( $1 ); }
774     ;
775 
776 negate_expr
777     : PT_NEGATE '(' '-' expr ')' { $$ = new AST_Expr ( $1 ); $$ -> AddNode ( $4 ); }
778 
779 cast_expr
780     : PT_CASTEXPR '(' '(' type_expr ')' expr  ')' { $$ = new AST_Expr ( $1 ); $$ -> AddNode ( $4 ); $$ -> AddNode ( $6 ); }
781     ;
782 
783 type_expr
784     : typespec                          { $$ = $1; }
785     | PT_TYPEEXPR '(' fqn '/' fqn ')'   { $$ = new AST ( $1, $3, $5 ); }
786     ;
787 
788 member_expr
789     : PT_MEMBEREXPR '(' ident '.' ident ')'                 { $$ = new AST_Expr ( $1 ); $$ -> AddNode ( $3 ); $$ -> AddNode ( $5 ); }
790     | PT_MEMBEREXPR '(' ident PHYSICAL_IDENTIFIER_1_0 ')'
791         {   /* remove leading '.'*/
792             $$ = new AST_Expr ( $1 );
793             $$ -> AddNode ( $3 );
794             AST * ident = new AST ( PT_IDENT );
795             Token t ( IDENTIFIER_1_0, $4 -> GetValue() + 1, $$ -> GetLocation() );
796             ident -> AddNode ( & t );
797             $$ -> AddNode ( ident );
798         }
799     ;
800 
801 join_expr
802     : PT_JOINEXPR '(' ident '[' cond_expr ']' '.' ident ')'
803         { $$ = new AST_Expr ( $1 ); $$ -> AddNode ( $3 ); $$ -> AddNode ( $5 ); $$ -> AddNode ( $8 ); }
804     ;
805 
806 /* commonly used productions */
807 
808 fqn
809     : PT_FQN '(' qualnames ')'  { $$ = $3; }
810     ;
811 
812 qualnames
813     : PT_IDENT '(' IDENTIFIER_1_0 ')'                   { $$ = new AST_FQN ( $1 ); $$ -> AddNode ( $3 ); }
814     | qualnames ':' PT_IDENT  '(' IDENTIFIER_1_0 ')'    { $$ = $1; $$ -> AddNode ( $5 ); }
815     ;
816 
817 ident
818     : PT_IDENT '(' IDENTIFIER_1_0 ')'   { $$ = new AST_FQN ( $1 ); $$ -> AddNode ( $3 ); }
819     ;
820 
821 fqn_opt_vers
822     : fqn       { $$ = $1; }
823     | fqn_vers  { $$ = $1; }
824     ;
825 
826 fqn_vers
827     : PT_VERSNAME '(' fqn VERSION ')'   { $$ = $3; $$ -> SetVersion ( $4 -> GetValue () ); }
828     ;
829 
830 /* view */
831 view
832     : PT_VIEW '(' KW_view fqn_vers '<' PT_ASTLIST '(' view_parms ')' '>'
833                         view_parents_opt '{' view_body_opt '}' ')'
834         { $$ = p_builder . ViewDef ( $1, $4, $8, $11, $13 ); }
835     ;
836 
837 view_parms
838     : view_parm                 { $$ = new AST (); $$ -> AddNode ( $1 ); }
839     | view_parms ',' view_parm  { $$ = $1; $$ -> AddNode ( $3 ); }
840     ;
841 
842 view_parm
843     : PT_VIEWPARAM '(' fqn_opt_vers ident ')'   { $$ = new AST ( $1, $3, $4 ); }
844     ;
845 
846 view_body_opt
847     : PT_EMPTY                      { $$ = new AST ( $1 ); }
848     | PT_ASTLIST '(' view_body ')'  { $$ = $3; }
849     ;
850 
851 view_body
852     : view_member           { $$ = new AST (); $$ -> AddNode ( $1 ); }
853     | view_body view_member { $$ = $1; $$ -> AddNode ( $2 ); }
854     ;
855 
856 view_member
857     : PT_PRODSTMT '(' typespec ident '=' cond_expr ';' ')'          { $$ = new AST ( $1, $3, $4, $6 ); }
858     | PT_COLUMN '(' KW_column typespec ident '=' cond_expr ';' ')'  { $$ = new AST ( $1, $4, $5, $7 ); }
859     | ';'                                                           { $$ = new AST ( PT_EMPTY ); }
860     ;
861 
862 view_parents_opt
863     : PT_EMPTY                                                      { $$ = new AST ( $1 ); }
864     | PT_VIEWPARENTS '(' '=' PT_ASTLIST '(' view_parents ')' ')'    { $$ = new AST ( $1, $6 ); }
865     ;
866 
867 view_parents
868     : view_parent                   { $$ = new AST (); $$ -> AddNode ( $1 ); }
869     | view_parents ',' view_parent  { $$ = $1; $$ -> AddNode ( $3 ); }
870     ;
871 
872 view_parent
873     : PT_VIEWPARENT '(' fqn_opt_vers '<' PT_ASTLIST '(' view_parent_parms ')' '>' ')'
874         { $$ = new AST ( $1, $3, $7 ); }
875     ;
876 
877 view_parent_parms
878     : ident                         { $$ = new AST (); $$ -> AddNode ( $1 ); }
879     | view_parent_parms ',' ident   { $$ = $1; $$ -> AddNode ( $3 ); }
880     ;
881