irods  4.2.8
About: iRODS (the integrated Rule Oriented Data System) is a distributed data-management system for creating data grids, digital libraries, persistent archives, and real-time data systems.
  Fossies Dox: irods-4.2.8.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

parser.cpp
Go to the documentation of this file.
1 /* For copyright information please refer to files in the COPYRIGHT directory
2  */
3 
4 #include <cstdlib>
5 #include "utils.hpp"
6 #include "parser.hpp"
7 #include "rules.hpp"
8 #include "functions.hpp"
9 #include "configuration.hpp"
10 #include "filesystem.hpp"
11 #include "rcMisc.h"
12 
14  {"-", 1, 10},
15  {"++", 2, 6},
16  {"+", 2, 6},
17  {"-", 2, 6},
18  {"*", 2, 7},
19  {"/", 2, 7},
20  {"&&", 2, 3},
21  {"%%", 2, 2},
22  {"||", 2, 2},
23  {"%", 2, 7},
24  {"<=", 2, 5},
25  {">=", 2, 5},
26  {"<", 2, 5},
27  {">", 2, 5},
28  {"==", 2, 4},
29  {"!=", 2, 4},
30  {"!", 1, 10},
31  {"like regex", 2, 4},
32  {"not like regex", 2, 4},
33  {"like", 2, 4},
34  {"not like", 2, 4},
35  {"^^", 2, 8},
36  {"^", 2, 8},
37  {".", 2, 8},
38  {"floor", 1, 10},
39  {"ceiling", 1, 10},
40  {"log", 1, 10},
41  {"exp", 1, 10},
42  {"abs", 1, 10},
43  {"=", 2, 1},
44  {"@@", 2, 20}
45 };
46 PARSER_FUNC_PROTO2( Term, int rulegen, int prec );
47 PARSER_FUNC_PROTO2( Actions, int rulegen, int backwardCompatible );
48 PARSER_FUNC_PROTO1( T, int rulegen );
49 PARSER_FUNC_PROTO1( Value, int rulegen );
50 PARSER_FUNC_PROTO1( StringExpression, Token *tk );
51 PARSER_FUNC_PROTO( PathExpression );
52 PARSER_FUNC_PROTO( RuleName );
53 PARSER_FUNC_PROTO( TermBackwardCompatible );
54 PARSER_FUNC_PROTO1( ExprBackwardCompatible, int level );
55 PARSER_FUNC_PROTO1( TermSystemBackwardCompatible, int lev );
56 PARSER_FUNC_PROTO( ActionArgumentBackwardCompatible );
57 PARSER_FUNC_PROTO( FuncExpr );
58 PARSER_FUNC_PROTO( Type );
59 PARSER_FUNC_PROTO2( _Type, int prec, int lifted );
60 PARSER_FUNC_PROTO( TypeSet );
61 PARSER_FUNC_PROTO( Column );
62 PARSER_FUNC_PROTO( QueryCond );
63 PARSER_FUNC_PROTO( FuncType );
64 PARSER_FUNC_PROTO( _FuncType );
65 PARSER_FUNC_PROTO( TypingConstraints );
66 PARSER_FUNC_PROTO( _TypingConstraints );
67 PARSER_FUNC_PROTO( Metadata );
68 
69 
71  ParserContext *pc = ( ParserContext * )malloc( sizeof( ParserContext ) );
72  pc->stackTopStackTop = 0;
73  pc->nodeStackTop = 0;
74  pc->error = 0;
75  pc->errloc.exprloc = -1;
76  pc->region = r;
77  pc->errmsg = errmsg;
78  pc->errnode = NULL;
79  pc->symtable = newHashTable2( 100, r );
80  pc->errmsgbuf[0] = '\0';
81  pc->tqp = pc->tqtop = pc->tqbot = 0;
82  return pc;
83 }
84 
86  free( t );
87 }
89  return
90  getNodeType( node ) == TK_VAR &&
91  node->text[0] == '*';
92 }
94  return
95  getNodeType( node ) == TK_VAR &&
96  node->text[0] == '$';
97 }
99  return
102 }
103 #define nKeywords 19
104 char *keywords[nKeywords] = { "in", "let", "match", "with", "for", "forExec", "while", "whileExec", "foreach", "forEachExec", "if", "ifExec", "then", "else", "data", "constructor", "on", "or", "oron"};
105 int isKeyword( char *text ) {
106  int i;
107  for ( i = 0; i < nKeywords; i++ ) {
108  if ( strcmp( keywords[i], text ) == 0 ) {
109  return 1;
110  }
111  }
112  return 0;
113 }
114 
115 void skipWhitespace( Pointer *expr ) {
116  int ch;
117  ch = lookAhead( expr, 0 );
118  while ( ch != -1 && ( ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n' ) ) {
119  ch = nextChar( expr );
120  }
121 }
123  int ch = lookAhead( e, 0 );
124  while ( ch != '\n' && ch != -1 ) {
125  ch = nextChar( e );
126  }
127 }
128 char *findLineCont( char *expr ) {
129  char *e = expr + strlen( expr );
130  while ( e != expr ) {
131  e--;
132  if ( *e == ' ' || *e == '\t' || *e == '\r' || *e == '\n' ) {
133  continue;
134  }
135  if ( *e == '\\' || *e == ',' || *e == ';' || *e == '|' || *e == '#' ) {
136  return e;
137  }
138  break;
139  }
140  return NULL;
141 }
142 
147 int skip( Pointer *e, char *text, Token **token, ParserContext *pc, int rulegen ) {
148  *token = nextTokenRuleGen( e, pc, rulegen, 0 );
149  if ( ( ( *token )->type != TK_TEXT && ( *token )->type != TK_OP && ( *token )->type != TK_MISC_OP ) || strcmp( ( *token )->text, text ) != 0 ) {
150  ( *token )->type = N_ERROR;
151  return 0;
152  }
153  return 1;
154 }
155 
156 /*void getRuleCode(char buf[MAX_RULE_LEN], Pointer *e, int rulegen, ParserContext *context) {
157 
158 }*/
159 
160 Token* nextTokenRuleGen( Pointer* e, ParserContext *context, int rulegen, int pathLiteral ) {
161  if ( context->tqp != context->tqtop ) {
162  Token *token = &( context->tokenQueue[context->tqp] );
163  INC_MOD( context->tqp, 1024 );
164  return token;
165  }
166 
167  Token* token = &( context->tokenQueue[context->tqp] );
168  INC_MOD( context->tqtop, 1024 );
169  if ( context->tqbot == context->tqtop ) {
170  INC_MOD( context->tqbot, 1024 );
171  }
172  context->tqp = context->tqtop;
173 
174  while ( 1 ) {
175  skipWhitespace( e );
176  Label start;
177  Label pos;
178  getFPos( &start, e, context );
179  token->exprloc = start.exprloc;
180  int ch = lookAhead( e, 0 );
181  if ( ch == -1 ) { /* reach the end of stream */
182  token->type = TK_EOS;
183  strcpy( token->text, "EOS" );
184  break;
185  }
186  else {
187  int i;
188  if ( ch == '{' || ch == '}' || ch == '[' || ch == ']' || ch == '(' || ch == ')' || ch == ',' || ch == '@' || ( ch == '|' && ( !rulegen || lookAhead( e, 1 ) != '|' ) ) || ch == ';' || ch == '?' ) {
189  *( token->text ) = ch;
190  ( token->text )[1] = '\0';
191  token->type = TK_MISC_OP;
192  nextChar( e );
193  break;
194  }
195  else if ( ch == '#' ) {
196  if ( !rulegen && lookAhead( e, 1 ) == '#' ) {
197  token->text[0] = ch;
198  token->text[1] = lookAhead( e, 1 );
199  token->text[2] = '\0';
200  token->type = TK_MISC_OP;
201  nextChar( e );
202  nextChar( e );
203  break;
204  }
205  else {
206  skipComments( e );
207  continue;
208  }
209  }
210  else if ( ch == '-' || ch == '=' ) {
211  if ( lookAhead( e, 1 ) == '>' ) {
212  token->text[0] = ch;
213  token->text[1] = '>';
214  token->text[2] = '\0';
215  token->type = TK_MISC_OP;
216  nextChar( e );
217  nextChar( e );
218  break;
219  }
220  }
221  else if ( ch == ':' ) {
222  if ( rulegen && lookAhead( e, 1 ) == ':'
223  && lookAhead( e, 2 ) == ':' ) {
224  token->text[0] = ch;
225  token->text[1] = lookAhead( e, 1 );
226  token->text[2] = lookAhead( e, 2 );
227  token->text[3] = '\0';
228  token->type = TK_MISC_OP;
229  nextChar( e );
230  nextChar( e );
231  }
232  else {
233  *( token->text ) = ch;
234  ( token->text )[1] = '\0';
235  token->type = TK_MISC_OP;
236  }
237  nextChar( e );
238  break;
239  }
240  else if ( ch == '*' || ch == '$' ) { /* variable */
241  token->type = ch == '*' ? TK_LOCAL_VAR : TK_SESSION_VAR;
242 
243  ch = nextChar( e );
244  if ( ch == '_' || isalpha( ch ) ) {
245  ch = nextChar( e );
246  while ( ch == '_' || isalnum( ch ) ) {
247  ch = nextChar( e );
248  }
249  FPOS;
250  dupString( e, &start, ( int )( pos.exprloc - start.exprloc ), token->text );
251  break;
252  }
253  else {
254  seekInFile( e, start.exprloc );
255  }
256  }
257  else if ( pathLiteral && ch == '/' ) { /* path */
258  nextStringBase( e, token->text,MAX_TOKEN_TEXT_LEN, "),; \t\r\n", 0, '\\', 0, token->vars ); /* path can be used in a foreach loop or assignment, or as a function argument */
259  token->type = TK_PATH;
260  break;
261  }
262 
263  char op[100];
264  dupString( e, &start, 10, op );
265  int found = 0;
266  for ( i = 0; i < num_ops; i++ ) {
267  int len = strlen( new_ops[i].string );
268  if ( strncmp( op, new_ops[i].string, len ) == 0 &&
269  ( !isalpha( new_ops[i].string[0] )
270  || !isalnum( op[len] ) ) ) {
271  strcpy( token->text, new_ops[i].string );
272  token->type = TK_OP;
273  nextChars( e, len );
274  found = 1;
275  break;
276  }
277  }
278  if ( found ) {
279  break;
280  }
281  if ( isdigit( ch ) || ch == '.' ) {
282  ch = nextChar( e );
283  while ( isdigit( ch ) || ch == '.' ) {
284  ch = nextChar( e );
285  }
286  FPOS;
287  dupString( e, &start, ( int )( pos.exprloc - start.exprloc ), token->text );
288  if ( strchr( token->text, '.' ) ) {
289  token->type = TK_DOUBLE;
290  }
291  else {
292  token->type = TK_INT;
293  }
294  }
295  else if ( ch == '_' || isalpha( ch ) || ch == '~' ) {
296  ch = nextChar( e );
297  while ( ch == '_' || isalnum( ch ) ) {
298  ch = nextChar( e );
299  }
300  FPOS;
301  dupString( e, &start, ( int )( pos.exprloc - start.exprloc ), token->text );
302  token->type = TK_TEXT;
303  }
304  else if ( ch == '\"' ) {
305  if ( nextString( e, token->text, token->vars ) == -1 ) {
306  token->type = N_ERROR;
307  }
308  else {
309  token->type = TK_STRING;
310  }
311  }
312  else if ( ch == '\'' ) {
313  if ( nextString2( e, token->text, token->vars ) == -1 ) {
314  token->type = N_ERROR;
315  }
316  else {
317  token->type = TK_STRING;
318  }
319  }
320  else if ( ch == '`' ) {
321  if ( lookAhead( e, 1 ) == '`' ) {
322  if ( nextStringBase2( e, token->text, MAX_TOKEN_TEXT_LEN, "``" ) == -1 ) {
323  token->type = N_ERROR;
324  }
325  else {
326  token->type = TK_STRING;
327  token->vars[0] = -1;
328  }
329  }
330  else {
331  if ( nextStringBase( e, token->text, MAX_TOKEN_TEXT_LEN, "`", 1, '\\', 1, token->vars ) == -1 ) {
332  token->type = N_ERROR;
333  }
334  else {
336  }
337  }
338  }
339  else {
340  token->type = N_ERROR;
341  }
342  break;
343  }
344  }
345  return token;
346 }
347 
348 void pushback( Token *token, ParserContext *context ) {
349  if ( token->type == TK_EOS ) {
350  return;
351  }
352  DEC_MOD( context->tqp, 1024 );
353 }
354 
355 void syncTokenQueue( Pointer *e, ParserContext *context ) {
356  if ( context->tqp == context->tqtop ) {
357  return;
358  }
359  Token *nextToken = &context->tokenQueue[context->tqp];
360  seekInFile( e, nextToken->exprloc );
361  context->tqtop = context->tqp;
362 }
363 
364 int eol( char ch ) {
365  return ch == '\n' || ch == '\r';
366 }
367 
373 PARSER_FUNC_BEGIN1( Rule, int backwardCompatible )
374 char *rk;
375 int rulegen = 0;
376 TRY( defType )
377 TTEXT( "data" );
378 NT( RuleName );
379 BUILD_NODE( N_DATA_DEF, "DATA", &start, 1, 1 );
380 int n = 0;
381 OPTIONAL_BEGIN( consDefs )
382 TTEXT( "=" );
383 OPTIONAL_BEGIN( semicolon )
384 TTEXT( "|" );
385 OPTIONAL_END( semicolon )
386 LOOP_BEGIN( cons )
387 Label cpos = *FPOS;
388 TTYPE( TK_TEXT );
389 BUILD_NODE( TK_TEXT, token->text, &pos, 0, 0 );
390 TTEXT( ":" );
391 NT( FuncType );
392 BUILD_NODE( N_CONSTRUCTOR_DEF, "CONSTR", &cpos, 2, 2 );
393 n++;
394 TRY( delim )
395 TTEXT( "|" );
396 OR( delim )
397 DONE( cons );
398 END_TRY( delim )
399 LOOP_END( cons )
400 OPTIONAL_END( consDefs )
401 OPTIONAL_BEGIN( semicolon )
402 TTEXT( ";" );
403 OPTIONAL_END( semicolon )
404 n = n + 1;
405 BUILD_NODE( N_RULE_PACK, "INDUCT", &start, n, n );
406 OR( defType )
407 TTEXT( "constructor" );
408 TTYPE( TK_TEXT );
409 BUILD_NODE( TK_TEXT, token->text, &pos, 0, 0 );
410 TTEXT( ":" )
411 NT( FuncType );
412 BUILD_NODE( N_CONSTRUCTOR_DEF, "CONSTR", &start, 2, 2 );
413 BUILD_NODE( N_RULE_PACK, "CONSTR", &start, 1, 1 );
414 OR( defType )
415 TTYPE( TK_TEXT );
416 BUILD_NODE( TK_TEXT, token->text, &pos, 0, 0 );
417 TTEXT( ":" );
418 NT( FuncType );
419 BUILD_NODE( N_EXTERN_DEF, "EXTERN", &start, 2, 2 );
420 BUILD_NODE( N_RULE_PACK, "EXTERN", &start, 1, 1 );
421 OR( defType )
422 NT( RuleName );
423 TRY( ruleType )
424 TTEXT( "{" );
425 rulegen = 1;
426 rk = "REL";
427 OR( ruleType )
428 TTEXT( "|" );
429 rulegen = 0;
430 rk = "REL";
431 OR( ruleType )
432 TTEXT( "=" );
433 rulegen = 1;
434 rk = "FUNC";
435 END_TRY( ruleType );
436 if ( strcmp( rk, "FUNC" ) == 0 ) {
437  BUILD_NODE( TK_BOOL, "true", FPOS, 0, 0 );
438  NT( FuncExpr );
439  NT( Metadata );
440  OPTIONAL_BEGIN( semicolon )
441  TTEXT( ";" );
442  OPTIONAL_END( semicolon )
443  BUILD_NODE( N_RULE, "RULE", &start, 5, 5 );
444  BUILD_NODE( N_RULE_PACK, rk, &start, 1, 1 );
445  /* } else if(PARSER_LAZY) {
446  char buf[MAX_RULE_LEN];
447  Label rcpos = *FPOS;
448  getRuleCode(buf, e, rulegen, context);
449  BUILD_NODE(N_RULE_CODE, buf, &rcpos, 0, 0);
450  BUILD_NODE(N_UNPARSED,"UNPARSED", &start,2, 2);
451  BUILD_NODE(N_RULE_PACK,rk, &start,1, 1); */
452 }
453 else if ( rulegen ) {
454  int numberOfRules = 0;
455  LOOP_BEGIN( rule )
456  TRY( rulePack )
457  TRY( rulePackCond )
458  TTEXT( "ON" );
459  OR( rulePackCond )
460  TTEXT( "on" );
461  OR( rulePackCond )
462  TTEXT( "ORON" );
463  OR( rulePackCond )
464  TTEXT( "oron" );
465  END_TRY( rulePackCond )
466  NT2( Term, 1, MIN_PREC );
467  TTEXT( "{" );
468  NT2( Actions, 1, 0 );
469  TTEXT( "}" );
470  NT( Metadata );
471  BUILD_NODE( N_RULE, "RULE", &start, 5, 4 );
472  SWAP;
473  numberOfRules++;
474  OR( rulePack )
475  TRY( rulePackUncond )
476  TTEXT( "OR" );
477  OR( rulePackUncond )
478  TTEXT( "or" );
479  END_TRY( rulePackUncond )
480  BUILD_NODE( TK_BOOL, "true", FPOS, 0, 0 );
481  TTEXT( "{" );
482  NT2( Actions, 1, 0 );
483  TTEXT( "}" );
484  NT( Metadata );
485  BUILD_NODE( N_RULE, "RULE", &start, 5, 4 );
486  SWAP;
487  numberOfRules++;
488  OR( rulePack )
489  ABORT( numberOfRules == 0 );
490  TTEXT( "}" );
491  DONE( rule );
492  OR( rulePack )
493  ABORT( numberOfRules != 0 );
494  BUILD_NODE( TK_BOOL, "true", FPOS, 0, 0 );
495  NT2( Actions, 1, 0 );
496  TTEXT( "}" );
497  NT( Metadata );
498  numberOfRules = 1;
499  BUILD_NODE( N_RULE, "RULE", &start, 5, 4 );
500  SWAP;
501  DONE( rule );
502  END_TRY( rulePack )
503  LOOP_END( rule )
504  ( void ) POP;
505  BUILD_NODE( N_RULE_PACK, rk, &start, numberOfRules, numberOfRules );
506 }
507 else {
508  Label pos = *FPOS;
509  TRY( ruleCond )
510  /* empty condition */
511  TTEXT( "|" );
512  BUILD_NODE( TK_BOOL, "true", FPOS, 0, 0 );
513  OR( ruleCond )
514  if ( backwardCompatible >= 0 ) {
515  NT1( ExprBackwardCompatible, 0 );
516  }
517  else {
518  NT2( Term, 0, MIN_PREC );
519  }
520  TTEXT( "|" );
521  BUILD_NODE( N_TUPLE, TUPLE, &pos, 1, 1 );
522  END_TRY( ruleCond )
523 
524 
525  NT2( Actions, 0, backwardCompatible >= 0 ? 1 : 0 );
526  TTEXT( "|" );
527  NT2( Actions, 0, backwardCompatible >= 0 ? 1 : 0 );
528  int n = 0;
529  Label metadataStart = *FPOS;
530  OPTIONAL_BEGIN( ruleId )
531  TTEXT( "|" );
532  TTYPE( TK_INT );
533  BUILD_NODE( TK_STRING, "id", &pos, 0, 0 );
534  BUILD_NODE( TK_STRING, token->text, &pos, 0, 0 );
535  BUILD_NODE( TK_STRING, "", &pos, 0, 0 );
536  BUILD_NODE( N_AVU, AVU, &pos, 3, 3 );
537  n++;
538  OPTIONAL_END( ruleId )
539  BUILD_NODE( N_META_DATA, META_DATA, &metadataStart, n, n );
540  BUILD_NODE( N_RULE, "RULE", &start, 5, 5 );
541  BUILD_NODE( N_RULE_PACK, rk, &start, 1, 1 );
542 }
543 /*OR(defType)
544  TTYPE(TK_LOCAL_VAR);
545  BUILD_NODE(TK_VAR, token->text, &pos, 0, 0);
546  TTEXT("=");
547  NT2(Term, 0, MIN_PREC);
548  BUILD_NODE(N_RULE_PACK, "GLOBAL", &start, 2, 2);*/
549 END_TRY( defType )
550 PARSER_FUNC_END( Rule )
551 
552 PARSER_FUNC_BEGIN( RuleName )
553 int rulegen = 0;
554 TTYPE( TK_TEXT );
555 char *ruleName = cpStringExt( token->text, context->region );
556 Label paramListStart = *FPOS;
557 TRY( params )
558 TTEXT( "(" );
559 int n = 0;
560 LOOP_BEGIN( params )
561 NT2( Term, rulegen, MIN_PREC );
562 n++;
563 CHOICE_BEGIN( paramType )
564 BRANCH_BEGIN( paramType )
565 TTEXT( ":" );
566 NT( Type );
567 BRANCH_END( paramType )
568 BRANCH_BEGIN( paramType )
569 BUILD_NODE( T_UNSPECED, NULL, FPOS, 0, 0 );
570 BRANCH_END( paramType )
571 CHOICE_END( paramType )
572 CHOICE_BEGIN( paramDelim )
573 BRANCH_BEGIN( paramDelim )
574 TTEXT( "," );
575 BRANCH_END( paramDelim )
576 BRANCH_BEGIN( paramDelim )
577 TTEXT( ")" );
578 DONE( params );
579 BRANCH_END( paramDelim )
580 CHOICE_END( paramDelim )
581 LOOP_END( params );
582 UNZIP( n );
583 BUILD_NODE( N_PARAM_TYPE_LIST, "paramTypelist", &paramListStart, n, n );
584 Node *node = POP;
585 BUILD_NODE( N_PARAM_LIST, "paramlist", &paramListStart, n, n );
586 PUSH( node );
587 OR( params )
588 OPTIONAL_BEGIN( epl )
589 TTEXT( "(" );
590 TTEXT( ")" );
591 OPTIONAL_END( epl )
592 BUILD_NODE( N_PARAM_LIST, "paramlist", &paramListStart, 0, 0 );
593 BUILD_NODE( N_PARAM_TYPE_LIST, "paramTypelist", &paramListStart, 0, 0 );
594 END_TRY( params )
595 
596 TRY( retType )
597 TTEXT( ":" );
598 NT( FuncType );
599 OR( retType )
600 BUILD_NODE( T_UNSPECED, NULL, FPOS, 0, 0 );
601 END_TRY( retType )
602 BUILD_NODE( N_RULE_NAME, ruleName, &start, 3, 3 );
603 PARSER_FUNC_END( RuleName )
604 
605 PARSER_FUNC_BEGIN( Metadata )
606 int rulegen = 1;
607 int n = 0;
608 LOOP_BEGIN( metadata )
609 TRY( avu )
610 TTEXT( "@" );
611 TTEXT( "(" );
612 TTYPE( TK_STRING );
613 BUILD_NODE( TK_STRING, token->text, &pos, 0, 0 );
614 TTEXT( "," );
615 TTYPE( TK_STRING );
616 BUILD_NODE( TK_STRING, token->text, &pos, 0, 0 );
617 TRY( u )
618 TTEXT( "," );
619 TTYPE( TK_STRING );
620 BUILD_NODE( TK_STRING, token->text, &pos, 0, 0 );
621 TTEXT( ")" );
622 OR( u )
623 TTEXT( ")" );
624 BUILD_NODE( TK_STRING, "", &pos, 0, 0 );
625 END_TRY( u )
626 BUILD_NODE( N_AVU, AVU, &pos, 3, 3 );
627 n++;
628 OR( avu )
629 DONE( metadata );
630 END_TRY( avu )
631 LOOP_END( metadata )
632 BUILD_NODE( N_META_DATA, META_DATA, &start, n, n );
633 PARSER_FUNC_END( Metadata )
634 
635 
636 PARSER_FUNC_BEGIN( FuncExpr )
637 int rulegen = 1;
638 NT2( Term, 1, MIN_PREC );
639 CHOICE_BEGIN( reco )
640 BRANCH_BEGIN( reco )
641 TTEXT( ":::" );
642 NT2( Term, 1, MIN_PREC );
643 BRANCH_END( reco )
644 BRANCH_BEGIN( reco )
645 BUILD_APP_NODE( "nop", FPOS, 0 );
646 BRANCH_END( reco )
647 CHOICE_END( reco )
648 PARSER_FUNC_END( FuncExpr )
649 
650 PARSER_FUNC_BEGIN2( Actions, int rulegen, int backwardCompatible )
651 int n = 0;
652 TRY( actions )
653 ABORT( backwardCompatible );
654 TTEXT_LOOKAHEAD( "}" );
655 OR( actions )
656 LOOP_BEGIN( actions );
657 if ( !backwardCompatible ) {
658  NT2( Term, rulegen, MIN_PREC );
659 }
660 else {
661  NT( TermBackwardCompatible );
662 }
663 if ( rulegen ) {
664  CHOICE_BEGIN( reco )
665  BRANCH_BEGIN( reco )
666  TTEXT( ":::" );
667  NT2( Term, rulegen, MIN_PREC );
668  BRANCH_END( reco )
669  BRANCH_BEGIN( reco )
670  BUILD_APP_NODE( "nop", NULL, 0 );
671  BRANCH_END( reco )
672  CHOICE_END( reco )
673 }
674 n++;
675 if ( rulegen ) {
676  OPTIONAL_BEGIN( actionSemiColon )
677  TTEXT( ";" );
678  OPTIONAL_END( actionSemiColon )
679  OPTIONAL_BEGIN( actionSemiColonBrace )
680  TTEXT_LOOKAHEAD( "}" );
681  DONE( actions );
682  OPTIONAL_END( actionSemiColonBrace )
683 }
684 else {
685  CHOICE_BEGIN( actionDelim )
686  BRANCH_BEGIN( actionDelim )
687  TTEXT( "##" );
688  BRANCH_END( actionDelim )
689  BRANCH_BEGIN( actionDelim )
690  DONE( actions );
691  BRANCH_END( actionDelim )
692  CHOICE_END( actionDelim )
693 }
694 LOOP_END( actions )
695 END_TRY( actions )
696 if ( rulegen ) {
697  UNZIP( n );
698 }
699 BUILD_NODE( N_ACTIONS, "ACTIONS", &start, n, n );
700 if ( rulegen ) {
701  Node *node = POP;
702  BUILD_NODE( N_ACTIONS, "ACTIONS", &start, n, n );
703  PUSH( node );
704 }
705 PARSER_FUNC_END( Actions )
706 
707 PARSER_FUNC_BEGIN( ActionsToStrings )
708 int rulegen = 1;
709 int n = 0;
710 #define bufferSize 10000
711 char actiBuffer[bufferSize], recoBuffer[bufferSize];
712 int actiP = 0, recoP = 0;
713 Label start, finish;
714 memset( &start, 0, sizeof( start ) );
715 memset( &finish, 0, sizeof( finish ) );
716 TRY( actions )
717 TTEXT_LOOKAHEAD( "}" );
718 OR( actions )
719 LOOP_BEGIN( actions );
720 start = *FPOS;
721 NT2( Term, rulegen, MIN_PREC );
722 ( void ) POP;
723 finish = *FPOS;
724 ABORT( actiP + finish.exprloc - start.exprloc + 1 >= bufferSize );
725 dupString( e, &start, finish.exprloc - start.exprloc, actiBuffer + actiP );
726 actiP += finish.exprloc - start.exprloc;
727 actiBuffer[actiP++] = ';';
728 if ( rulegen ) {
729  CHOICE_BEGIN( reco )
730  BRANCH_BEGIN( reco )
731  TTEXT( ":::" );
732  start = *FPOS;
733  NT2( Term, rulegen, MIN_PREC );
734  ( void ) POP;
735  finish = *FPOS;
736  ABORT( finish.exprloc - start.exprloc + 1 + recoP >= bufferSize );
737  dupString( e, &start, finish.exprloc - start.exprloc, recoBuffer + recoP );
738  recoP += finish.exprloc - start.exprloc;
739  recoBuffer[actiP++] = ';';
740  BRANCH_END( reco )
741  BRANCH_BEGIN( reco )
742  ABORT( recoP + 4 >= bufferSize );
743  strcpy( recoBuffer + recoP, "nop;" );
744  recoP += 4;
745  BRANCH_END( reco )
746  CHOICE_END( reco )
747 }
748 n++;
749 if ( rulegen ) {
750  OPTIONAL_BEGIN( actionSemiColon )
751  TTEXT( ";" );
752  OPTIONAL_END( actionSemiColon )
753  OPTIONAL_BEGIN( actionSemiColonBrace )
754  TTEXT_LOOKAHEAD( "}" );
755  DONE( actions );
756  OPTIONAL_END( actionSemiColonBrace )
757 }
758 else {
759  CHOICE_BEGIN( actionDelim )
760  BRANCH_BEGIN( actionDelim )
761  TTEXT( "##" );
762  BRANCH_END( actionDelim )
763  BRANCH_BEGIN( actionDelim )
764  DONE( actions );
765  BRANCH_END( actionDelim )
766  CHOICE_END( actionDelim )
767 }
768 LOOP_END( actions )
769 END_TRY( actions )
770 actiBuffer[actiP] = recoBuffer[recoP] = '\0';
771 BUILD_NODE( TK_STRING, actiBuffer, &start, 0, 0 );
772 BUILD_NODE( TK_STRING, recoBuffer, &start, 0, 0 );
773 PARSER_FUNC_END( ActionsToStrings )
774 
775 PARSER_FUNC_BEGIN1( TermSystemBackwardCompatible, int level )
776 int rulegen = 0;
777 TRY( func )
778 TTEXT( "ifExec" );
779 TTEXT( "(" );
780 if ( level == 1 ) {
781  NT1( ExprBackwardCompatible, 0 );
782 }
783 else {
784  NT2( Term, 0, MIN_PREC );
785 }
786 TTEXT( "," );
787 NT2( Actions, 0, level );
788 TTEXT( "," );
789 NT2( Actions, 0, level );
790 TTEXT( "," );
791 NT2( Actions, 0, level );
792 TTEXT( "," );
793 NT2( Actions, 0, level );
794 TTEXT( ")" );
795 BUILD_APP_NODE( "if", &start, 5 );
796 OR( func )
797 TTEXT( "whileExec" );
798 TTEXT( "(" );
799 if ( level == 1 ) {
800  NT1( ExprBackwardCompatible, 0 );
801 }
802 else {
803  NT2( Term, 0, MIN_PREC );
804 }
805 TTEXT( "," );
806 NT2( Actions, 0, level );
807 TTEXT( "," );
808 NT2( Actions, 0, level );
809 TTEXT( ")" );
810 BUILD_APP_NODE( "while", &start, 3 );
811 OR( func )
812 TTEXT( "forEachExec" );
813 TTEXT( "(" );
814 TTYPE( TK_LOCAL_VAR );
815 BUILD_NODE( TK_VAR, token->text, &start, 0, 0 );
816 TTEXT( "," );
817 NT2( Actions, 0, level );
818 TTEXT( "," );
819 NT2( Actions, 0, level );
820 TTEXT( ")" );
821 BUILD_APP_NODE( "foreach", &start, 3 );
822 
823 OR( func )
824 TTEXT( "assign" );
825 TTEXT( "(" );
826 TTYPE( TK_LOCAL_VAR );
827 BUILD_NODE( TK_VAR, token->text, &pos, 0, 0 );
828 TTEXT( "," );
829 if ( level == 1 ) {
830  TRY( expr )
831  NT1( ExprBackwardCompatible, 1 );
832  OR( expr )
833  NT( ActionArgumentBackwardCompatible );
834  END_TRY( expr )
835 }
836 else {
837  NT2( Term, 0, MIN_PREC );
838 }
839 TTEXT( ")" );
840 if ( level == 1 ) {
841  BUILD_APP_NODE( "assignStr", &start, 2 );
842 }
843 else {
844  BUILD_APP_NODE( "assign", &start, 2 );
845 }
846 OR( func )
847 TTEXT( "forExec" );
848 TTEXT( "(" );
849 NT2( Term, 0, MIN_PREC );
850 TTEXT( "," );
851 NT2( Term, 0, MIN_PREC );
852 TTEXT( "," );
853 NT2( Term, 0, MIN_PREC );
854 TTEXT( "," );
855 NT2( Actions, 0, level );
856 TTEXT( "," );
857 NT2( Actions, 0, level );
858 TTEXT( ")" );
859 BUILD_APP_NODE( "for", &start, 5 );
860 OR( func )
861 TTEXT( "breakExec" );
862 BUILD_APP_NODE( "break", &start, 0 );
863 OR( func )
864 TTEXT( "delayExec" );
865 TTEXT( "(" );
866 NT( ActionArgumentBackwardCompatible )
867 TTEXT( "," );
868 Token strtoken;
869 nextActionArgumentStringBackwardCompatible( e, &strtoken );
870 if ( strtoken.type != TK_STRING ) {
871  BUILD_NODE( N_ERROR, "reached the end of stream while parsing an action argument", FPOS, 0, 0 );
872 }
873 else {
874  BUILD_NODE( TK_STRING, strtoken.text, &pos, 0, 0 );
875 }
876 TTEXT( "," );
877 nextActionArgumentStringBackwardCompatible( e, &strtoken );
878 if ( strtoken.type != TK_STRING ) {
879  BUILD_NODE( N_ERROR, "reached the end of stream while parsing an action argument", FPOS, 0, 0 );
880 }
881 else {
882  BUILD_NODE( TK_STRING, strtoken.text, &pos, 0, 0 );
883 }
884 TTEXT( ")" );
885 BUILD_APP_NODE( "delayExec", &start, 3 );
886 OR( func )
887 TTEXT( "remoteExec" );
888 TTEXT( "(" );
889 
890 NT( ActionArgumentBackwardCompatible )TTEXT( "," );
891 NT( ActionArgumentBackwardCompatible )TTEXT( "," );
892 Token strtoken;
893 nextActionArgumentStringBackwardCompatible( e, &strtoken );
894 if ( strtoken.type != TK_STRING ) {
895  BUILD_NODE( N_ERROR, "reached the end of stream while parsing an action argument", FPOS, 0, 0 );
896 }
897 else {
898  BUILD_NODE( TK_STRING, strtoken.text, &pos, 0, 0 );
899 }
900 TTEXT( "," );
901 nextActionArgumentStringBackwardCompatible( e, &strtoken );
902 if ( strtoken.type != TK_STRING ) {
903  BUILD_NODE( N_ERROR, "reached the end of stream while parsing an action argument", FPOS, 0, 0 );
904 }
905 else {
906  BUILD_NODE( TK_STRING, strtoken.text, &pos, 0, 0 );
907 }
908 TTEXT( ")" );
909 BUILD_APP_NODE( "remoteExec", &start, 4 );
910 END_TRY( func )
911 PARSER_FUNC_END( TermSystemBackwardCompatible )
912 
913 PARSER_FUNC_BEGIN1( ExprBackwardCompatible, int level )
914 int rulegen = 0;
915 TRY( func )
916 ABORT( level == 1 );
917 NT( TermBackwardCompatible );
918 OR( func )
919 TTEXT( "(" );
920 NT1( ExprBackwardCompatible, level );
921 TTEXT( ")" );
922 OR( func )
923 NT1( T, 0 );
924 END_TRY( func )
925 OPTIONAL_BEGIN( term2 )
926 TTYPE( TK_OP );
927 char *fn = cpStringExt( token->text, context->region );
928 ABORT( !isBinaryOp( token ) );
929 if ( TOKEN_TEXT( "like" ) || TOKEN_TEXT( "not like" ) || TOKEN_TEXT( "==" ) || TOKEN_TEXT( "!=" ) ) {
930  BUILD_APP_NODE( "str", FPOS, 1 );
931  NT( ActionArgumentBackwardCompatible );
932 }
933 else if ( TOKEN_TEXT( "+" ) || TOKEN_TEXT( "-" ) || TOKEN_TEXT( "*" ) || TOKEN_TEXT( "/" ) || TOKEN_TEXT( "<" ) || TOKEN_TEXT( "<=" ) || TOKEN_TEXT( ">" ) || TOKEN_TEXT( ">=" ) ) {
934  BUILD_APP_NODE( "double", FPOS, 1 );
935  NT1( ExprBackwardCompatible, 1 );
936  BUILD_APP_NODE( "double", FPOS, 1 );
937 }
938 else if ( TOKEN_TEXT( "%%" ) || TOKEN_TEXT( "&&" ) ) {
939  BUILD_APP_NODE( "bool", FPOS, 1 );
940  NT1( ExprBackwardCompatible, 1 );
941  BUILD_APP_NODE( "bool", FPOS, 1 );
942 }
943 else {
944  BUILD_APP_NODE( "str", FPOS, 1 );
945  NT1( ExprBackwardCompatible, 1 );
946  BUILD_APP_NODE( "str", FPOS, 1 );
947 }
948 BUILD_APP_NODE( fn, &start, 2 );
949 OPTIONAL_END( term2 )
950 PARSER_FUNC_END( ExprBackwardCompatible )
951 
952 PARSER_FUNC_BEGIN( TermBackwardCompatible )
953 int rulegen = 0;
954 TRY( func )
955 NT1( TermSystemBackwardCompatible, 1 );
956 
957 OR( func )
958 TTYPE( TK_TEXT );
959 char *fn = cpStringExt( token->text, context->region );
960 TTEXT( "(" );
961 TTEXT( ")" );
962 BUILD_APP_NODE( fn, &start, 0 );
963 
964 OR( func )
965 TTYPE( TK_TEXT );
966 char *fn = cpStringExt( token->text, context->region );
967 TTEXT( "(" );
968 int n = 0;
969 LOOP_BEGIN( func )
970 NT( ActionArgumentBackwardCompatible );
971 n++;
972 CHOICE_BEGIN( paramDelim )
973 BRANCH_BEGIN( paramDelim )
974 TTEXT( "," );
975 BRANCH_END( paramDelim )
976 BRANCH_BEGIN( paramDelim )
977 TTEXT( ")" );
978 DONE( func );
979 BRANCH_END( paramDelim )
980 CHOICE_END( paramDelim )
981 LOOP_END( func )
982 BUILD_APP_NODE( fn, &start, n );
983 OR( func )
984 TTYPE( TK_TEXT );
985 char *fn = cpStringExt( token->text, context->region );
986 BUILD_APP_NODE( fn, &start, 0 );
987 
988 END_TRY( func )
989 
990 PARSER_FUNC_END( ValueBackwardCompatible )
991 
992 
993 PARSER_FUNC_BEGIN( ActionArgumentBackwardCompatible )
994 int rulegen = 0;
995 Token strtoken;
996 TRY( var )
997 Label vpos = *FPOS;
998 TTYPE( TK_LOCAL_VAR );
999 char *vn = cpStringExt( token->text, context->region );
1000 TTEXT3( ",", "|", ")" );
1001 PUSHBACK;
1002 BUILD_NODE( TK_VAR, vn, &vpos, 0, 0 );
1003 OR( var )
1004 syncTokenQueue( e, context );
1005 
1006 nextActionArgumentStringBackwardCompatible( e, &strtoken );
1007 if ( strtoken.type != TK_STRING ) {
1008  BUILD_NODE( N_ERROR, "reached the end of stream while parsing an action argument", FPOS, 0, 0 );
1009 }
1010 else {
1011  NT1( StringExpression, &strtoken );
1012 }
1013 END_TRY( var )
1014 PARSER_FUNC_END( ActionArgumentBackwardCompatible )
1015 
1016 PARSER_FUNC_BEGIN2( Term, int rulegen, int prec )
1017 TRY(term0)
1018  int n = 0;
1019  TTEXT2( "SELECT", "select" );
1020  LOOP_BEGIN( columns )
1021  NT( Column );
1022  n++;
1023  TRY( columnDelim )
1024  TTEXT( "," );
1025  OR( columnDelim )
1026  DONE( columns )
1027  END_TRY( columnDelim )
1028  LOOP_END( columns )
1029  OPTIONAL_BEGIN( where )
1030  TTEXT2( "WHERE", "where" );
1031  LOOP_BEGIN( queryConds )
1032  NT( QueryCond );
1033  n++;
1034  TRY( queryCondDelim )
1035  TTEXT2( "AND", "and" );
1036  OR( queryCondDelim )
1037  DONE( queryConds )
1038  END_TRY( queryCondDelim )
1039  LOOP_END( queryConds )
1040  OPTIONAL_END( where )
1041  BUILD_NODE( N_QUERY, "QUERY", &start, n, n );
1042  BUILD_APP_NODE( "query", &start, 1 );
1043 OR( term0 )
1044  TRY( func )
1045  ABORT( !rulegen );
1046  TRY( funcIf )
1047  TTEXT( "if" );
1048  TTEXT( "(" );
1049  NT2( Term, 1, MIN_PREC );
1050  TTEXT( ")" );
1051  OPTIONAL_BEGIN( ifThen )
1052  TTEXT( "then" );
1053  OPTIONAL_END( ifThen )
1054  TTEXT( "{" );
1055  NT2( Actions, 1, 0 );
1056  TTEXT( "}" );
1057  TRY( ifElse )
1058  TTEXT( "else" );
1059  TTEXT_LOOKAHEAD( "if" );
1060  NT2( Term, 1, MIN_PREC );
1061  BUILD_NODE( N_ACTIONS, "ACTIONS", &pos, 1, 1 );
1062  BUILD_APP_NODE( "nop", FPOS, 0 );
1063  BUILD_NODE( N_ACTIONS, "ACTIONS", FPOS, 1, 1 );
1064  OR( ifElse )
1065  TTEXT( "else" );
1066  TTEXT( "{" );
1067  NT2( Actions, 1, 0 );
1068  TTEXT( "}" );
1069  OR( ifElse )
1070  BUILD_APP_NODE( "nop", FPOS, 0 );
1071  BUILD_NODE( N_ACTIONS, "ACTIONS", FPOS, 1, 1 );
1072  BUILD_APP_NODE( "nop", FPOS, 0 );
1073  BUILD_NODE( N_ACTIONS, "ACTIONS", FPOS, 1, 1 );
1074  END_TRY( ifElse )
1075  UNZIP( 2 );
1076  BUILD_APP_NODE( "if", &start, 5 );
1077  OR( funcIf )
1078  TTEXT( "if" );
1079  NT2( Term, rulegen, MIN_PREC );
1080  TTEXT( "then" );
1081  NT2( Term, 1, MIN_PREC );
1082  BUILD_APP_NODE( "nop", FPOS, 0 );
1083  TTEXT( "else" )
1084  NT2( Term, 1, MIN_PREC );
1085  BUILD_APP_NODE( "nop", FPOS, 0 );
1086  UNZIP( 2 );
1087  BUILD_APP_NODE( "if2", &start, 5 );
1088  END_TRY( funcIf )
1089  OR( func )
1090  ABORT( !rulegen );
1091  TRY( whil )
1092  TTEXT( "while" );
1093  OR( whil )
1094  TTEXT( "whileExec" );
1095  END_TRY( whil )
1096  TTEXT( "(" );
1097  NT2( Term, 1, MIN_PREC );
1098  TTEXT( ")" );
1099  TTEXT( "{" );
1100  NT2( Actions, 1, 0 );
1101  TTEXT( "}" );
1102  BUILD_APP_NODE( "while", &start, 3 );
1103  OR( func )
1104  ABORT( !rulegen );
1105  TRY( foreach )
1106  TTEXT( "foreach" );
1107  OR( foreach )
1108  TTEXT( "forEachExec" );
1109  END_TRY( foreach )
1110  TTEXT( "(" );
1111  TTYPE( TK_LOCAL_VAR );
1112  BUILD_NODE( TK_VAR, token->text, &pos, 0, 0 );
1113  TRY( foreach2 )
1114  TTEXT( ")" );
1115  TTEXT( "{" );
1116  NT2( Actions, 1, 0 );
1117  TTEXT( "}" );
1118  BUILD_APP_NODE( "foreach", &start, 3 );
1119  OR( foreach2 )
1120  TTEXT( "in" );
1121  NT2( Term, 1, MIN_PREC );
1122  TTEXT( ")" );
1123  TTEXT( "{" );
1124  NT2( Actions, 1, 0 ); TTEXT( "}" );
1125  BUILD_APP_NODE( "foreach2", &start, 4 ); END_TRY( foreach2 )
1126  OR( func )
1127  ABORT( !rulegen );
1128  TRY( fo )
1129  TTEXT( "for" );
1130  OR( fo )
1131  TTEXT( "forExec" );
1132  END_TRY( fo )
1133  TTEXT( "(" );
1134  NT2( Term, 1, MIN_PREC );
1135  TTEXT( ";" );
1136  NT2( Term, 1, MIN_PREC );
1137  TTEXT( ";" );
1138  NT2( Term, 1, MIN_PREC );
1139  TTEXT( ")" );
1140  TTEXT( "{" );
1141  NT2( Actions, 1, 0 );
1142  TTEXT( "}" );
1143  BUILD_APP_NODE( "for", &start, 5 );
1144  OR( func )
1145  ABORT( !rulegen );
1146  TTEXT( "remote" );
1147  TTEXT( "(" );
1148  NT2( Term, 1, MIN_PREC );
1149  TTEXT( "," );
1150  NT2( Term, 1, MIN_PREC );
1151  TTEXT( ")" );
1152  TTEXT( "{" );
1153  char buf[10000];
1154  Label actionsStart = *FPOS;
1155  NT2( Actions, 1, 0 );
1156  ( void ) POP;
1157  ( void ) POP;
1158  Label actionsFinish = *FPOS;
1159  TTEXT( "}" );
1160  dupString( e, &actionsStart, actionsFinish.exprloc - actionsStart.exprloc, buf );
1161  BUILD_NODE( TK_STRING, buf, &actionsStart, 0, 0 );
1162  BUILD_NODE( TK_STRING, "", &actionsFinish, 0, 0 );
1163  BUILD_APP_NODE( "remoteExec", &start, 4 );
1164  OR( func )
1165  ABORT( !rulegen );
1166  TTEXT( "delay" );
1167  TTEXT( "(" );
1168  NT2( Term, 1, MIN_PREC );
1169  TTEXT( ")" );
1170  TTEXT( "{" );
1171  char buf[10000];
1172  Label actionsStart = *FPOS;
1173  NT2( Actions, 1, 0 );
1174  ( void ) POP;
1175  ( void ) POP;
1176  Label actionsFinish = *FPOS;
1177  TTEXT( "}" );
1178  dupString( e, &actionsStart, actionsFinish.exprloc - actionsStart.exprloc, buf );
1179  BUILD_NODE( TK_STRING, buf, &actionsStart, 0, 0 );
1180  BUILD_NODE( TK_STRING, "", &actionsFinish, 0, 0 );
1181  BUILD_APP_NODE( "delayExec", &start, 3 );
1182  OR( func )
1183  ABORT( !rulegen );
1184  TTEXT( "let" );
1185  NT2( Term, 1, 2 );
1186  TTEXT( "=" );
1187  NT2( Term, 1, MIN_PREC );
1188  TTEXT( "in" );
1189  NT2( Term, 1, MIN_PREC );
1190  BUILD_APP_NODE( "let", &start, 3 );
1191  OR( func )
1192  ABORT( !rulegen );
1193  TTEXT( "match" );
1194  NT2( Term, 1, 2 );
1195  TTEXT( "with" );
1196  int n = 0;
1197  OPTIONAL_BEGIN( semicolon )
1198  TTEXT( "|" );
1199  OPTIONAL_END( semicolon )
1200  LOOP_BEGIN( cases )
1201  Label cpos = *FPOS;
1202  NT2( Term, 1, MIN_PREC );
1203  TTEXT( "=>" );
1204  NT2( Term, 1, MIN_PREC );
1205  BUILD_NODE( N_TUPLE, TUPLE, &cpos, 2, 2 );
1206  n++;
1207  TRY( vbar )
1208  TTEXT( "|" );
1209  OR( vbar )
1210  DONE( cases )
1211  END_TRY( vbar );
1212  LOOP_END( cases )
1213  BUILD_APP_NODE( "match", &start, n + 1 );
1214  END_TRY( func )
1215 OR(term0)
1216 NT1( Value, rulegen );
1217 int done = 0;
1218 while ( !done && NO_SYNTAX_ERROR ) {
1219  CHOICE_BEGIN( term )
1220  BRANCH_BEGIN( term )
1221  TTYPE( TK_OP );
1222  ABORT( !isBinaryOp( token ) );
1223  if ( prec >= getBinaryPrecedence( token ) ) {
1224  PUSHBACK;
1225  done = 1;
1226  }
1227  else {
1228  char *fn;
1229  if ( TOKEN_TEXT( "=" ) ) {
1230  fn = "assign";
1231  }
1232  else {
1233  fn = token->text;
1234  }
1235  NT2( Term, rulegen, getBinaryPrecedence( token ) );
1236 #ifdef DEBUG_VERBOSE
1237  char err[1024];
1238  generateErrMsg( fn, FPOS->exprloc, "ftest", err );
1239  printf( "%s", err );
1240 #endif
1241  BUILD_APP_NODE( fn, &start, 2 );
1242  }
1243 
1244  BRANCH_END( term )
1245  BRANCH_BEGIN( term )
1246  TRY( syntacticalArg )
1247  TTEXT_LOOKAHEAD( "(" );
1248  OR( syntacticalArg )
1249  TTEXT_LOOKAHEAD( "[" );
1250  END_TRY( syntacticalArg )
1251 
1252  Token appToken;
1253  strcpy( appToken.text, "@@" );
1254  NT2( Term, rulegen, getBinaryPrecedence( &appToken ) );
1255  BUILD_NODE( N_APPLICATION, APPLICATION, &start, 2, 2 );
1256  BRANCH_END( term )
1257  BRANCH_BEGIN( term )
1258  done = 1;
1259  BRANCH_END( term )
1260  CHOICE_END( term )
1261 }
1262 if ( !done ) {
1263  break;
1264 }
1265 END_TRY(term0)
1266 OPTIONAL_BEGIN(typeascription)
1267  TTEXT(":");
1268  NT2(_Type, 0, 0);
1269  BUILD_NODE( N_EXTERN_DEF, "EXTERN", &start, 2, 2 );
1270 OPTIONAL_END(typeascription)
1271 PARSER_FUNC_END( Term )
1272 
1273 PARSER_FUNC_BEGIN1( StringExpression, Token *tk )
1274 int rulegen = 0;
1275 Token *strToken = NULL;
1276 if ( tk == NULL ) {
1277  TTYPE( TK_STRING );
1278  strToken = token;
1279 }
1280 else {
1281  strToken = tk;
1282 }
1283 int i = 0, k = 0;
1284 pos.base = e->base;
1285 long startLoc = strToken->exprloc;
1286 char *str = strToken->text;
1287 int st[100];
1288 int end[100];
1289 int noi = 1;
1290 st[0] = 0;
1291 end[0] = strlen( str );
1292 while ( strToken->vars[i] != -1 ) {
1293  /* this string contains reference to vars */
1294  int vs = strToken->vars[i];
1295  i++;
1296  if ( !isalpha( str[vs + 1] ) && str[vs + 1] != '_' ) {
1297  continue;
1298  }
1299  int ve;
1300  ve = vs + 2;
1301  while ( isalnum( str[ve] ) || str[ve] == '_' ) {
1302  ve++;
1303  }
1304  end[noi] = end[noi - 1];
1305  end[noi - 1] = vs;
1306  st[noi] = ve;
1307  noi++;
1308 }
1309 char sbuf[MAX_RULE_LEN];
1310 char delim[1];
1311 delim[0] = '\0';
1312 strncpy( sbuf, str + st[0], end[0] - st[0] );
1313 strcpy( sbuf + end[0] - st[0], delim );
1314 pos.exprloc = startLoc + st[0];
1315 int startloc = pos.exprloc;
1316 BUILD_NODE( TK_STRING, sbuf, &pos, 0, 0 );
1317 k = 1;
1318 while ( k < noi ) {
1319  strncpy( sbuf, str + end[k - 1], st[k] - end[k - 1] ); /* var */
1320  strcpy( sbuf + st[k] - end[k - 1], delim );
1321  pos.exprloc = startLoc + end[k - 1];
1322  BUILD_NODE( TK_VAR, sbuf, &pos, 0, 0 );
1323 
1324  BUILD_APP_NODE( "str", &pos, 1 );
1325 
1326  pos.exprloc = startloc;
1327  BUILD_APP_NODE( "++", &pos, 2 );
1328 
1329  strncpy( sbuf, str + st[k], end[k] - st[k] );
1330  strcpy( sbuf + end[k] - st[k], delim );
1331  pos.exprloc = startLoc + st[k];
1332  BUILD_NODE( TK_STRING, sbuf, &pos, 0, 0 );
1333 
1334  pos.exprloc = startloc;
1335  BUILD_APP_NODE( "++", &pos, 2 );
1336  k++;
1337 }
1338 PARSER_FUNC_END( StringExpression )
1339 
1340 PARSER_FUNC_BEGIN( PathExpression )
1341 int rulegen = 1;
1342 TRY( Token )
1343 TTYPE( TK_PATH );
1344 OR( Token )
1345 TTEXT( "/" );
1346 /* need to reparse */
1347 PUSHBACK;
1348 syncTokenQueue( e, context );
1349 TTYPE( TK_PATH );
1350 END_TRY( Token )
1351 NT1( StringExpression, token );
1352 BUILD_APP_NODE( "path", &start, 1 );
1353 PARSER_FUNC_END( PathExpression )
1354 
1355 PARSER_FUNC_BEGIN1( T, int rulegen )
1356 TRY( value )
1357 TTYPE( TK_LOCAL_VAR );
1358 BUILD_NODE( TK_VAR, token->text, &pos, 0, 0 );
1359 OR( value )
1360 TTYPE( TK_SESSION_VAR );
1361 BUILD_NODE( TK_VAR, token->text, &pos, 0, 0 );
1362 OR( value )
1363 TTYPE( TK_INT );
1364 BUILD_NODE( TK_INT, token->text, &start, 0, 0 );
1365 OR( value )
1366 TTYPE( TK_DOUBLE );
1367 BUILD_NODE( TK_DOUBLE, token->text, &start, 0, 0 );
1368 END_TRY( value )
1369 PARSER_FUNC_END( T )
1370 
1371 PARSER_FUNC_BEGIN1( Value, int rulegen )
1372 TRY( value )
1373 NT1( T, rulegen );
1374 OR( value )
1375 TTEXT2( "true", "false" );
1376 BUILD_NODE( TK_BOOL, token->text, &pos, 0, 0 );
1377 OR( value )
1378 TTEXT( "(" );
1379 TRY( tuple )
1380 TTEXT( ")" );
1381 BUILD_NODE( N_TUPLE, TUPLE, &start, 0, 0 );
1382 OR( tuple )
1383 NT2( Term, rulegen, MIN_PREC );
1384 int n = 1;
1385 LOOP_BEGIN( tupleLoop )
1386 TRY( tupleComp )
1387 TTEXT( "," );
1388 NT2( Term, rulegen, MIN_PREC );
1389 n++;
1390 OR( tupleComp )
1391 TTEXT( ")" );
1392 DONE( tupleLoop );
1393 END_TRY( tupleComp )
1394 LOOP_END( tupleLoop )
1395 BUILD_NODE( N_TUPLE, TUPLE, &start, n, n );
1396 
1397 
1398 END_TRY( tuple )
1399 
1400 OR( value )
1401 TTEXT( "{" );
1402 NT2( Actions, rulegen, 0 );
1403 if ( rulegen ) {
1404  BUILD_NODE( N_ACTIONS_RECOVERY, "ACTIONS_RECOVERY", &start, 2, 2 );
1405 }
1406 TTEXT( "}" );
1407 
1408 OR( value )
1409 TTYPE( TK_OP );
1410 ABORT( !isUnaryOp( token ) );
1411 NT2( Term, rulegen, getUnaryPrecedence( token ) );
1412 char *fn;
1413 if ( strcmp( token->text, "-" ) == 0 ) {
1414  fn = "neg";
1415 }
1416 else {
1417  fn = token->text;
1418 }
1419 BUILD_APP_NODE( fn, &start, 1 );
1420 
1421 OR( value )
1422 NT( PathExpression );
1423 OR( value )
1424 TRY( func )
1425 ABORT( rulegen );
1426 NT1( TermSystemBackwardCompatible, 0 );
1427 OR( func )
1428 TTYPE( TK_TEXT );
1429 ABORT( rulegen && isKeyword( token->text ) );
1430 char *fn = cpStringExt( token->text, context->region );
1431 BUILD_NODE( TK_TEXT, fn, &start, 0, 0 );
1432 #ifdef DEBUG_VERBOSE
1433 char err[1024];
1434 generateErrMsg( fn, start.exprloc, start.base, err );
1435 printf( "%s, %ld\n", err, start.exprloc );
1436 #endif
1437 TRY( nullary )
1438 TTEXT_LOOKAHEAD( "(" );
1439 OR( nullary )
1440 TTEXT_LOOKAHEAD( "[" );
1441 OR( nullary )
1442 Node *n = POP;
1443 BUILD_APP_NODE( n->text, &start, 0 );
1444 END_TRY( nullary )
1445 END_TRY( func )
1446 OR( value )
1447 NT1( StringExpression, NULL );
1448 END_TRY( value )
1449 PARSER_FUNC_END( Value )
1450 
1451 PARSER_FUNC_BEGIN( Column )
1452 int rulegen = 1;
1453 
1454 TRY( Column )
1455 Label colFuncStart = *FPOS;
1456 char *columnFunc = NULL;
1457 TRY( columnFunc )
1458 TTEXT2( "count", "COUNT" );
1459 columnFunc = "count";
1460 OR( columnFunc )
1461 TTEXT2( "sum", "SUM" );
1462 columnFunc = "sum";
1463 OR( columnFunc )
1464 TTEXT2( "order_desc", "ORDER_DESC" );
1465 columnFunc = "order_desc";
1466 OR( columnFunc )
1467 TTEXT2( "order_asc", "ORDER_ASC" );
1468 columnFunc = "order";
1469 OR( columnFunc )
1470 TTEXT2( "order", "ORDER" );
1471 columnFunc = "order";
1472 END_TRY( columnFunc )
1473 TTEXT( "(" );
1474 Label colStart = *FPOS;
1475 TTYPE( TK_TEXT );
1476 BUILD_NODE( TK_COL, token->text, &colStart, 0, 0 );
1477 TTEXT( ")" );
1478 BUILD_NODE( N_ATTR, columnFunc, &colFuncStart, 1, 1 );
1479 OR( Column )
1480 Label colStart = *FPOS;
1481 TTYPE( TK_TEXT );
1482 BUILD_NODE( TK_COL, token->text, &colStart, 0, 0 );
1483 BUILD_NODE( N_ATTR, "", &colStart, 1, 1 );
1484 END_TRY( Column )
1485 PARSER_FUNC_END( Column )
1486 
1487 PARSER_FUNC_BEGIN( QueryCond )
1488 int rulegen = 1;
1489 char *op = NULL;
1490 
1491 TRY( QueryCond )
1492 NT( Column )
1493 int n = 0;
1494 LOOP_BEGIN( Junction )
1495 Label l = *FPOS;
1496 TRY( QueryCondOp )
1497 TTEXT2( "=", "==" );
1498 NT1( Value, 1 );
1499 BUILD_NODE( N_QUERY_COND, "=", &l, 1, 1 );
1500 OR( QueryCondOp )
1501 TTEXT2( "<>", "!=" );
1502 NT1( Value, 1 );
1503 BUILD_NODE( N_QUERY_COND, "<>", &l, 1, 1 );
1504 OR( QueryCondOp )
1505 TTEXT( ">" );
1506 NT1( Value, 1 );
1507 BUILD_NODE( N_QUERY_COND, ">", &l, 1, 1 );
1508 OR( QueryCondOp )
1509 TTEXT( "<" );
1510 NT1( Value, 1 );
1511 BUILD_NODE( N_QUERY_COND, "<", &l, 1, 1 );
1512 OR( QueryCondOp )
1513 TTEXT( ">=" );
1514 NT1( Value, 1 );
1515 BUILD_NODE( N_QUERY_COND, ">=", &l, 1, 1 );
1516 OR( QueryCondOp )
1517 TTEXT( "<=" );
1518 NT1( Value, 1 );
1519 BUILD_NODE( N_QUERY_COND, "<=", &l, 1, 1 );
1520 OR( QueryCondOp )
1521 TTEXT2( "in", "IN" );
1522 NT1( Value, 1 );
1523 BUILD_NODE( N_QUERY_COND, "in", &l, 1, 1 );
1524 OR( QueryCondOp )
1525 TTEXT2( "between", "BETWEEN" );
1526 NT1( Value, 1 );
1527 NT1( Value, 1 );
1528 BUILD_NODE( N_QUERY_COND, "between", &l, 2, 2 );
1529 OR( QueryCondOp )
1530 TTEXT2( "like", "LIKE" );
1531 NT1( Value, 1 );
1532 BUILD_NODE( N_QUERY_COND, "like", &l, 1, 1 );
1533 OR( QueryCondOp )
1534 TTEXT2( "not", "NOT" );
1535 TTEXT2( "like", "LIKE" );
1536 NT1( Value, 1 );
1537 BUILD_NODE( N_QUERY_COND, "not like", &l, 1, 1 );
1538 END_TRY( QueryCondOp )
1539 n++;
1540 TRY( Or )
1541 TTEXT( "||" );
1542 ABORT( op != NULL && strcmp( op, "||" ) != 0 );
1543 op = "||";
1544 OR( Or )
1545 TTEXT( "&&" );
1546 ABORT( op != NULL && strcmp( op, "&&" ) != 0 );
1547 op = "&&";
1548 OR( Or )
1549 DONE( Junction )
1550 END_TRY( Or )
1551 LOOP_END( Junction )
1552 BUILD_NODE( N_QUERY_COND_JUNCTION, op, &start, n + 1, n + 1 );
1553 
1554 END_TRY( QueryCond )
1555 PARSER_FUNC_END( QueryCond )
1556 
1557 int nextStringBase2( Pointer *e, char *value, int max_len, char* delim ) {
1558  char *value0 = value;
1559  nextChar( e );
1560  int ch = nextChar( e );
1561  while ( ch != -1 ) {
1562  if (value >= value0 + max_len) {
1563  return -1;
1564  }
1565  if ( delim[0] == ch && delim[1] == lookAhead( e, 1 ) ) {
1566  if ( delim[0] == delim[1] ) {
1567  while ( lookAhead( e, 2 ) == delim[1] ) {
1568  *( value++ ) = delim[0];
1569  if (value >= value0 + max_len) { return -1; }
1570  nextChar( e );
1571  }
1572  }
1573  *value = '\0';
1574  nextChar( e );
1575  nextChar( e );
1576  return 0;
1577  }
1578  *( value++ ) = ch;
1579  ch = nextChar( e );
1580  }
1581  return -1;
1582 
1583 }
1584 /*
1585  * return number of vars or -1 if no string found
1586  */
1587 int nextStringBase( Pointer *e, char *value, int max_len, char* delim, int consumeDelim, char escape, int cntOffset, int vars[] ) {
1588  int mode = 1; /* 1 string 3 escape */
1589  int nov = 0;
1590  char* value0 = value;
1591  *value = lookAhead( e, 0 );
1592  value++;
1593  int ch = nextChar( e );
1594  while ( ch != -1 ) {
1595  if (value >= value0 + max_len) {
1596  return -1;
1597  }
1598  *value = ch;
1599  switch ( mode ) {
1600  case 1:
1601  if ( ch == escape ) {
1602  value--;
1603  mode = 3;
1604  }
1605  else if ( strchr( delim, ch ) != NULL ) {
1606  if ( consumeDelim ) {
1607  value[1] = '\0';
1608  trimquotes( value0 );
1609  nextChar( e );
1610  }
1611  else {
1612  value[0] = '\0';
1613  }
1614  vars[nov] = -1;
1615  return nov;
1616  }
1617  else if ( ( ch == '*' || ch == '$' ) &&
1618  isalpha( lookAhead( e, 1 ) ) ) {
1619  vars[nov++] = value - value0 - cntOffset;
1620  }
1621 
1622 
1623  break;
1624  case 3:
1625  if ( ch == 'n' ) {
1626  *value = '\n';
1627  }
1628  else if ( ch == 't' ) {
1629  *value = '\t';
1630  }
1631  else if ( ch == 'r' ) {
1632  *value = '\r';
1633  }
1634  else if ( ch == '0' ) {
1635  *value = '\0';
1636  }
1637  else {
1638  *value = ch;
1639  }
1640  mode -= 2;
1641  }
1642  ch = nextChar( e );
1643  value ++;
1644  }
1645  return -1;
1646 }
1647 int nextStringParsed( Pointer *e, char *value, int max_len, char* deliml, char *delimr, char *delim, int consumeDelim, int vars[] ) {
1648  int mode = 0; /* level */
1649  int nov = 0;
1650  char* value0 = value;
1651  int ch = lookAhead( e, 0 );
1652  while ( ch != -1 ) {
1653  if (value >= value0 + max_len) {
1654  return -1;
1655  }
1656  *value = ch;
1657  if ( strchr( deliml, ch ) != NULL ) {
1658  mode ++;
1659  }
1660  else if ( mode > 0 && strchr( delimr, ch ) != NULL ) {
1661  mode --;
1662  }
1663  else if ( mode == 0 && strchr( delim, ch ) ) {
1664  if ( consumeDelim ) {
1665  value[1] = '\0';
1666  trimquotes( value0 );
1667  nextChar( e );
1668  }
1669  else {
1670  value[0] = '\0';
1671  }
1672  vars[nov] = -1;
1673  return nov;
1674  }
1675  else if ( ( ch == '*' || ch == '$' ) &&
1676  isalpha( lookAhead( e, 1 ) ) ) {
1677  vars[nov++] = value - value0;
1678  }
1679  ch = nextChar( e );
1680  value ++;
1681  }
1682  return -1;
1683 }
1684 int nextString( Pointer *e, char *value, int vars[] ) {
1685  return nextStringBase( e, value, MAX_TOKEN_TEXT_LEN, "\"", 1, '\\', 1, vars );
1686 }
1687 int nextString2( Pointer *e, char *value, int vars[] ) {
1688  return nextStringBase( e, value, MAX_TOKEN_TEXT_LEN,"\'", 1, '\\', 1, vars );
1689 }
1690 
1692  int i;
1693  for ( i = 0; i < num_ops; i++ ) {
1694  if ( new_ops[i].arity == 2 && strcmp( new_ops[i].string, token->text ) == 0 ) {
1695  return new_ops[i].prec;
1696  }
1697  }
1698  return -1;
1699 }
1701  int i;
1702  for ( i = 0; i < num_ops; i++ ) {
1703  if ( new_ops[i].arity == 1 && strcmp( new_ops[i].string, token->text ) == 0 ) {
1704  return new_ops[i].prec;
1705  }
1706  }
1707  return -1;
1708 }
1710  int i;
1711  for ( i = 0; i < num_ops; i++ ) {
1712  if ( strcmp( token->text, new_ops[i].string ) == 0 ) {
1713  if ( new_ops[i].arity == 1 ) {
1714  return 1;
1715  }
1716  }
1717  }
1718  return 0;
1719 }
1721  int i;
1722  for ( i = 0; i < num_ops; i++ ) {
1723  if ( strcmp( token->text, new_ops[i].string ) == 0 ) {
1724  if ( new_ops[i].arity == 2 ) {
1725  return 1;
1726  }
1727  }
1728  }
1729  return 0;
1730 }
1731 int isOp( char *token ) {
1732  int i;
1733  for ( i = 0; i < num_ops; i++ ) {
1734  if ( strcmp( token, new_ops[i].string ) == 0 ) {
1735  return 1;
1736  }
1737  }
1738  return 0;
1739 }
1740 char* trim( char* str ) {
1741  char* trimmed = str;
1742  while ( *trimmed == '\t' || *trimmed == ' ' ) {
1743  trimmed ++;
1744  }
1745  int l = strlen( trimmed ) - 1;
1746  while ( l >= 0 && ( trimmed[l] == '\t' || trimmed[l] == ' ' ) ) {
1747  l--;
1748  }
1749  trimmed[l + 1] = '\0';
1750  return trimmed;
1751 
1752 }
1753 void trimquotes( char *string ) {
1754  int len = strlen( string ) - 2;
1755  memmove( string, string + 1, len * sizeof( char ) );
1756  string[len] = '\0';
1757 }
1758 
1759 void printTree( Node *n, int indent ) {
1760  printIndent( indent );
1761  char buf[128], buf2[128];
1762  if ( getNodeType( n ) >= T_UNSPECED && getNodeType( n ) <= T_TYPE ) {
1763  typeToString( n, NULL, buf, 128 );
1764  printf( "%s:%d\n", buf, getNodeType( n ) );
1765  return;
1766  }
1767  else if ( getNodeType( n ) >= TC_LT && getNodeType( n ) <= TC_SET ) {
1768  printf( "%s:%d\n", n->text, getNodeType( n ) );
1769  }
1770  else {
1771  if ( n->coercionType != NULL ) {
1772  typeToString( n->coercionType, NULL, buf, 128 );
1773  }
1774  else {
1775  buf[0] = '\0';
1776  }
1777  if ( n->exprType != NULL ) {
1778  typeToString( n->exprType, NULL, buf2, 128 );
1779  }
1780  else {
1781  buf2[0] = '\0';
1782  }
1783  char iotype[128];
1784  strcpy( iotype, "" );
1785  if ( getIOType( n ) & IO_TYPE_INPUT ) {
1786  strcat( iotype, "i" );
1787  }
1788  if ( getIOType( n ) & IO_TYPE_OUTPUT ) {
1789  strcat( iotype, "o" );
1790  }
1791  if ( getIOType( n ) & IO_TYPE_DYNAMIC ) {
1792  strcat( iotype, "d" );
1793  }
1794  if ( getIOType( n ) & IO_TYPE_EXPRESSION ) {
1795  strcat( iotype, "e" );
1796  }
1797  if ( getIOType( n ) & IO_TYPE_ACTIONS ) {
1798  strcat( iotype, "a" );
1799  }
1800  printf( "%s:%d %s => %s(option=%d)[%s]\n", n->text, getNodeType( n ), buf2, buf, n->option, iotype );
1801  }
1802  int i;
1803  for ( i = 0; i < n->degree; i++ ) {
1804  printTree( n->subtrees[i], indent + 1 );
1805  }
1806 
1807 }
1808 void patternToString( char **p, int *s, int indent, int prec, Node *n ) {
1809  switch ( getNodeType( n ) ) {
1810  case N_APPLICATION:
1811  if ( getNodeType( n->subtrees[0] ) == TK_TEXT ) {
1812  char *fn = n->subtrees[0]->text;
1813  Token t;
1814  snprintf( t.text, sizeof( t.text ), "%s", fn );
1815  if ( isBinaryOp( &t ) ) {
1816  int opPrec = getBinaryPrecedence( &t );
1817  if ( opPrec < prec ) {
1818  PRINT( p, s, "%s", "(" );
1819  }
1820  patternToString( p, s, indent, prec, n->subtrees[1]->subtrees[0] );
1821  PRINT( p, s, " %s ", fn );
1822  patternToString( p, s, indent, prec + 1, n->subtrees[1]->subtrees[1] );
1823  if ( opPrec < prec ) {
1824  PRINT( p, s, "%s", ")" );
1825  }
1826  }
1827  else {
1828  patternToString( p, s, indent, MIN_PREC, n->subtrees[0] );
1829  if ( getNodeType( n->subtrees[1] ) != N_TUPLE || n->subtrees[1]->degree != 0 ) {
1830  patternToString( p, s, indent, MIN_PREC, n->subtrees[1] );
1831  }
1832  }
1833  }
1834  else {
1835  PRINT( p, s, "%s", "<unsupported>" );
1836  }
1837  break;
1838  case N_TUPLE:
1839  PRINT( p, s, "%s", "(" );
1840  int i;
1841  for ( i = 0; i < n->degree; i++ ) {
1842  if ( i != 0 ) {
1843  PRINT( p, s, "%s", "," );
1844  }
1845  patternToString( p, s, indent, MIN_PREC, n->subtrees[i] );
1846  }
1847  PRINT( p, s, "%s", ")" );
1848  break;
1849  case TK_BOOL:
1850  case TK_DOUBLE:
1851  case TK_INT:
1852  case TK_VAR:
1853  case TK_TEXT:
1854  PRINT( p, s, "%s", n->text );
1855  break;
1856  case TK_STRING:
1857  PRINT( p, s, "%s", "\"" );
1858  unsigned int k;
1859  for ( k = 0; k < strlen( n->text ); k++ ) {
1860  switch ( n->text[k] ) {
1861  case '\t':
1862  PRINT( p, s, "%s", "\\t" );
1863  break;
1864  case '\n':
1865  PRINT( p, s, "%s", "\\n" );
1866  break;
1867  case '\r':
1868  PRINT( p, s, "%s", "\\r" );
1869  break;
1870  case '$':
1871  case '*':
1872  case '\\':
1873  case '\"':
1874  case '\'':
1875  PRINT( p, s, "%s", "\\" );
1876  PRINT( p, s, "%c", n->text[k] );
1877  break;
1878  default:
1879  PRINT( p, s, "%c", n->text[k] );
1880 
1881  }
1882  }
1883  PRINT( p, s, "%s", "\"" );
1884  break;
1885  default:
1886  PRINT( p, s, "%s", "<unsupported>" );
1887  }
1888 }
1889 void termToString( char **p, int *s, int indent, int prec, Node *n, int quote ) {
1890  switch ( getNodeType( n ) ) {
1891  case N_ACTIONS_RECOVERY:
1892  actionsToString( p, s, indent, n->subtrees[0], n->subtrees[1] );
1893  break;
1894  case N_APPLICATION:
1895  if ( getNodeType( n->subtrees[0] ) == TK_TEXT ) {
1896  char *fn = n->subtrees[0]->text;
1897  if ( strcmp( fn, "if" ) == 0 ) {
1898  PRINT( p, s, "%s", "if (" );
1899  termToString( p, s, indent, MIN_PREC, n->subtrees[1]->subtrees[0], quote );
1900  PRINT( p, s, "%s", ") " );
1901  actionsToString( p, s, indent, n->subtrees[1]->subtrees[1], n->subtrees[1]->subtrees[3] );
1902  PRINT( p, s, "%s", " else " );
1903  actionsToString( p, s, indent, n->subtrees[1]->subtrees[2], n->subtrees[1]->subtrees[4] );
1904  break;
1905  }
1906  if ( strcmp( fn, "if2" ) == 0 ) {
1907  PRINT( p, s, "%s", "if " );
1908  termToString( p, s, indent, MIN_PREC, n->subtrees[1]->subtrees[0], quote );
1909  PRINT( p, s, "%s", " then " );
1910  termToString( p, s, indent, MIN_PREC, n->subtrees[1]->subtrees[1], quote );
1911  PRINT( p, s, "%s", " else " );
1912  termToString( p, s, indent, MIN_PREC, n->subtrees[1]->subtrees[2], quote );
1913  break;
1914  }
1915  if ( strcmp( fn, "while" ) == 0 ) {
1916  PRINT( p, s, "%s", "while (" );
1917  termToString( p, s, indent, MIN_PREC, n->subtrees[1]->subtrees[0], quote );
1918  PRINT( p, s, "%s", ") " );
1919  actionsToString( p, s, indent, n->subtrees[1]->subtrees[1], n->subtrees[1]->subtrees[2] );
1920  break;
1921  }
1922  if ( strcmp( fn, "foreach" ) == 0 ) {
1923  PRINT( p, s, "%s", "foreach (" );
1924  termToString( p, s, indent, MIN_PREC, n->subtrees[1]->subtrees[0], quote );
1925  PRINT( p, s, "%s", ") " );
1926  actionsToString( p, s, indent, n->subtrees[1]->subtrees[1], n->subtrees[1]->subtrees[2] );
1927  break;
1928  }
1929  if ( strcmp( fn, "foreach2" ) == 0 ) {
1930  PRINT( p, s, "%s", "foreach (" );
1931  termToString( p, s, indent, MIN_PREC, n->subtrees[1]->subtrees[0], quote );
1932  PRINT( p, s, "%s", " in " );
1933  termToString( p, s, indent, MIN_PREC, n->subtrees[1]->subtrees[1], quote );
1934  PRINT( p, s, "%s", ") " );
1935  actionsToString( p, s, indent, n->subtrees[1]->subtrees[2], n->subtrees[1]->subtrees[3] );
1936  break;
1937  }
1938  if ( strcmp( fn, "for" ) == 0 ) {
1939  PRINT( p, s, "%s", "for (" );
1940  termToString( p, s, indent, MIN_PREC, n->subtrees[1]->subtrees[0], quote );
1941  PRINT( p, s, "%s", ";" );
1942  termToString( p, s, indent, MIN_PREC, n->subtrees[1]->subtrees[1], quote );
1943  PRINT( p, s, "%s", ";" );
1944  termToString( p, s, indent, MIN_PREC, n->subtrees[1]->subtrees[2], quote );
1945  PRINT( p, s, "%s", ") " );
1946  actionsToString( p, s, indent, n->subtrees[1]->subtrees[3], n->subtrees[1]->subtrees[4] );
1947  break;
1948  }
1949  if ( strcmp( fn, "let" ) == 0 ) {
1950  PRINT( p, s, "%s", "let " );
1951  termToString( p, s, indent, MIN_PREC, n->subtrees[1]->subtrees[0], quote );
1952  PRINT( p, s, "%s", " = " );
1953  termToString( p, s, indent, MIN_PREC, n->subtrees[1]->subtrees[1], quote );
1954  PRINT( p, s, "%s", " in " );
1955  termToString( p, s, indent, MIN_PREC, n->subtrees[1]->subtrees[2], quote );
1956  break;
1957  }
1958  if ( strcmp( fn, "match" ) == 0 ) {
1959  PRINT( p, s, "%s", "match " );
1960  termToString( p, s, indent, MIN_PREC, N_APP_ARG( n, 0 ), quote );
1961  PRINT( p, s, "%s", " with" );
1962  int i;
1963  for ( i = 1; i < N_APP_ARITY( n ); i++ ) {
1964  PRINT( p, s, "%s", "\n" );
1965  indentToString( p, s, indent + 1 );
1966  PRINT( p, s, "%s", "| " );
1967  patternToString( p, s, indent + 1, MIN_PREC, N_APP_ARG( n, i )->subtrees[0] );
1968  PRINT( p, s, "%s", " => " );
1969  termToString( p, s, indent + 1, MIN_PREC, N_APP_ARG( n, i )->subtrees[1], quote );
1970  }
1971  break;
1972  }
1973  if ( strcmp( fn, "assign" ) == 0 ) {
1974  patternToString( p, s, indent, MIN_PREC, n->subtrees[1]->subtrees[0] );
1975  PRINT( p, s, "%s", " = " );
1976  termToString( p, s, indent, MIN_PREC, n->subtrees[1]->subtrees[1], quote );
1977  break;
1978  }
1979  if ( strcmp( fn, "query" ) == 0 ) {
1980  Node *queNode = N_APP_ARG( n, 0 );
1981  int where = 0;
1982  PRINT( p, s, "%s", "select" );
1983  int i;
1984  for ( i = 0; i < queNode->degree; i++ ) {
1985  if ( getNodeType( queNode->subtrees[i] ) == N_ATTR ) {
1986  if ( i != 0 ) {
1987  PRINT( p, s, "%s", "," );
1988  }
1989  if ( strlen( queNode->subtrees[i]->text ) != 0 ) {
1990  PRINT( p, s, " %s(", queNode->subtrees[i]->text );
1991  PRINT( p, s, "%s)", queNode->subtrees[i]->subtrees[0]->text );
1992  }
1993  else {
1994  PRINT( p, s, "%s", queNode->subtrees[i]->subtrees[0]->text );
1995  }
1996  }
1997  else if ( getNodeType( queNode->subtrees[i] ) == N_QUERY_COND_JUNCTION ) {
1998  if ( !where ) {
1999  PRINT( p, s, " %s", "where" );
2000  where = 1;
2001  }
2002  else {
2003  PRINT( p, s, " %s", "and" );
2004  }
2005  PRINT( p, s, " %s", queNode->subtrees[i]->subtrees[0]->text ); /* column */
2006  PRINT( p, s, " %s", queNode->subtrees[i]->text ); /* op */
2007  int k;
2008  for ( k = 1; k < queNode->subtrees[i]->degree; k++ ) {
2009  termToString( p, s, indent, MAX_PREC, queNode->subtrees[i]->subtrees[k], quote );
2010  }
2011  }
2012  else {
2013  /* todo error handling */
2014  }
2015  }
2016  }
2017  Token t;
2018  snprintf( t.text, sizeof( t.text ), "%s", fn );
2019  if ( isBinaryOp( &t ) ) {
2020  int opPrec = getBinaryPrecedence( &t );
2021  if ( opPrec < prec ) {
2022  PRINT( p, s, "%s", "(" );
2023  }
2024  termToString( p, s, indent, prec, n->subtrees[1]->subtrees[0], quote );
2025  PRINT( p, s, " %s ", fn );
2026  termToString( p, s, indent, prec + 1, n->subtrees[1]->subtrees[1], quote );
2027  if ( opPrec < prec ) {
2028  PRINT( p, s, "%s", ")" );
2029  }
2030  break;
2031  }
2032  }
2033  termToString( p, s, indent, MIN_PREC, n->subtrees[0], quote );
2034  termToString( p, s, indent, MIN_PREC, n->subtrees[1], quote );
2035  break;
2036  case N_TUPLE:
2037  PRINT( p, s, "%s", "(" );
2038  int i;
2039  for ( i = 0; i < n->degree; i++ ) {
2040  if ( i != 0 ) {
2041  PRINT( p, s, "%s", "," );
2042  }
2043  termToString( p, s, indent, MIN_PREC, n->subtrees[i], quote );
2044  }
2045  PRINT( p, s, "%s", ")" );
2046  break;
2047  case TK_BOOL:
2048  case TK_DOUBLE:
2049  case TK_INT:
2050  case TK_VAR:
2051  case TK_TEXT:
2052  PRINT( p, s, "%s", n->text );
2053  break;
2054  case TK_STRING:
2055  PRINT( p, s, "%s", quote ? "\'" : "\"" );
2056  unsigned int k;
2057  for ( k = 0; k < strlen( n->text ); k++ ) {
2058  switch ( n->text[k] ) {
2059  case '\t':
2060  PRINT( p, s, "%s", "\\t" );
2061  break;
2062  case '\n':
2063  PRINT( p, s, "%s", "\\n" );
2064  break;
2065  case '\r':
2066  PRINT( p, s, "%s", "\\r" );
2067  break;
2068  case '$':
2069  case '*':
2070  case '\\':
2071  case '\"':
2072  case '\'':
2073  PRINT( p, s, "%s", "\\" );
2074  PRINT( p, s, "%c", n->text[k] );
2075  break;
2076  default:
2077  PRINT( p, s, "%c", n->text[k] );
2078 
2079  }
2080 
2081  }
2082  PRINT( p, s, "%s", quote ? "\'" : "\"" );
2083  break;
2084  default:
2085  PRINT( p, s, "%s", "<unsupported>" );
2086  }
2087 }
2088 void indentToString( char **p, int *s, int indent ) {
2089  int i;
2090  for ( i = 0; i < indent; i++ ) {
2091  PRINT( p, s, "%s", " " );
2092  }
2093 
2094 }
2095 void actionsToString( char **p, int *s, int indent, Node *na, Node *nr ) {
2096  int n = na->degree;
2097 
2098  int i;
2099  PRINT( p, s, "%s", "{\n" );
2100  for ( i = 0; i < n; i++ ) {
2101  indentToString( p, s, indent + 1 );
2102  termToString( p, s, indent + 1, MIN_PREC, na->subtrees[i], 0 );
2103  if ( nr != NULL && i < nr->degree && ( getNodeType( nr->subtrees[i] ) != N_APPLICATION || strcmp( nr->subtrees[i]->subtrees[0]->text, "nop" ) != 0 ) ) {
2104  PRINT( p, s, "%s", ":::" );
2105  termToString( p, s, indent + 1, MIN_PREC, nr->subtrees[i], 0 );
2106  }
2107  if ( ( *p )[-1] != '}' ) {
2108  PRINT( p, s, "%s", ";" );
2109  }
2110  PRINT( p, s, "%s", "\n" );
2111  }
2112  indentToString( p, s, indent );
2113  PRINT( p, s, "%s", "}" );
2114 }
2115 
2116 void metadataToString( char **p, int *s, int indent, Node *nm ) {
2117  int n = nm->degree;
2118  int i;
2119  for ( i = 0; i < n; i++ ) {
2120  indentToString( p, s, indent );
2121  PRINT( p, s, "%s", "@(" );
2122  termToString( p, s, indent, MIN_PREC, nm->subtrees[i]->subtrees[0], 0 );
2123  PRINT( p, s, "%s", ", " );
2124  termToString( p, s, indent, MIN_PREC, nm->subtrees[i]->subtrees[1], 0 );
2125  PRINT( p, s, "%s", ", " );
2126  termToString( p, s, indent, MIN_PREC, nm->subtrees[i]->subtrees[2], 0 );
2127  PRINT( p, s, "%s", ")\n" );
2128  }
2129 }
2130 
2131 void ruleNameToString( char **p, int *s, int indent, Node *rn ) {
2132  PRINT( p, s, "%s", rn->text );
2133  PRINT( p, s, "%s", "(" );
2134  int i;
2135  for ( i = 0; i < rn->subtrees[0]->degree; i++ ) {
2136  if ( i != 0 ) {
2137  PRINT( p, s, "%s", "," );
2138  }
2139  patternToString( p, s, indent, MIN_PREC, rn->subtrees[0]->subtrees[i] );
2140  }
2141  PRINT( p, s, "%s", ")" );
2142 }
2143 void typeToStringParser( char **p, int *s, int indent, int lifted, ExprType *type ) {
2144  ExprType *etype = type;
2145 
2146  if ( getIOType( etype ) == ( IO_TYPE_INPUT | IO_TYPE_OUTPUT ) ) {
2147  PRINT( p, s, "%s ", "input output" );
2148  }
2149  else if ( getIOType( etype ) == IO_TYPE_OUTPUT ) {
2150  PRINT( p, s, "%s ", "output" );
2151  }
2152  else if ( getIOType( etype ) == IO_TYPE_DYNAMIC ) {
2153  PRINT( p, s, "%s ", "dynamic" );
2154  }
2155  else if ( getIOType( etype ) == IO_TYPE_ACTIONS ) {
2156  PRINT( p, s, "%s ", "actions" );
2157  }
2158  else if ( getIOType( etype ) == IO_TYPE_EXPRESSION ) {
2159  PRINT( p, s, "%s ", "expression" );
2160  }
2161  if ( getNodeType( etype ) == T_VAR ) {
2162  PRINT( p, s, "%s", etype->text );
2163  if ( T_VAR_NUM_DISJUNCTS( type ) != 0 ) {
2164  PRINT( p, s, " %s", "{" );
2165  int i;
2166  for ( i = 0; i < T_VAR_NUM_DISJUNCTS( type ); i++ ) {
2167  typeToStringParser( p, s, indent, 0, T_VAR_DISJUNCT( type, i ) );
2168  PRINT( p, s, "%s", " " );
2169  }
2170  PRINT( p, s, "%s", "}" );
2171  }
2172  }
2173  else if ( getNodeType( etype ) == T_CONS ) {
2174  if ( strcmp( etype->text, FUNC ) == 0 ) {
2175  /* PRINT(p, s, "%s", "("); */
2176  typeToStringParser( p, s, indent, 1, T_CONS_TYPE_ARG( etype, 0 ) );
2177  if ( getVararg( type ) == OPTION_VARARG_OPTIONAL ) {
2178  PRINT( p, s, " %s", "?" );
2179  }
2180  else if ( getVararg( type ) == OPTION_VARARG_STAR ) {
2181  PRINT( p, s, " %s", "*" );
2182  }
2183  else if ( getVararg( type ) == OPTION_VARARG_PLUS ) {
2184  PRINT( p, s, " %s", "+" );
2185  }
2186  PRINT( p, s, " %s ", "->" );
2187  typeToStringParser( p, s, indent, 0, T_CONS_TYPE_ARG( etype, 1 ) );
2188  /* PRINT(p, s, "%s", ")"); */
2189  }
2190  else {
2191  PRINT( p, s, "%s", T_CONS_TYPE_NAME( etype ) );
2192  int i;
2193  if ( T_CONS_ARITY( etype ) != 0 ) {
2194  PRINT( p, s, "%s", "(" );
2195  for ( i = 0; i < T_CONS_ARITY( etype ); i++ ) {
2196  if ( i != 0 ) {
2197  PRINT( p, s, "%s ", "," );
2198  }
2199  typeToStringParser( p, s, indent, 0, T_CONS_TYPE_ARG( etype, i ) );
2200  }
2201  PRINT( p, s, "%s", ")" );
2202  }
2203  }
2204  }
2205  else if ( getNodeType( etype ) == T_FLEX ) {
2206  PRINT( p, s, "%s ", typeName_Parser( getNodeType( etype ) ) );
2207  typeToStringParser( p, s, indent, 0, etype->subtrees[0] );
2208  }
2209  else if ( getNodeType( etype ) == T_FIXD ) {
2210  PRINT( p, s, "%s ", typeName_Parser( getNodeType( etype ) ) );
2211  typeToStringParser( p, s, indent, 0, etype->subtrees[0] );
2212  PRINT( p, s, " %s ", "=>" );
2213  typeToStringParser( p, s, indent, 0, etype->subtrees[1] );
2214  }
2215  else if ( getNodeType( etype ) == T_TUPLE ) {
2216  if ( T_CONS_ARITY( etype ) == 0 ) {
2217  PRINT( p, s, "%s", "unit" );
2218  }
2219  else {
2220  if ( T_CONS_ARITY( etype ) == 1 && !lifted ) {
2221  PRINT( p, s, "%s", "<" );
2222  }
2223  int i;
2224  for ( i = 0; i < T_CONS_ARITY( etype ); i++ ) {
2225  if ( i != 0 ) {
2226  PRINT( p, s, " %s ", "*" );
2227  }
2228  typeToStringParser( p, s, indent, 0, T_CONS_TYPE_ARG( etype, i ) );
2229  }
2230  if ( T_CONS_ARITY( etype ) == 1 && !lifted ) {
2231  PRINT( p, s, "%s", ">" );
2232  }
2233  }
2234  }
2235  else if ( getNodeType( etype ) == T_IRODS ) {
2236  PRINT( p, s, "`%s`", etype->text );
2237  }
2238  else {
2239  PRINT( p, s, "%s", typeName_Parser( getNodeType( etype ) ) );
2240  }
2241 
2242 }
2243 
2244 void ruleToString( char *buf, int size, RuleDesc *rd ) {
2245  Node *node = rd->node;
2246  char **p = &buf;
2247  int *s = &size;
2248  Node *subt = NULL;
2249  switch ( rd->ruleType ) {
2250  case RK_REL:
2251  ruleNameToString( p, s, 0, node->subtrees[0] );
2252 
2253  int indent;
2254  subt = node->subtrees[1];
2255  while ( getNodeType( subt ) == N_TUPLE && subt->degree == 1 ) {
2256  subt = subt->subtrees[0];
2257  }
2258 
2259  PRINT( p, s, "%s", " " );
2260  if ( getNodeType( subt ) != TK_BOOL ||
2261  strcmp( subt->text, "true" ) != 0 ) {
2262  PRINT( p, s, "%s", "{\n" );
2263  indentToString( p, s, 1 );
2264  PRINT( p, s, "%s", "on " );
2265  termToString( p, s, 1, MIN_PREC, node->subtrees[1], 0 );
2266  PRINT( p, s, "%s", " " );
2267  indent = 1;
2268  }
2269  else {
2270  indent = 0;
2271  }
2272  actionsToString( p, s, indent, node->subtrees[2], node->subtrees[3] );
2273  if ( indent == 1 ) {
2274  PRINT( p, s, "%s", "\n" );
2275  indentToString( p, s, 1 );
2276  metadataToString( p, s, 0, node->subtrees[4] );
2277  PRINT( p, s, "%s", "}\n" );
2278  }
2279  else {
2280  PRINT( p, s, "%s", "\n" );
2281  metadataToString( p, s, 0, node->subtrees[4] );
2282  }
2283  break;
2284  case RK_FUNC:
2285  ruleNameToString( p, s, 0, node->subtrees[0] );
2286  PRINT( p, s, "%s", " = " );
2287  termToString( p, s, 1, MIN_PREC, node->subtrees[2], 0 );
2288  PRINT( p, s, "%s", "\n" );
2289  metadataToString( p, s, 0, node->subtrees[4] );
2290  break;
2291  case RK_CONSTRUCTOR:
2292  PRINT( p, s, "constructor %s", node->subtrees[0]->text );
2293  PRINT( p, s, "%s", " : " );
2294  typeToStringParser( p, s, 0, 0, node->subtrees[1] );
2295  PRINT( p, s, "%s", "\n" );
2296  /* metadataToString(p, s, 0, node->subtrees[2]); */
2297  break;
2298  case RK_DATA:
2299  PRINT( p, s, "%s ", "data" );
2300  ruleNameToString( p, s, 0, node->subtrees[0] );
2301  PRINT( p, s, "%s", "\n" );
2302  break;
2303  case RK_EXTERN:
2304  PRINT( p, s, "%s : ", node->subtrees[0]->text );
2305  typeToStringParser( p, s, 0, 0, node->subtrees[1] );
2306  PRINT( p, s, "%s", "\n" );
2307  break;
2308 
2309 
2310  }
2311 
2312 }
2313 
2314 void functionApplicationToString( char *buf, int size, char *fn, Node **args, int n ) {
2315  char **p = &buf;
2316  int *s = &size;
2317  PRINT( p, s, "%s(", fn );
2318  int i;
2319  char *res;
2320  for ( i = 0; i < n; i++ ) {
2321  switch ( getNodeType( args[i] ) ) {
2322  case N_VAL:
2323  res = convertResToString( args[i] );
2324  PRINT( p, s, "%s", res );
2325  free( res );
2326  break;
2327  case N_ACTIONS:
2328  actionsToString( p, s, 0, args[i], NULL );
2329  break;
2330  default:
2331  termToString( p, s, 0, MIN_PREC, args[i], 0 );
2332  }
2333  if ( i != n - 1 ) {
2334  PRINT( p, s, "%s", ", " );
2335  }
2336  }
2337  PRINT( p, s, "%s", ")" );
2338  return;
2339 }
2340 
2341 
2343  if ( getNodeType( a ) == getNodeType( b ) &&
2344  strcmp( a->text, b->text ) == 0 &&
2345  a->degree == b->degree ) {
2346  int i;
2347  for ( i = 0; i < a->degree; i++ ) {
2348  if ( !eqExprNodeSyntactic( a->subtrees[i], b->subtrees[i] ) ) {
2349  return 0;
2350  }
2351  }
2352  }
2353  return 1;
2354 }
2355 int eqExprNodeSyntacticVarMapping( Node *a, Node *b, Hashtable *varMapping /* from a to b */ ) {
2356  char *val;
2357  if ( getNodeType( a ) == TK_VAR && getNodeType( b ) == TK_VAR &&
2358  ( val = ( char * )lookupFromHashTable( varMapping, a->text ) ) != NULL &&
2359  strcmp( val, b->text ) == 0 ) {
2360  return 1;
2361  }
2362  if ( getNodeType( a ) == getNodeType( b ) &&
2363  strcmp( a->text, b->text ) == 0 &&
2364  a->degree == b->degree ) {
2365  int i;
2366  for ( i = 0; i < a->degree; i++ ) {
2367  if ( !eqExprNodeSyntactic( a->subtrees[i], b->subtrees[i] ) ) {
2368  return 0;
2369  }
2370  }
2371  }
2372  return 1;
2373 }
2374 
2376  return getVarNamesInExprNodeAux( expr, NULL, r );
2377 }
2378 
2380  int i;
2381  switch ( getNodeType( expr ) ) {
2382  case TK_VAR:
2383  if ( expr->text[0] == '*' ) {
2384  StringList *nvars = ( StringList* )region_alloc( r, sizeof( StringList ) );
2385  nvars->next = vars;
2386  nvars->str = expr->text;
2387  return nvars;
2388  }
2389  /* non var */
2390  default:
2391  for ( i = 0; i < expr->degree; i++ ) {
2392  vars = getVarNamesInExprNodeAux( expr->subtrees[i], vars, r );
2393  }
2394  return vars;
2395  }
2396 }
2397 
2398 
2399 
2400 void nextChars( Pointer *p, int len ) {
2401  int i;
2402  for ( i = 0; i < len; i++ ) {
2403  nextChar( p );
2404  }
2405 }
2406 
2410 int nextChar( Pointer *p ) {
2411  if ( p->isFile ) {
2412  int ch = lookAhead( p, 1 );
2413  /*if(ch != -1) { */
2414  p->p++;
2415  /*} */
2416  return ch;
2417  }
2418  else {
2419  if ( p->strbuf[p->strp] == '\0' ) {
2420  return -1;
2421  }
2422  int ch = p->strbuf[++p->strp];
2423  if ( ch == '\0' ) {
2424  ch = -1; /* return -1 for eos */
2425  }
2426  return ch;
2427  }
2428 }
2429 
2430 Pointer *newPointer( FILE *fp, const char *ruleBaseName ) {
2431  Pointer *e = ( Pointer * )malloc( sizeof( Pointer ) );
2432  initPointer( e, fp, ruleBaseName );
2433  return e;
2434 }
2436  Pointer *e = ( Pointer * )malloc( sizeof( Pointer ) );
2437  initPointer2( e, buf );
2438 
2439  return e;
2440 }
2442  if ( buf ) {
2443  if ( buf->isFile ) {
2444  fclose( buf->fp );
2445  }
2446  free( buf->base );
2447  free( buf );
2448  }
2449 
2450 }
2451 
2452 void initPointer( Pointer *p, FILE* fp, const char* ruleBaseName /* = NULL */ ) {
2453  fseek( fp, 0, SEEK_SET );
2454  p->fp = fp;
2455  p->fpos = 0;
2456  p->len = 0;
2457  p->p = 0;
2458  p->isFile = 1;
2459  p->base = ( char * )malloc( strlen( ruleBaseName ) + 2 );
2460  p->base[0] = 'f';
2461  strcpy( p->base + 1, ruleBaseName );
2462 }
2463 
2464 void initPointer2( Pointer *p, char *buf ) {
2465  p->strbuf = buf;
2466  p->strlen = strlen( buf );
2467  p->strp = 0;
2468  p->isFile = 0;
2469  p->base = ( char * )malloc( strlen( buf ) + 2 );
2470  p->base[0] = 's';
2471  strcpy( p->base + 1, buf );
2472 }
2473 
2475  if ( p->isFile ) {
2476  unsigned int move = ( p->len + 1 ) / 2;
2477  move = move > p->p ? p->p : move; /* prevent next char from being deleted */
2478  int startpos = p->len - move;
2479  int load = POINTER_BUF_SIZE - startpos;
2480  /* move remaining to the top of the buffer */
2481  memmove( p->buf, p->buf + move, startpos * sizeof( char ) );
2482  /* load from file */
2483  int count = fread( p->buf + startpos, sizeof( char ), load, p->fp );
2484  p->len = startpos + count;
2485  p->p -= move;
2486  p->fpos += move * sizeof( char );
2487  }
2488  else {
2489  }
2490 }
2491 
2492 void seekInFile( Pointer *p, unsigned long x ) {
2493  if ( p -> isFile ) {
2494  if ( p->fpos < x * sizeof( char ) || p->fpos + p->len >= x * sizeof( char ) ) {
2495  int error_code = fseek( p->fp, x * sizeof( char ), SEEK_SET );
2496  if ( error_code != 0 ) {
2497  rodsLog( LOG_ERROR, "fseek failed in seekInFile with error code %d", error_code );
2498  }
2499  clearBuffer( p );
2500  p->fpos = x * sizeof( char );
2501  readToBuffer( p );
2502  }
2503  else {
2504  p->p = x * sizeof( char ) - p->fpos;
2505  }
2506  }
2507  else {
2508  p->strp = x;
2509  }
2510 }
2511 
2513  if ( p->isFile ) {
2514  p->fpos += p->len * sizeof( char );
2515  p->len = p->p = 0;
2516  }
2517  else {
2518  }
2519 }
2520 
2521 /* assume that n is less then POINTER_BUF_SIZE */
2522 int dupString( Pointer *p, Label * start, int n, char *buf ) {
2523  if ( p->isFile ) {
2524  Label curr;
2525  getFPos( &curr, p, NULL );
2526  seekInFile( p, start->exprloc );
2527  int len = 0;
2528  int ch;
2529  while ( len < n && ( ch = lookAhead( p, 0 ) ) != -1 ) {
2530  buf[len++] = ( char ) ch;
2531  nextChar( p );
2532  }
2533  buf[len] = '\0';
2534  seekInFile( p, curr.exprloc );
2535  return len;
2536  }
2537  else {
2538  int len = strlen( p->strbuf + start->exprloc );
2539  len = len > n ? n : len;
2540  memcpy( buf, p->strbuf + start->exprloc, len * sizeof( char ) );
2541  buf[len] = '\0';
2542  return len;
2543  }
2544 }
2545 
2546 int dupLine( Pointer *p, Label * start, int n, char *buf ) {
2547  Label pos;
2548  getFPos( &pos, p, NULL );
2549  seekInFile( p, 0 );
2550  int len = 0;
2551  int i = 0;
2552  int ch = lookAhead( p, 0 );
2553  while ( ch != -1 ) {
2554  if ( ch == '\n' ) {
2555  if ( i < start->exprloc ) {
2556  len = 0;
2557  }
2558  else {
2559  break;
2560  }
2561  }
2562  else {
2563  buf[len] = ch;
2564  len++;
2565  if ( len == n - 1 ) {
2566  break;
2567  }
2568  }
2569  i++;
2570  ch = nextChar( p );
2571  }
2572  buf[len] = '\0';
2573  seekInFile( p, pos.exprloc );
2574  return len;
2575 }
2576 
2577 void getCoor( Pointer *p, Label * errloc, int coor[2] ) {
2578  Label pos;
2579  getFPos( &pos, p, NULL );
2580  seekInFile( p, 0 );
2581  coor[0] = coor[1] = 0;
2582  int i;
2583  char ch = lookAhead( p, 0 );
2584  for ( i = 0; i < errloc->exprloc; i++ ) {
2585  if ( ch == '\n' ) {
2586  coor[0]++;
2587  coor[1] = 0;
2588  }
2589  else {
2590  coor[1]++;
2591  }
2592  ch = nextChar( p );
2593  /* if(ch == '\r') { skip \r
2594  ch = nextChar(p);
2595  } */
2596  }
2597  seekInFile( p, pos.exprloc );
2598 }
2599 
2601  Label pos;
2602  getFPos( &pos, p, NULL );
2603  seekInFile( p, 0 );
2604  Label l;
2605  range[0] = range[1] = 0;
2606  int i = 0;
2607  int ch = lookAhead( p, 0 );
2608  while ( i < line && ch != -1 ) {
2609  if ( ch == '\n' ) {
2610  i++;
2611  }
2612  ch = nextChar( p );
2613  /* if(ch == '\r') { skip \r
2614  ch = nextChar(p);
2615  } */
2616  }
2617  if ( ch == -1 ) {
2618  return -1;
2619  }
2620  range[0] = getFPos( &l, p, NULL )->exprloc;
2621  while ( i == line && ch != -1 ) {
2622  if ( ch == '\n' ) {
2623  i++;
2624  }
2625  ch = nextChar( p );
2626  /* if(ch == '\r') { skip \r
2627  ch = nextChar(p);
2628  } */
2629  }
2630  range[1] = getFPos( &l, p, NULL )->exprloc;
2631  seekInFile( p, pos.exprloc );
2632  return 0;
2633 }
2634 
2636  if ( context == NULL || context->tqtop == context->tqp ) {
2637  if ( p->isFile ) {
2638  l->exprloc = p->fpos / sizeof( char ) + p->p;
2639  }
2640  else {
2641  l->exprloc = p->strp;
2642  }
2643  }
2644  else {
2645  l->exprloc = context->tokenQueue[context->tqp].exprloc;
2646  }
2647  l->base = p->base;
2648  return l;
2649 }
2650 /* assume that n is less then POINTER_BUF_SIZE/2 and greater than or equal to 0 */
2651 int lookAhead( Pointer *p, unsigned int n ) {
2652  if ( p->isFile ) {
2653  if ( p->p + n >= p->len ) {
2654  readToBuffer( p );
2655  if ( p->p + n >= p->len ) {
2656  return -1;
2657  }
2658  }
2659  return ( int )p->buf[p->p + n];
2660  }
2661  else {
2662  if ( n + p->strp >= p->strlen ) {
2663  return -1;
2664  }
2665  return ( int )p->strbuf[p->strp + n];
2666  }
2667 
2668 }
2669 
2670 /* backward compatibility with the previous version */
2671 char *functionParameters( char *e, char *value ) {
2672  int mode = 0; /* 0 params 1 string 2 string2 3 escape 4 escape2 */
2673  int l0 = 0;
2674  while ( *e != 0 ) {
2675  *value = *e;
2676  switch ( mode ) {
2677  case 0:
2678 
2679  switch ( *e ) {
2680  case '(':
2681  l0++;
2682  break;
2683  case '\"':
2684  mode = 1;
2685  break;
2686  case '\'':
2687  mode = 2;
2688  break;
2689  case ')':
2690  l0--;
2691  if ( l0 == 0 ) {
2692  value[1] = '\0';
2693  return e + 1;
2694  }
2695  }
2696  break;
2697  case 1:
2698  switch ( *e ) {
2699  case '\\':
2700  mode = 3;
2701  break;
2702  case '\"':
2703  mode = 0;
2704  }
2705  break;
2706  case 2:
2707  switch ( *e ) {
2708  case '\\':
2709  mode = 4;
2710  break;
2711  case '\'':
2712  mode = 0;
2713  }
2714  break;
2715  case 3:
2716  case 4:
2717  mode -= 2;
2718  }
2719  e++;
2720  value ++;
2721  }
2722  *value = 0;
2723  return e;
2724 }
2725 char *nextStringString( char *e, char *value ) {
2726  int mode = 1; /* 1 string 3 escape */
2727  char* e0 = e;
2728  char* value0 = value;
2729  *value = *e;
2730  value++;
2731  e++;
2732  while ( *e != 0 ) {
2733  *value = *e;
2734  switch ( mode ) {
2735  case 1:
2736  switch ( *e ) {
2737  case '\\':
2738  value--;
2739  mode = 3;
2740  break;
2741  case '\"':
2742  value[1] = '\0';
2743  trimquotes( value0 );
2744  return e + 1;
2745  }
2746  break;
2747  case 3:
2748  mode -= 2;
2749  }
2750  e++;
2751  value ++;
2752  }
2753  return e0;
2754 }
2755 char *nextString2String( char *e, char *value ) {
2756  int mode = 1; /* 1 string 3 escape */
2757  char* e0 = e;
2758  char* value0 = value;
2759  *value = *e;
2760  value ++;
2761  e++;
2762  while ( *e != 0 ) {
2763  *value = *e;
2764  switch ( mode ) {
2765  case 1:
2766  switch ( *e ) {
2767  case '\\':
2768  value--;
2769  mode = 3;
2770  break;
2771  case '\'':
2772  value[1] = '\0';
2773  trimquotes( value0 );
2774  return e + 1;
2775  }
2776  break;
2777  case 3:
2778  mode -= 2;
2779  }
2780  e++;
2781  value ++;
2782  }
2783  return e0;
2784 }
2785 
2786 
2787 char * nextRuleSection( char* buf, char* value ) {
2788  char* e = buf;
2789  int mode = 0; /* 0 section 1 string 2 string2 3 escape 4 escape2 */
2790  while ( *e != 0 ) {
2791  *value = *e;
2792  switch ( mode ) {
2793  case 0:
2794 
2795  switch ( *e ) {
2796  case '\"':
2797  mode = 1;
2798  break;
2799  case '\'':
2800  mode = 2;
2801  break;
2802  case '|':
2803  *value = '\0';
2804  return e + 1;
2805  }
2806  break;
2807  case 1:
2808  switch ( *e ) {
2809  case '\\':
2810  mode = 3;
2811  break;
2812  case '\"':
2813  mode = 0;
2814  }
2815  break;
2816  case 2:
2817  switch ( *e ) {
2818  case '\\':
2819  mode = 4;
2820  break;
2821  case '\'':
2822  mode = 0;
2823  }
2824  break;
2825  case 3:
2826  case 4:
2827  mode -= 2;
2828  }
2829  e++;
2830  value ++;
2831  }
2832  *value = 0;
2833  return e;
2834 
2835 
2836 }
2837 
2839  skipWhitespace( e );
2840  Label start;
2841  token->exprloc = getFPos( &start, e, NULL )->exprloc;
2842  int ch = lookAhead( e, 0 );
2843  if ( ch == -1 ) { /* reach the end of stream */
2844  token->type = TK_EOS;
2845  strcpy( token->text, "EOS" );
2846  }
2847  else {
2848  ch = lookAhead( e, 0 );
2849  if ( ch == '\"' ) {
2850  nextStringBase( e, token->text, MAX_TOKEN_TEXT_LEN,"\"", 1, '\\', 1, token->vars );
2851  skipWhitespace( e );
2852  }
2853  else if ( ch == '\'' ) {
2854  nextStringBase( e, token->text, MAX_TOKEN_TEXT_LEN,"\'", 1, '\\', 1, token->vars );
2855  skipWhitespace( e );
2856  }
2857  else {
2858  nextStringParsed( e, token->text, MAX_TOKEN_TEXT_LEN, "(", ")", ",|)", 0, token->vars );
2859  /* remove trailing ws */
2860  int l0;
2861  l0 = strlen( token->text );
2862  while ( isspace( token->text[l0 - 1] ) ) {
2863  l0--;
2864  }
2865  token->text[l0++] = '\0';
2866  }
2867  token->type = TK_STRING;
2868  }
2869 }
2870 
2871 PARSER_FUNC_BEGIN( TypingConstraints )
2872 Hashtable *temp = context->symtable;
2873 context->symtable = newHashTable2( 10, context->region );
2874 TRY( exec )
2875 NT( _TypingConstraints );
2876 FINALLY( exec )
2877 context->symtable = temp;
2878 END_TRY( exec )
2879 
2880 PARSER_FUNC_END( TypingConstraints )
2882 Hashtable *temp = context->symtable;
2883 context->symtable = newHashTable2( 10, context->region );
2884 TRY( exec )
2885 NT2( _Type, 0, 0 );
2886 FINALLY( exec )
2887 context->symtable = temp;
2888 END_TRY( exec )
2889 PARSER_FUNC_END( Type )
2890 
2892 Hashtable *temp = context->symtable;
2893 context->symtable = newHashTable2( 10, context->region );
2894 TRY( exec )
2895 NT( _FuncType );
2896 OR( exec )
2897 NT2( _Type, 0, 0 );
2898 BUILD_NODE( T_TUPLE, TUPLE, &start, 0, 0 );
2899 SWAP;
2900 BUILD_NODE( T_CONS, FUNC, &start, 2, 2 );
2901 FINALLY( exec )
2902 context->symtable = temp;
2903 END_TRY( exec )
2904 PARSER_FUNC_END( FuncType )
2905 
2906 PARSER_FUNC_BEGIN2( _Type, int prec, int lifted )
2907 int rulegen = 1;
2908 int arity = 0;
2909 Node *node = NULL;
2910 TRY( type )
2911 ABORT( prec == 1 );
2912 TRY( typeEnd )
2913 TTEXT_LOOKAHEAD( "->" );
2914 OR( typeEnd )
2915 TTEXT_LOOKAHEAD( "=>" );
2916 OR( typeEnd )
2917 TTEXT_LOOKAHEAD( ")" );
2918 OR( typeEnd )
2919 TTEXT_LOOKAHEAD( ">" );
2920 OR( typeEnd )
2922 END_TRY( typeEnd )
2923 OR( type )
2924 LOOP_BEGIN( type )
2925 int cont = 0;
2926 Label vpos = *FPOS;
2927 TRY( type )
2928 TTYPE( TK_BACKQUOTED ); /* irods type */
2929 BUILD_NODE( T_IRODS, token->text, &vpos, 0, 0 );
2930 OR( type )
2931 TRY( typeVar )
2932 TTYPE( TK_INT );
2933 OR( typeVar )
2934 TTYPE( TK_TEXT );
2935 ABORT( !isupper( token->text[0] ) );
2936 END_TRY( typeVar ) /* type variable */
2937 char *vname = cpStringExt( token->text, context->region );
2938 
2939 Node *tvar;
2940 if ( ( tvar = ( ExprType * ) lookupFromHashTable( context->symtable, vname ) ) == NULL ) {
2941  TRY( typeVarBound )
2942  /* union */
2943  NT( TypeSet );
2944  OR( typeVarBound )
2945  BUILD_NODE( T_VAR, vname, &vpos, 0, 0 );
2946  END_TRY( typeVarBound )
2947  tvar = POP;
2948  T_VAR_ID( tvar ) = newTVarId();
2949  insertIntoHashTable( context->symtable, vname, tvar );
2950 }
2951 CASCADE( tvar );
2952 OR( type )
2953 TTEXT( "?" );
2954 CASCADE( newSimpType( T_DYNAMIC, context->region ) );
2955 OR( type )
2956 TTEXT2( "integer", "int" );
2957 CASCADE( newSimpType( T_INT, context->region ) );
2958 OR( type )
2959 TTEXT( "double" );
2960 CASCADE( newSimpType( T_DOUBLE, context->region ) );
2961 OR( type )
2962 TTEXT( "boolean" );
2963 CASCADE( newSimpType( T_BOOL, context->region ) );
2964 OR( type )
2965 TTEXT( "time" );
2966 CASCADE( newSimpType( T_DATETIME, context->region ) );
2967 OR( type )
2968 TTEXT( "string" );
2969 CASCADE( newSimpType( T_STRING, context->region ) );
2970 OR( type )
2971 TTEXT( "path" );
2972 CASCADE( newSimpType( T_PATH, context->region ) );
2973 OR( type )
2974 TTEXT( "list" );
2975 NT2( _Type, 1, 0 );
2976 BUILD_NODE( T_CONS, LIST, &vpos, 1, 1 );
2977 Node *node = POP;
2979 PUSH( node );
2980 OR( type )
2981 TTEXT( "unit" );
2982 BUILD_NODE( T_TUPLE, TUPLE, &vpos, 0, 0 );
2983 OR( type )
2984 TTEXT( "(" );
2985 NT2( _Type, 0, 0 );
2986 TTEXT( ")" );
2987 OR( type )
2988 TTEXT( "<" )
2989 NT2( _Type, 0, 1 );
2990 TTEXT( ">" );
2991 OR( type )
2992 TTEXT( "forall" );
2993 TTYPE( TK_TEXT );
2994 ABORT( !isupper( token->text[0] ) );
2995 char *vname = cpStringExt( token->text, context->region );
2996 TRY( typeVarBound )
2997 TTEXT( "in" );
2998 NT( TypeSet );
2999 OR( typeVarBound )
3000 BUILD_NODE( T_VAR, vname, &vpos, 0, 0 );
3001 END_TRY( typeVarBound )
3002 Node *tvar = POP;
3003 T_VAR_ID( tvar ) = newTVarId();
3004 TTEXT( "," );
3005 insertIntoHashTable( context->symtable, vname, tvar );
3006 cont = 1;
3007 OR( type )
3008 TTEXT( "f" );
3009 /* flexible type, non dynamic coercion allowed */
3010 NT2( _Type, 1, 0 );
3011 TRY( ftype )
3012 TTEXT( "=>" );
3013 NT2( _Type, 1, 0 );
3014 BUILD_NODE( T_FIXD, NULL, &start, 2, 2 );
3015 OR( ftype )
3016 BUILD_NODE( T_FLEX, NULL, &start, 1, 1 );
3017 END_TRY( ftype );
3018 
3019 OR( type )
3020 TTEXT2( "output", "o" );
3021 NT2( _Type, 1, 0 );
3022 node = POP;
3024 PUSH( node );
3025 OR( type )
3026 TTEXT2( "input", "i" );
3027 NT2( _Type, 1, 0 );
3028 node = POP;
3030 PUSH( node );
3031 OR( type )
3032 TTEXT2( "expression", "e" );
3033 NT2( _Type, 1, 0 );
3034 node = POP;
3036 PUSH( node );
3037 OR( type )
3038 TTEXT2( "actions", "a" );
3039 NT2( _Type, 1, 0 );
3040 node = POP;
3042 PUSH( node );
3043 OR( type )
3044 TTEXT2( "dynamic", "d" );
3045 NT2( _Type, 1, 0 );
3046 node = POP;
3048 PUSH( node );
3049 OR( type )
3050 TTEXT( "type" );
3051 CASCADE( newSimpType( T_TYPE, context->region ) );
3052 /* type */
3053 OR( type )
3054 TTEXT( "set" );
3055 CASCADE( newSimpType( T_TYPE, context->region ) );
3056 /* set */
3057 OR( type )
3058 TTYPE( TK_TEXT );
3059 char *cons = cpStringExt( token->text, context->region );
3060 /* user type */
3061 int n = 0;
3062 OPTIONAL_BEGIN( argList )
3063 TTEXT( "(" );
3064 LOOP_BEGIN( args )
3065 NT2( _Type, 1, 0 );
3066 n++;
3067 TRY( delim )
3068 TTEXT( "," );
3069 OR( delim )
3070 DONE( args );
3071 END_TRY( delim )
3072 LOOP_END( args )
3073 TTEXT( ")" )
3074 OPTIONAL_END( argList )
3075 BUILD_NODE( T_CONS, cons, &start, n, n );
3076 END_TRY( type )
3077 OPTIONAL_BEGIN( kind )
3078 TTEXT( ":" );
3079 NT2( _Type, 1, 0 );
3080 SWAP;
3081 node = POP;
3082 node->exprType = POP;
3083 PUSH( node );
3084 OPTIONAL_END( kind )
3085 if ( !cont ) {
3086  arity ++;
3087  TRY( typeEnd )
3088  ABORT( prec != 1 );
3089  DONE( type );
3090  OR( typeEnd )
3092  DONE( type );
3093  OR( typeEnd )
3094  TTEXT( "*" );
3095  TTEXT( "->" );
3096  PUSHBACK;
3097  PUSHBACK;
3098  DONE( type );
3099  OR( typeEnd )
3100  TTEXT( "*" );
3101  OR( typeEnd );
3102  DONE( type );
3103  END_TRY( typeEnd )
3104 }
3105 LOOP_END( type )
3106 END_TRY( type )
3107 if ( arity != 1 || lifted ) {
3108  BUILD_NODE( T_TUPLE, TUPLE, &start, arity, arity );
3109 }
3110 PARSER_FUNC_END( _Type )
3111 
3113 int rulegen = 1;
3114 TTEXT( "{" );
3115 int n = 0;
3116 int done2 = 0;
3117 while ( !done2 && NO_SYNTAX_ERROR ) {
3118  NT2( _Type, 1, 0 );
3119  n++;
3120  OPTIONAL_BEGIN( typeVarBoundEnd )
3121  TTEXT( "}" );
3122  done2 = 1;
3123  OPTIONAL_END( typeVarBoundEnd )
3124 }
3125 if ( done2 ) {
3126  BUILD_NODE( T_VAR, NULL, &start, n, n );
3127 }
3128 else {
3129  break;
3130 }
3131 PARSER_FUNC_END( TypeSet )
3132 
3133 PARSER_FUNC_BEGIN( _TypingConstraints )
3134 int rulegen = 1;
3135 TTEXT( "{" );
3136 int n = 0;
3137 LOOP_BEGIN( tc )
3138 Label pos2 = *FPOS;
3139 NT2( _Type, 0, 0 );
3140 TTEXT( "<=" );
3141 NT2( _Type, 0, 0 );
3142 BUILD_NODE( TC_LT, "", &pos2, 0, 0 ); /* node for generating error messages */
3143 BUILD_NODE( TC_LT, "<=", &pos2, 3, 3 );
3144 n++;
3145 TRY( tce )
3146 TTEXT( "," );
3147 OR( tce )
3148 TTEXT( "}" );
3149 DONE( tc );
3150 END_TRY( tce )
3151 LOOP_END( tc )
3152 BUILD_NODE( TC_SET, "{}", &start, n, n );
3153 PARSER_FUNC_END( TypingConstraints )
3154 
3155 PARSER_FUNC_BEGIN( _FuncType )
3156 int rulegen = 1;
3157 int vararg = 0;
3158 NT2( _Type, 0, 1 );
3159 TRY( vararg )
3160 TTEXT( "*" );
3161 vararg = OPTION_VARARG_STAR;
3162 OR( vararg )
3163 TTEXT( "+" );
3164 vararg = OPTION_VARARG_PLUS;
3165 OR( vararg )
3166 TTEXT( "?" );
3167 vararg = OPTION_VARARG_OPTIONAL;
3168 OR( vararg )
3169 vararg = OPTION_VARARG_ONCE;
3170 END_TRY( vararg )
3171 TTEXT( "->" );
3172 NT2( _Type, 0, 0 );
3173 BUILD_NODE( T_CONS, FUNC, &start, 2, 2 );
3174 Node *node = POP;
3175 setVararg( node, vararg );
3176 PUSH( node );
3177 PARSER_FUNC_END( _FuncType )
3178 
3179 int parseRuleSet( Pointer *e, RuleSet *ruleSet, Env *funcDescIndex, int *errloc, rError_t *errmsg, Region *r ) {
3180  char errbuf[ERR_MSG_LEN];
3181  Token *token;
3182  ParserContext *pc = newParserContext( errmsg, r );
3183 
3184  int ret = 1;
3185  /* parser variables */
3186  int backwardCompatible = 0; /* 0 auto 1 true -1 false */
3187 
3188  while ( ret == 1 ) {
3189  pc->nodeStackTop = 0;
3190  pc->stackTopStackTop = 0;
3191  token = nextTokenRuleGen( e, pc, 1, 0 );
3192  switch ( token->type ) {
3193  case N_ERROR:
3194  deleteParserContext( pc );
3195  return -1;
3196  case TK_EOS:
3197  ret = 0;
3198  continue;
3199  case TK_MISC_OP:
3200  case TK_TEXT:
3201  if ( token->text[0] == '#' ) {
3202  skipComments( e );
3203  continue;
3204  }
3205  else if ( token->text[0] == '@' ) { /* directive */
3206  token = nextTokenRuleGen( e, pc, 1, 0 );
3207  if ( strcmp( token->text, "backwardCompatible" ) == 0 ) {
3208  token = nextTokenRuleGen( e, pc, 1, 0 );
3209  if ( token->type == TK_TEXT ) {
3210  if ( strcmp( token->text, "true" ) == 0 ) {
3211  backwardCompatible = 1;
3212  }
3213  else if ( strcmp( token->text, "false" ) == 0 ) {
3214  backwardCompatible = -1;
3215  }
3216  else if ( strcmp( token->text, "auto" ) == 0 ) {
3217  backwardCompatible = 0;
3218  }
3219  else {
3220  /* todo error handling */
3221  }
3222  }
3223  else {
3224  /* todo error handling */
3225  }
3226  }
3227  else if ( strcmp( token->text, "include" ) == 0 ) {
3228  token = nextTokenRuleGen( e, pc, 1, 0 );
3229  if ( token->type == TK_TEXT || token->type == TK_STRING ) {
3230  int ret = readRuleSetFromFile( token->text, ruleSet, funcDescIndex, errloc, errmsg, r );
3231  if ( ret != 0 ) {
3232  deleteParserContext( pc );
3233  return ret;
3234  }
3235  }
3236  else {
3237  /* todo error handling */
3238  }
3239  }
3240  else {
3241  /* todo error handling */
3242  }
3243  continue;
3244  }
3245  break;
3246  default:
3247  break;
3248  }
3249  pushback( token, pc );
3250 
3251  Node *node = parseRuleRuleGen( e, backwardCompatible, pc );
3252  if ( node == NULL ) {
3253  addRErrorMsg( errmsg, RE_OUT_OF_MEMORY, "parseRuleSet: out of memory." );
3254  deleteParserContext( pc );
3255  return RE_OUT_OF_MEMORY;
3256  }
3257  else if ( getNodeType( node ) == N_ERROR ) {
3258  *errloc = NODE_EXPR_POS( node );
3259  generateErrMsg( "parseRuleSet: error parsing rule.", *errloc, e->base, errbuf );
3260  addRErrorMsg( errmsg, RE_PARSER_ERROR, errbuf );
3261  /* skip the current line and try to parse the rule from the next line */
3262  skipComments( e );
3263  deleteParserContext( pc );
3264  return RE_PARSER_ERROR;
3265  }
3266  else {
3267  int n = node->degree;
3268  Node **nodes = node->subtrees;
3269  /* if(strcmp(node->text, "UNPARSED") == 0) {
3270  pushRule(ruleSet, newRuleDesc(RK_UNPARSED, nodes[0], r));
3271  } else */
3272  if ( strcmp( node->text, "INDUCT" ) == 0 ) {
3273  int k;
3274  pushRule( ruleSet, newRuleDesc( RK_DATA, nodes[0], 0, r ) );
3275  for ( k = 1; k < n; k++ ) {
3276  if ( lookupFromEnv( funcDescIndex, nodes[k]->subtrees[0]->text ) != NULL ) {
3277  generateErrMsg( "parseRuleSet: redefinition of constructor.", NODE_EXPR_POS( nodes[k]->subtrees[0] ), nodes[k]->subtrees[0]->base, errbuf );
3278  addRErrorMsg( errmsg, RE_TYPE_ERROR, errbuf );
3279  deleteParserContext( pc );
3280  return RE_TYPE_ERROR;
3281  }
3282  insertIntoHashTable( funcDescIndex->current, nodes[k]->subtrees[0]->text, newConstructorFD2( nodes[k]->subtrees[1], r ) );
3283  pushRule( ruleSet, newRuleDesc( RK_CONSTRUCTOR, nodes[k], 0, r ) );
3284  }
3285  }
3286  else if ( strcmp( node->text, "CONSTR" ) == 0 ) {
3287  if ( lookupFromEnv( funcDescIndex, nodes[0]->subtrees[0]->text ) != NULL ) {
3288  generateErrMsg( "parseRuleSet: redefinition of constructor.", NODE_EXPR_POS( nodes[0]->subtrees[0] ), nodes[0]->subtrees[0]->base, errbuf );
3289  addRErrorMsg( errmsg, RE_TYPE_ERROR, errbuf );
3290  deleteParserContext( pc );
3291  return RE_TYPE_ERROR;
3292  }
3293  insertIntoHashTable( funcDescIndex->current, nodes[0]->subtrees[0]->text, newConstructorFD2( nodes[0]->subtrees[1], r ) );
3294  pushRule( ruleSet, newRuleDesc( RK_CONSTRUCTOR, nodes[0], 0, r ) );
3295  }
3296  else if ( strcmp( node->text, "EXTERN" ) == 0 ) {
3297  FunctionDesc *fd;
3298  if ( ( fd = ( FunctionDesc * ) lookupFromEnv( funcDescIndex, nodes[0]->subtrees[0]->text ) ) != NULL ) {
3299  generateErrMsg( "parseRuleSet: redefinition of function.", NODE_EXPR_POS( nodes[0]->subtrees[0] ), nodes[0]->subtrees[0]->base, errbuf );
3300  addRErrorMsg( errmsg, RE_TYPE_ERROR, errbuf );
3301  deleteParserContext( pc );
3302  return RE_TYPE_ERROR;
3303  }
3304  insertIntoHashTable( funcDescIndex->current, nodes[0]->subtrees[0]->text, newExternalFD( nodes[0]->subtrees[1], r ) );
3305  pushRule( ruleSet, newRuleDesc( RK_EXTERN, nodes[0], 0, r ) );
3306  }
3307  else if ( strcmp( node->text, "REL" ) == 0 ) {
3308  int notyping = backwardCompatible >= 0 ? 1 : 0;
3309  int k;
3310  for ( k = 0; k < n; k++ ) {
3311  Node *node = nodes[k];
3312  pushRule( ruleSet, newRuleDesc( RK_REL, node, notyping, r ) );
3313  /* printf("%s\n", node->subtrees[0]->text);
3314  printTree(node, 0); */
3315  }
3316  }
3317  else if ( strcmp( node->text, "FUNC" ) == 0 ) {
3318  int k;
3319  for ( k = 0; k < n; k++ ) {
3320  Node *node = nodes[k];
3321  pushRule( ruleSet, newRuleDesc( RK_FUNC, node, 0, r ) );
3322  /* printf("%s\n", node->subtrees[0]->text);
3323  printTree(node, 0); */
3324  }
3325  }
3326  }
3327  }
3328  deleteParserContext( pc );
3329  return 0;
3330 }
3331 
3332 /*
3333  * parse the string for an ExprType
3334  * supported types:
3335  * ? dynamic
3336  * i integer
3337  * b boolean
3338  * d double
3339  * t time
3340  * s string
3341  * list <type> list
3342  * f <type> flexible
3343  * <var> ({ <type> ... <type> })? variable
3344  * <type> * ... * <type> product
3345  * < <type> * ... * <type> > lifted product
3346  * `irods PI` irods
3347  *
3348  * <type> (*|+|?)? -> <type> function
3349  * forall <var> (in { <type> ... <type> })?, <type> universal
3350  */
3351 Node* parseFuncTypeFromString( char *string, Region *r ) {
3352  Pointer *p = newPointer2( string );
3353  ParserContext *pc = newParserContext( NULL, r );
3354  nextRuleGenFuncType( p, pc );
3355  Node *exprType = pc->nodeStack[0];
3356  deleteParserContext( pc );
3357  deletePointer( p );
3358  return exprType;
3359 }
3360 Node* parseTypingConstraintsFromString( char *string, Region *r ) {
3361  Pointer *p = newPointer2( string );
3362  ParserContext *pc = newParserContext( NULL, r );
3363  nextRuleGenTypingConstraints( p, pc );
3364  Node *exprType = pc->nodeStack[0];
3365  /*char buf[ERR_MSG_LEN];
3366  errMsgToString(pc->errmsg, buf, ERR_MSG_LEN);
3367  printf("%s", buf);*/
3368  deleteParserContext( pc );
3369  deletePointer( p );
3370  return exprType;
3371 }
3372 Node *parseRuleRuleGen( Pointer *expr, int backwardCompatible, ParserContext *pc ) {
3373  nextRuleGenRule( expr, pc, backwardCompatible );
3374  Node *rulePackNode = pc->nodeStack[0];
3375  if ( pc->error ) {
3376  if ( pc->errnode != NULL ) {
3377  rulePackNode = pc->errnode;
3378  }
3379  else {
3380  rulePackNode = createErrorNode( "parser error", &pc->errloc, pc->region );
3381  }
3382  }
3383  return rulePackNode;
3384 }
3385 Node *parseTermRuleGen( Pointer *expr, int rulegen, ParserContext *pc ) {
3386  nextRuleGenTerm( expr, pc, rulegen, 0 );
3387  Node *rulePackNode = pc->nodeStack[0];
3388  if ( pc->error ) {
3389  if ( pc->errnode != NULL ) {
3390  rulePackNode = pc->errnode;
3391  }
3392  else {
3393  rulePackNode = createErrorNode( "parser error", &pc->errloc, pc->region );
3394  }
3395  }
3396 
3397  return rulePackNode;
3398 
3399 }
3400 Node *parseActionsRuleGen( Pointer *expr, int rulegen, int backwardCompatible, ParserContext *pc ) {
3401  nextRuleGenActions( expr, pc, rulegen, backwardCompatible );
3402  Node *rulePackNode = pc->nodeStack[0];
3403  if ( pc->error ) {
3404  if ( pc->errnode != NULL ) {
3405  rulePackNode = pc->errnode;
3406  }
3407  else {
3408  rulePackNode = createErrorNode( "parser error", &pc->errloc, pc->region );
3409  }
3410  }
3411 
3412  return rulePackNode;
3413 
3414 }
3415 char* typeName_Res( Res *s ) {
3416  return typeName_ExprType( s->exprType );
3417 }
3418 
3419 char* typeName_ExprType( ExprType *s ) {
3420  switch ( getNodeType( s ) ) {
3421  case T_IRODS:
3422  return s->text;
3423  default:
3424  return typeName_NodeType( getNodeType( s ) );
3425  }
3426 }
3427 
3428 char* typeName_Parser( NodeType s ) {
3429  switch ( s ) {
3430  case T_IRODS:
3431  return "IRODS";
3432  case T_VAR:
3433  return "VAR";
3434  case T_DYNAMIC:
3435  return "?";
3436  case T_CONS:
3437  return "CONS";
3438  case T_FLEX:
3439  return "f";
3440  case T_FIXD:
3441  return "f";
3442  case T_BOOL:
3443  return "boolean";
3444  case T_INT:
3445  return "integer";
3446  case T_DOUBLE:
3447  return "double";
3448  case T_STRING:
3449  return "string";
3450  case T_ERROR:
3451  return "ERROR";
3452  case T_DATETIME:
3453  return "time";
3454  case T_PATH:
3455  return "path";
3456  case T_TYPE:
3457  return "set";
3458  case T_TUPLE:
3459  return "TUPLE";
3460  default:
3461  return "OTHER";
3462  }
3463 }
3464 
3465 char* typeName_NodeType( NodeType s ) {
3466  switch ( s ) {
3467  case T_IRODS:
3468  return "IRODS";
3469  case T_VAR:
3470  return "VAR";
3471  case T_DYNAMIC:
3472  return "DYNAMIC";
3473  case T_CONS:
3474  return "CONS";
3475  case T_FLEX:
3476  return "FLEX";
3477  case T_FIXD:
3478  return "FIXD";
3479  case T_BOOL:
3480  return "BOOLEAN";
3481  case T_INT:
3482  return "INTEGER";
3483  case T_DOUBLE:
3484  return "DOUBLE";
3485  case T_STRING:
3486  return "STRING";
3487  case T_ERROR:
3488  return "ERROR";
3489  case T_DATETIME:
3490  return "DATETIME";
3491  case T_PATH:
3492  return "PATH";
3493  case T_TYPE:
3494  return "TYPE";
3495  case T_TUPLE:
3496  return "TUPLE";
3497  default:
3498  return "OTHER";
3499  }
3500 }
3501 
3502 void generateErrMsgFromFile( char *msg, long errloc, char *ruleBaseName, char* ruleBasePath, char errbuf[ERR_MSG_LEN] ) {
3503  FILE *fp = fopen( ruleBasePath, "r" );
3504  if ( fp != NULL ) {
3505  Pointer *e = newPointer( fp, ruleBaseName );
3506  Label l;
3507  l.base = NULL;
3508  l.exprloc = errloc;
3509  generateErrMsgFromPointer( msg, &l, e, errbuf );
3510  deletePointer( e );
3511  }
3512 }
3513 
3514 void generateErrMsgFromSource( char *msg, long errloc, char *src, char errbuf[ERR_MSG_LEN] ) {
3515  Pointer *e = newPointer2( src );
3516  Label l;
3517  l.base = NULL;
3518  l.exprloc = errloc;
3519  generateErrMsgFromPointer( msg, &l, e, errbuf );
3520  deletePointer( e );
3521 }
3522 void generateErrMsgFromPointer( char *msg, Label *l, Pointer *e, char errbuf[ERR_MSG_LEN] ) {
3523  char buf[ERR_MSG_LEN];
3524  dupLine( e, l, ERR_MSG_LEN, buf );
3525  int len = strlen( buf );
3526  int coor[2];
3527  getCoor( e, l, coor );
3528  int i;
3529  if ( len < ERR_MSG_LEN - 1 ) {
3530  buf[len++] = '\n';
3531  }
3532  for ( i = 0; i < coor[1]; i++ ) {
3533  if ( len >= ERR_MSG_LEN - 1 ) {
3534  break;
3535  }
3536  buf[len++] = buf[i] == '\t' ? '\t' : ' ';
3537  }
3538  if ( len < ERR_MSG_LEN - 2 ) {
3539  buf[len++] = '^';
3540  }
3541  buf[len++] = '\0';
3542  if ( e->isFile )
3543  snprintf( errbuf, ERR_MSG_LEN,
3544  "%s\nline %d, col %d, rule base %s\n%s\n", msg, coor[0], coor[1], e->base + 1, buf );
3545  else
3546  snprintf( errbuf, ERR_MSG_LEN,
3547  "%s\nline %d, col %d\n%s\n", msg, coor[0], coor[1], buf );
3548 
3549 }
3550 void generateAndAddErrMsg( char *msg, Node *node, int errcode, rError_t *errmsg ) {
3551  char errmsgBuf[ERR_MSG_LEN];
3552  generateErrMsg( msg, NODE_EXPR_POS( node ), node->base, errmsgBuf );
3553  addRErrorMsg( errmsg, errcode, errmsgBuf );
3554 }
3555 char *generateErrMsg( char *msg, long errloc, char *ruleBaseName, char errmsg[ERR_MSG_LEN] ) {
3556  char ruleBasePath[MAX_NAME_LEN];
3557  switch ( ruleBaseName[0] ) {
3558  case 's': // source
3559  generateErrMsgFromSource( msg, errloc, ruleBaseName + 1, errmsg );
3560  return errmsg;
3561  case 'f': // file
3562  getRuleBasePath( ruleBaseName + 1, ruleBasePath );
3563  generateErrMsgFromFile( msg, errloc, ruleBaseName + 1, ruleBasePath, errmsg );
3564  return errmsg;
3565  default:
3566  rodsLog(LOG_ERROR, "generateErrMsg: ruleBaseName of unknown type: [%s] [%ji] [%s]", msg, static_cast<intmax_t>(errloc), ruleBaseName);
3567  snprintf( errmsg, ERR_MSG_LEN, "<unknown source type>" );
3568  return errmsg;
3569  }
3570 }
rodsLog
void rodsLog(int level, const char *formatStr,...)
Definition: rodsLog.cpp:86
T_TYPE
@ T_TYPE
Definition: restructs.hpp:173
ABORT
#define ABORT(x)
Definition: parser.hpp:268
TTYPE_LOOKAHEAD
#define TTYPE_LOOKAHEAD(x)
Definition: parser.hpp:199
NULL
#define NULL
Definition: rodsDef.h:70
isLocalVariableNode
int isLocalVariableNode(Node *node)
Definition: parser.cpp:88
irods::experimental::administration::v1::zone_type::local
@ local
parser.hpp
parseRuleSet
int parseRuleSet(Pointer *e, RuleSet *ruleSet, Env *funcDescIndex, int *errloc, rError_t *errmsg, Region *r)
Definition: parser.cpp:3179
T_CONS_ARITY
#define T_CONS_ARITY(x)
Definition: restructs.hpp:28
convertResToString
char * convertResToString(Res *res0)
Definition: conversion.cpp:556
TK_BOOL
@ TK_BOOL
Definition: restructs.hpp:116
nextString2
int nextString2(Pointer *e, char *value, int vars[])
Definition: parser.cpp:1687
nextChar
int nextChar(Pointer *p)
Definition: parser.cpp:2410
nKeywords
#define nKeywords
Definition: parser.cpp:103
NT2
#define NT2(x, p, q)
Definition: parser.hpp:217
IO_TYPE_OUTPUT
#define IO_TYPE_OUTPUT
Definition: restructs.hpp:82
TTEXT_LOOKAHEAD
#define TTEXT_LOOKAHEAD(x)
Definition: parser.hpp:189
NT
#define NT(x)
Definition: parser.hpp:209
RK_FUNC
@ RK_FUNC
Definition: restructs.hpp:265
END_TRY
#define END_TRY(l)
Definition: parser.hpp:264
getFPos
Label * getFPos(Label *l, Pointer *p, ParserContext *context)
Definition: parser.cpp:2635
FUNC
#define FUNC
Definition: reconstants.hpp:20
token::type
NodeType type
Definition: restructs.hpp:294
INC_MOD
#define INC_MOD(x, m)
Definition: utils.hpp:96
utils.hpp
N_ATTR
@ N_ATTR
Definition: restructs.hpp:130
nextActionArgumentStringBackwardCompatible
void nextActionArgumentStringBackwardCompatible(Pointer *e, Token *token)
Definition: parser.cpp:2838
IO_TYPE_EXPRESSION
#define IO_TYPE_EXPRESSION
Definition: restructs.hpp:84
region_alloc
void * region_alloc(Region *r, size_t s)
Definition: region.cpp:138
ParserContext::errloc
Label errloc
Definition: parser.hpp:59
T_UNSPECED
@ T_UNSPECED
Definition: restructs.hpp:156
clearBuffer
void clearBuffer(Pointer *p)
Definition: parser.cpp:2512
syncTokenQueue
void syncTokenQueue(Pointer *e, ParserContext *context)
Definition: parser.cpp:355
op::prec
int prec
Definition: parser.hpp:28
isVariableNode
int isVariableNode(Node *node)
Definition: parser.cpp:98
getNodeType
#define getNodeType(x)
Definition: restructs.hpp:69
ParserContext::stackTopStackTop
int stackTopStackTop
Definition: parser.hpp:54
PARSER_FUNC_PROTO1
#define PARSER_FUNC_PROTO1(l, p)
Definition: parser.hpp:120
getLineRange
int getLineRange(Pointer *p, int line, rodsLong_t range[2])
Definition: parser.cpp:2600
configuration.hpp
IO_TYPE_ACTIONS
#define IO_TYPE_ACTIONS
Definition: restructs.hpp:85
generate_iadmin_commands_for_41_to_42_upgrade.output
output
Definition: generate_iadmin_commands_for_41_to_42_upgrade.py:21
readToBuffer
void readToBuffer(Pointer *p)
Definition: parser.cpp:2474
ParserContext::region
Region * region
Definition: parser.hpp:63
ParserContext::symtable
Hashtable * symtable
Definition: parser.hpp:61
typeToString
char * typeToString(ExprType *type, Hashtable *var_types, char *buf, int bufsize)
Definition: utils.cpp:522
rcMisc.h
TK_SESSION_VAR
@ TK_SESSION_VAR
Definition: restructs.hpp:121
RuleDesc::ruleType
RuleType ruleType
Definition: restructs.hpp:276
N_APP_ARITY
#define N_APP_ARITY(x)
Definition: restructs.hpp:44
pid_age.p
p
Definition: pid_age.py:13
printTree
void printTree(Node *n, int indent)
Definition: parser.cpp:1759
TC_LT
@ TC_LT
Definition: restructs.hpp:174
functionApplicationToString
void functionApplicationToString(char *buf, int size, char *fn, Node **args, int n)
Definition: parser.cpp:2314
generateErrMsg
char * generateErrMsg(char *msg, long errloc, char *ruleBaseName, char errmsg[1024])
Definition: parser.cpp:3555
T_DOUBLE
@ T_DOUBLE
Definition: restructs.hpp:159
T_PATH
@ T_PATH
Definition: restructs.hpp:168
ParserContext
Definition: parser.hpp:50
token::text
char text[1023+1]
Definition: restructs.hpp:295
TUPLE
#define TUPLE
Definition: reconstants.hpp:15
filesystem.hpp
num_ops
#define num_ops
Definition: parser.hpp:31
skipComments
void skipComments(Pointer *e)
Definition: parser.cpp:122
nextStringBase
int nextStringBase(Pointer *e, char *value, int max_len, char *delim, int consumeDelim, char escape, int cntOffset, int vars[])
Definition: parser.cpp:1587
N_APPLICATION
@ N_APPLICATION
Definition: restructs.hpp:128
TTEXT2
#define TTEXT2(x, y)
Definition: parser.hpp:175
node
Definition: restructs.hpp:244
POINTER_BUF_SIZE
#define POINTER_BUF_SIZE
Definition: reconstants.hpp:34
nextStringParsed
int nextStringParsed(Pointer *e, char *value, int max_len, char *deliml, char *delimr, char *delim, int consumeDelim, int vars[])
Definition: parser.cpp:1647
newParserContext
ParserContext * newParserContext(rError_t *errmsg, Region *r)
Definition: parser.cpp:70
getBinaryPrecedence
int getBinaryPrecedence(Token *token)
Definition: parser.cpp:1691
lookAhead
int lookAhead(Pointer *p, unsigned int n)
Definition: parser.cpp:2651
nextRuleSection
char * nextRuleSection(char *buf, char *value)
Definition: parser.cpp:2787
delayExec
int delayExec(msParam_t *condition, msParam_t *workflow, msParam_t *recoverWorkFlow, ruleExecInfo_t *rei)
Definition: nre.systemMS.cpp:111
eol
int eol(char ch)
Definition: parser.cpp:364
deploy_schemas_locally.parser
parser
Definition: deploy_schemas_locally.py:59
newTVarId
int newTVarId()
Definition: utils.cpp:312
RK_DATA
@ RK_DATA
Definition: restructs.hpp:266
TYPE
#define TYPE(x)
Definition: restructs.hpp:23
ParserContext::errnode
Node * errnode
Definition: parser.hpp:58
T_VAR_DISJUNCT
#define T_VAR_DISJUNCT(x, n)
Definition: restructs.hpp:35
token
Definition: restructs.hpp:293
LOG_ERROR
#define LOG_ERROR
Definition: rodsLog.h:43
OPTION_VARARG_OPTIONAL
#define OPTION_VARARG_OPTIONAL
Definition: restructs.hpp:75
pointer
Definition: parser.hpp:34
label::exprloc
long exprloc
Definition: restructs.hpp:289
isUnaryOp
int isUnaryOp(Token *token)
Definition: parser.cpp:1709
TK_MISC_OP
@ TK_MISC_OP
Definition: restructs.hpp:123
run_tests.action
action
Definition: run_tests.py:114
irods.pypyodbc.STRING
STRING
Definition: pypyodbc.py:335
TK_INT
@ TK_INT
Definition: restructs.hpp:112
irods.pyparsing.range
range
Definition: pyparsing.py:111
T_CONS
@ T_CONS
Definition: restructs.hpp:167
isOp
int isOp(char *token)
Definition: parser.cpp:1731
BOOLEAN
#define BOOLEAN
Definition: regExpMatch.hpp:27
RK_CONSTRUCTOR
@ RK_CONSTRUCTOR
Definition: restructs.hpp:267
IO_TYPE_DYNAMIC
#define IO_TYPE_DYNAMIC
Definition: restructs.hpp:83
irods::experimental::filesystem::client::end
auto end(const collection_iterator &) noexcept -> const collection_iterator
Definition: collection_iterator.hpp:88
node::text
char * text
Definition: restructs.hpp:252
functions.hpp
eqExprNodeSyntacticVarMapping
int eqExprNodeSyntacticVarMapping(Node *a, Node *b, Hashtable *varMapping)
Definition: parser.cpp:2355
nextStringString
char * nextStringString(char *e, char *value)
Definition: parser.cpp:2725
getVarNamesInExprNode
StringList * getVarNamesInExprNode(Node *expr, Region *r)
Definition: parser.cpp:2375
TK_VAR
@ TK_VAR
Definition: restructs.hpp:119
TTYPE
#define TTYPE(x)
Definition: parser.hpp:192
TTEXT
#define TTEXT(x)
Definition: parser.hpp:168
N_RULE_PACK
@ N_RULE_PACK
Definition: restructs.hpp:141
trim
char * trim(char *str)
Definition: parser.cpp:1740
trimquotes
void trimquotes(char *string)
Definition: parser.cpp:1753
str_list::next
struct str_list * next
Definition: restructs.hpp:239
TK_EOS
@ TK_EOS
Definition: restructs.hpp:110
POP
#define POP
Definition: parser.hpp:71
OR
#define OR(l)
Definition: parser.hpp:255
metadataToString
void metadataToString(char **p, int *s, int indent, Node *nm)
Definition: parser.cpp:2116
IO_TYPE_INPUT
#define IO_TYPE_INPUT
Definition: restructs.hpp:81
newHashTable2
Hashtable * newHashTable2(int size, Region *r)
Definition: hashtable.cpp:72
skipWhitespace
void skipWhitespace(Pointer *expr)
Definition: parser.cpp:115
irods.pypyodbc.DATETIME
DATETIME
Definition: pypyodbc.py:331
printIndent
void printIndent(int indent)
Definition: utils.cpp:487
irods.pyparsing.col
def col(loc, strg)
Definition: pyparsing.py:703
rError_t
Definition: rodsError.h:24
newPointer2
Pointer * newPointer2(char *buf)
Definition: parser.cpp:2435
T_IRODS
@ T_IRODS
Definition: restructs.hpp:172
start
irods::error start(irods::default_re_ctx &_u, const std::string &_instance_name)
Definition: libirods_rule_engine_plugin-cpp_default_policy.cpp:796
nextString2String
char * nextString2String(char *e, char *value)
Definition: parser.cpp:2755
ruleType
ruleType
Definition: restructs.hpp:263
N_ACTIONS
@ N_ACTIONS
Definition: restructs.hpp:134
TK_LOCAL_VAR
@ TK_LOCAL_VAR
Definition: restructs.hpp:120
nextChars
void nextChars(Pointer *p, int len)
Definition: parser.cpp:2400
TK_TEXT
@ TK_TEXT
Definition: restructs.hpp:114
TC_SET
@ TC_SET
Definition: restructs.hpp:175
N_EXTERN_DEF
@ N_EXTERN_DEF
Definition: restructs.hpp:152
node::subtrees
struct node ** subtrees
Definition: restructs.hpp:254
ParserContext::error
int error
Definition: parser.hpp:55
LOOP_BEGIN
#define LOOP_BEGIN(l)
Definition: parser.hpp:284
ParserContext::errmsgbuf
char errmsgbuf[1024]
Definition: parser.hpp:60
N_ACTIONS_RECOVERY
@ N_ACTIONS_RECOVERY
Definition: restructs.hpp:135
ParserContext::nodeStackTop
int nodeStackTop
Definition: parser.hpp:52
PRINT
#define PRINT(p, s, f, d)
Definition: utils.hpp:28
rules.hpp
T_DATETIME
@ T_DATETIME
Definition: restructs.hpp:162
node::degree
int degree
Definition: restructs.hpp:246
patternToString
void patternToString(char **p, int *s, int indent, int prec, Node *n)
Definition: parser.cpp:1808
N_QUERY_COND_JUNCTION
@ N_QUERY_COND_JUNCTION
Definition: restructs.hpp:132
BUILD_NODE
#define BUILD_NODE(type, cons, loc, deg, consume)
Definition: parser.hpp:100
PARSER_FUNC_END
#define PARSER_FUNC_END(l)
Definition: parser.hpp:142
PARSER_FUNC_PROTO2
#define PARSER_FUNC_PROTO2(l, p, q)
Definition: parser.hpp:122
termToString
void termToString(char **p, int *s, int indent, int prec, Node *n, int quote)
Definition: parser.cpp:1889
typeToStringParser
void typeToStringParser(char **p, int *s, int indent, int lifted, ExprType *type)
Definition: parser.cpp:2143
ParserContext::tqp
int tqp
Definition: parser.hpp:65
T_STRING
@ T_STRING
Definition: restructs.hpp:161
terminate_irods_processes.e
e
Definition: terminate_irods_processes.py:19
new_ops
Op new_ops[31]
Definition: parser.cpp:13
newSimpType
ExprType * newSimpType(NodeType t, Region *r)
Definition: restructs.cpp:70
insertIntoHashTable
int insertIntoHashTable(Hashtable *h, const char *key, const void *value)
Definition: hashtable.cpp:99
CASCADE
#define CASCADE(x)
Definition: parser.hpp:89
str_list::str
char * str
Definition: restructs.hpp:238
RK_EXTERN
@ RK_EXTERN
Definition: restructs.hpp:268
get_irods_version.value
dictionary value
Definition: get_irods_version.py:27
OPTION_VARARG_PLUS
#define OPTION_VARARG_PLUS
Definition: restructs.hpp:74
MAX_TOKEN_TEXT_LEN
#define MAX_TOKEN_TEXT_LEN
Definition: reconstants.hpp:24
FPOS
#define FPOS
Definition: parser.hpp:87
dupLine
int dupLine(Pointer *p, Label *start, int n, char *buf)
Definition: parser.cpp:2546
TK_DOUBLE
@ TK_DOUBLE
Definition: restructs.hpp:113
irods::experimental::filesystem::client::move
auto move(rcComm_t &_comm, const path &_old_p, const path &_new_p) -> void
Definition: filesystem.cpp:881
keywords
char * keywords[19]
Definition: parser.cpp:104
OPTION_VARARG_STAR
#define OPTION_VARARG_STAR
Definition: restructs.hpp:73
TK_PATH
@ TK_PATH
Definition: restructs.hpp:125
remoteExec
int remoteExec(msParam_t *hostName, msParam_t *condition, msParam_t *workflow, msParam_t *recoverWorkFlow, ruleExecInfo_t *rei)
Definition: nre.systemMS.cpp:298
node::coercionType
ExprType * coercionType
Definition: restructs.hpp:251
DONE
#define DONE(l)
Definition: parser.hpp:306
ParserContext::tqbot
int tqbot
Definition: parser.hpp:67
op::string
char * string
Definition: parser.hpp:26
lookupFromHashTable
const void * lookupFromHashTable(Hashtable *h, const char *key)
Definition: hashtable.cpp:222
token::vars
int vars[100]
Definition: restructs.hpp:296
ruleToString
void ruleToString(char *buf, int size, RuleDesc *rd)
Definition: parser.cpp:2244
ParserContext::tokenQueue
Token tokenQueue[1024]
Definition: parser.hpp:64
T_FIXD
@ T_FIXD
Definition: restructs.hpp:165
OPTION_VARARG_ONCE
#define OPTION_VARARG_ONCE
Definition: restructs.hpp:72
SWAP
#define SWAP
Definition: parser.hpp:148
ERROR
#define ERROR(code_, message_)
Definition: irods_error.hpp:117
isSessionVariableNode
int isSessionVariableNode(Node *node)
Definition: parser.cpp:93
FINALLY
#define FINALLY(l)
Definition: parser.hpp:259
region
Definition: region.h:45
T_BOOL
@ T_BOOL
Definition: restructs.hpp:163
indentToString
void indentToString(char **p, int *s, int indent)
Definition: parser.cpp:2088
PARSER_FUNC_PROTO
#define PARSER_FUNC_PROTO(l)
Definition: parser.hpp:118
ruleNameToString
void ruleNameToString(char **p, int *s, int indent, Node *rn)
Definition: parser.cpp:2131
actionsToString
void actionsToString(char **p, int *s, int indent, Node *na, Node *nr)
Definition: parser.cpp:2095
PUSHBACK
#define PUSHBACK
Definition: parser.hpp:86
irods.lib.indent
def indent(*text, **kwargs)
Definition: lib.py:138
RuleDesc
Definition: restructs.hpp:272
get_db_schema_version.l
l
Definition: get_db_schema_version.py:19
N_VAL
@ N_VAL
Definition: restructs.hpp:126
getUnaryPrecedence
int getUnaryPrecedence(Token *token)
Definition: parser.cpp:1700
deletePointer
void deletePointer(Pointer *buf)
Definition: parser.cpp:2441
PUSH
#define PUSH(n)
Definition: parser.hpp:70
MIN_PREC
#define MIN_PREC
Definition: reconstants.hpp:32
node::exprType
ExprType * exprType
Definition: restructs.hpp:250
nextString
int nextString(Pointer *e, char *value, int vars[])
Definition: parser.cpp:1684
match
int match(char *pattern, char *text)
eqExprNodeSyntactic
int eqExprNodeSyntactic(Node *a, Node *b)
Definition: parser.cpp:2342
TK_OP
@ TK_OP
Definition: restructs.hpp:122
N_TUPLE
@ N_TUPLE
Definition: restructs.hpp:127
PARSER_FUNC_BEGIN1
#define PARSER_FUNC_BEGIN1(l, p)
Definition: parser.hpp:135
skip
int skip(Pointer *e, char *text, Token **token, ParserContext *pc, int rulegen)
Definition: parser.cpp:147
deleteParserContext
void deleteParserContext(ParserContext *t)
Definition: parser.cpp:85
op
Definition: parser.hpp:25
isKeyword
int isKeyword(char *text)
Definition: parser.cpp:105
irods.six.b
def b(s)
Definition: six.py:606
T_VAR
@ T_VAR
Definition: restructs.hpp:171
initPointer2
void initPointer2(Pointer *p, char *buf)
Definition: parser.cpp:2464
error
int error
Definition: filesystem.cpp:101
RuleDesc::node
Node * node
Definition: restructs.hpp:275
seekInFile
void seekInFile(Pointer *p, unsigned long x)
Definition: parser.cpp:2492
T_VAR_NUM_DISJUNCTS
#define T_VAR_NUM_DISJUNCTS(x)
Definition: restructs.hpp:37
T_INT
@ T_INT
Definition: restructs.hpp:160
N_ERROR
@ N_ERROR
Definition: restructs.hpp:111
initPointer
void initPointer(Pointer *p, FILE *fp, const char *ruleBaseName)
Definition: parser.cpp:2452
T_TUPLE
@ T_TUPLE
Definition: restructs.hpp:166
TK_STRING
@ TK_STRING
Definition: restructs.hpp:115
PARSER_FUNC_BEGIN2
#define PARSER_FUNC_BEGIN2(l, p, q)
Definition: parser.hpp:138
node::option
int option
Definition: restructs.hpp:247
functionParameters
char * functionParameters(char *e, char *value)
Definition: parser.cpp:2671
T_DYNAMIC
@ T_DYNAMIC
Definition: restructs.hpp:158
getCoor
void getCoor(Pointer *p, Label *errloc, int coor[2])
Definition: parser.cpp:2577
hashtable
Definition: irods_hashtable.h:16
TK_BACKQUOTED
@ TK_BACKQUOTED
Definition: restructs.hpp:117
PARSER_FUNC_BEGIN
#define PARSER_FUNC_BEGIN(l)
Definition: parser.hpp:132
irods::foreach2
void foreach2(S &&a, T &&b, F &&f)
Definition: irods_re_plugin.hpp:813
OPTIONAL_BEGIN
#define OPTIONAL_BEGIN(l)
Definition: parser.hpp:274
newPointer
Pointer * newPointer(FILE *fp, const char *ruleBaseName)
Definition: parser.cpp:2430
size
long long size
Definition: filesystem.cpp:102
dupString
int dupString(Pointer *p, Label *start, int n, char *buf)
Definition: parser.cpp:2522
label
Definition: restructs.hpp:288
typeName_Parser
char * typeName_Parser(NodeType s)
Definition: parser.cpp:3428
mode
int mode
Definition: filesystem.cpp:104
N_CONSTRUCTOR_DEF
@ N_CONSTRUCTOR_DEF
Definition: restructs.hpp:151
token::exprloc
long exprloc
Definition: restructs.hpp:297
str_list
Definition: restructs.hpp:237
DEC_MOD
#define DEC_MOD(x, m)
Definition: utils.hpp:97
OPTIONAL_END
#define OPTIONAL_END(l)
Definition: parser.hpp:278
setVararg
#define setVararg(n, v)
Definition: restructs.hpp:88
getVararg
#define getVararg(n)
Definition: restructs.hpp:87
setIOType
#define setIOType(n, v)
Definition: restructs.hpp:90
T_CONS_TYPE_ARG
#define T_CONS_TYPE_ARG(x, n)
Definition: restructs.hpp:26
nextTokenRuleGen
Token * nextTokenRuleGen(Pointer *e, ParserContext *context, int rulegen, int pathLiteral)
Definition: parser.cpp:160
TRY
#define TRY(l)
Definition: parser.hpp:251
N_APP_ARG
#define N_APP_ARG(x, n)
Definition: restructs.hpp:42
findLineCont
char * findLineCont(char *expr)
Definition: parser.cpp:128
buf
static char buf[64+50+1]
Definition: rsAuthRequest.cpp:21
manual_cleanup.out
out
Definition: manual_cleanup.py:29
type
int type
Definition: filesystem.cpp:103
nextStringBase2
int nextStringBase2(Pointer *e, char *value, int max_len, char *delim)
Definition: parser.cpp:1557
T_VAR_ID
#define T_VAR_ID(x)
Definition: restructs.hpp:34
isBinaryOp
int isBinaryOp(Token *token)
Definition: parser.cpp:1720
MAX_PREC
#define MAX_PREC
Definition: reconstants.hpp:31
nop
void nop(const void *a)
Definition: hashtable.cpp:284
cpStringExt
char * cpStringExt(const char *str, Region *r)
Definition: utils.cpp:358
N_DATA_DEF
@ N_DATA_DEF
Definition: restructs.hpp:153
irods.pyparsing.line
def line(loc, strg)
Definition: pyparsing.py:728
getIOType
#define getIOType(n)
Definition: restructs.hpp:89
rodsLong_t
long long rodsLong_t
Definition: rodsType.h:32
getVarNamesInExprNodeAux
StringList * getVarNamesInExprNodeAux(Node *expr, StringList *vars, Region *r)
Definition: parser.cpp:2379
T_FLEX
@ T_FLEX
Definition: restructs.hpp:164
ParserContext::tqtop
int tqtop
Definition: parser.hpp:66
pushback
void pushback(Token *token, ParserContext *context)
Definition: parser.cpp:348
T_CONS_TYPE_NAME
#define T_CONS_TYPE_NAME(x)
Definition: restructs.hpp:27
LIST
#define LIST
Definition: reconstants.hpp:14
ParserContext::errmsg
rError_t * errmsg
Definition: parser.hpp:62
LOOP_END
#define LOOP_END(l)
Definition: parser.hpp:299
RK_REL
@ RK_REL
Definition: restructs.hpp:264