Removed obsolete selection code.
[gromacs/qmmm-gamess-us.git] / src / gmxlib / selection / parser.y
blob3d40293667abe3c0bdc440a8b46f467cca3a3e76
1 /*
3 * This source code is part of
5 * G R O M A C S
7 * GROningen MAchine for Chemical Simulations
9 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
10 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
11 * Copyright (c) 2001-2009, The GROMACS development team,
12 * check out http://www.gromacs.org for more information.
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * If you want to redistribute modifications, please consider that
20 * scientific software is very special. Version control is crucial -
21 * bugs must be traceable. We will be happy to consider code for
22 * inclusion in the official distribution, but derived work must not
23 * be called official GROMACS. Details are found in the README & COPYING
24 * files - if they are missing, get the official version at www.gromacs.org.
26 * To help us fund GROMACS development, we humbly ask that you cite
27 * the papers on the package - you can find them in the top README file.
29 * For more info, check our website at http://www.gromacs.org
31 /*! \internal \file
32 * \brief Grammar description and parser for the selection language.
35 /*! \internal \file parser.c
36 * \brief Generated (from parser.y by Bison) parser for the selection language.
38 /*! \internal \file parser.h
39 * \brief Generated (from parser.y by Bison) parser include file.
41 #ifdef HAVE_CONFIG_H
42 #include <config.h>
43 #endif
46 #include <string2.h>
48 #include "parsetree.h"
49 #include "selelem.h"
51 #include "scanner.h"
53 static t_selexpr_value *
54 process_value_list(t_selexpr_value *values, int *nr);
55 static t_selexpr_param *
56 process_param_list(t_selexpr_param *params);
58 static void
59 yyerror(yyscan_t, char const *s);
62 %union{
63 int i;
64 real r;
65 char *str;
66 struct gmx_ana_selmethod_t *meth;
68 struct t_selelem *sel;
70 struct t_selexpr_value *val;
71 struct t_selexpr_param *param;
74 /* Invalid token to report lexer errors */
75 %token INVALID
77 /* Tokens for help requests */
78 %token HELP
79 %token <str> HELP_TOPIC
81 /* Simple input tokens */
82 %token <i> TOK_INT
83 %token <r> TOK_REAL
84 %token <str> STR
85 %token <str> IDENTIFIER
86 %token CMD_SEP
88 /* Simple keyword tokens */
89 %token GROUP
90 %token TO
92 /* Variable tokens */
93 %token <sel> VARIABLE_NUMERIC
94 %token <sel> VARIABLE_GROUP
95 %token <sel> VARIABLE_POS
97 /* Selection method tokens */
98 %token <meth> KEYWORD_NUMERIC
99 %token <meth> KEYWORD_STR
100 %token <str> KEYWORD_POS
101 %token <meth> KEYWORD_GROUP
102 %token <meth> METHOD_NUMERIC
103 %token <meth> METHOD_GROUP
104 %token <meth> METHOD_POS
105 %token <meth> MODIFIER
106 /* Empty token that should precede any non-position KEYWORD/METHOD token that
107 * is not preceded by KEYWORD_POS. This is used to work around reduce/reduce
108 * conflicts that appear when a lookahead token would require a reduction of
109 * a rule with empty RHS before shifting, and there is an alternative reduction
110 * available. Replacing the empty RHS with a dummy token makes these conflicts
111 * only shift/reduce conflicts. Another alternative would be to remove the
112 * pos_mod non-terminal completely and split each rule that uses it into two,
113 * but this would require duplicating six rules in the grammar. */
114 %token EMPTY_POSMOD
116 %token <str> PARAM
117 %token END_OF_METHOD
119 %token OF
120 /* Comparison operators have lower precedence than parameter reduction
121 * to make it possible to parse, e.g., "mindist from resnr 1 < 2" without
122 * parenthesis. */
123 %nonassoc <str> CMP_OP
124 /* A dummy token that determines the precedence of parameter reduction */
125 %nonassoc PARAM_REDUCT
126 /* Boolean operator tokens */
127 %left AND OR XOR
128 %left NOT
129 /* Arithmetic operator tokens */
130 %left '+' '-'
131 %left '*' '/'
132 %left UNARY_NEG /* Dummy token for unary negation precedence */
133 %right '^'
135 /* Simple non-terminals */
136 %type <r> number
137 %type <str> string
138 %type <str> pos_mod
140 /* Expression non-terminals */
141 %type <sel> commands command cmd_plain
142 %type <sel> selection
143 %type <sel> sel_expr
144 %type <sel> num_expr
145 %type <sel> str_expr
146 %type <sel> pos_expr
148 /* Parameter/value non-terminals */
149 %type <param> method_params method_param_list method_param
150 %type <val> value_list value_list_nonempty value_item
152 %destructor { free($$); } HELP_TOPIC STR IDENTIFIER CMP_OP string
153 %destructor { if($$) free($$); } PARAM
154 %destructor { if($$) _gmx_selelem_free($$); } command cmd_plain
155 %destructor { _gmx_selelem_free_chain($$); } selection
156 %destructor { _gmx_selelem_free($$); } sel_expr num_expr str_expr pos_expr
157 %destructor { _gmx_selexpr_free_params($$); } method_params method_param_list method_param
158 %destructor { _gmx_selexpr_free_values($$); } value_list value_list_nonempty value_item
160 %expect 91
161 %debug
162 %pure-parser
164 /* If you change these, you also need to update the prototype in parsetree.c. */
165 %name-prefix="_gmx_sel_yyb"
166 %parse-param { yyscan_t scanner }
167 %lex-param { yyscan_t scanner }
171 /* The start rule: allow one or more commands */
172 commands: /* empty */ { $$ = NULL }
173 | commands command
175 $$ = _gmx_sel_append_selection($2, $1, scanner);
176 if (_gmx_sel_parser_should_finish(scanner))
177 YYACCEPT;
181 /* A command is formed from an actual command and a separator */
182 command: cmd_plain CMD_SEP { $$ = $1; }
183 | error CMD_SEP
185 $$ = NULL;
186 _gmx_selparser_error("invalid selection '%s'",
187 _gmx_sel_lexer_pselstr(scanner));
188 _gmx_sel_lexer_clear_method_stack(scanner);
189 if (_gmx_sel_is_lexer_interactive(scanner))
191 _gmx_sel_lexer_clear_pselstr(scanner);
192 yyerrok;
194 else
196 YYABORT;
201 /* Commands can be selections or variable assignments */
202 cmd_plain: /* empty */
204 $$ = NULL;
205 _gmx_sel_handle_empty_cmd(scanner);
207 | help_request { $$ = NULL; }
208 | TOK_INT
210 t_selelem *s, *p;
211 s = _gmx_sel_init_group_by_id($1, scanner);
212 if (s == NULL) YYERROR;
213 p = _gmx_sel_init_position(s, NULL, scanner);
214 if (p == NULL) YYERROR;
215 $$ = _gmx_sel_init_selection(strdup(s->name), p, scanner);
217 | string
219 t_selelem *s, *p;
220 s = _gmx_sel_init_group_by_name($1, scanner);
221 free($1);
222 if (s == NULL) YYERROR;
223 p = _gmx_sel_init_position(s, NULL, scanner);
224 if (p == NULL) YYERROR;
225 $$ = _gmx_sel_init_selection(strdup(s->name), p, scanner);
227 | selection
228 { $$ = _gmx_sel_init_selection(NULL, $1, scanner); }
229 | string selection
230 { $$ = _gmx_sel_init_selection($1, $2, scanner); }
231 | IDENTIFIER '=' sel_expr
232 { $$ = _gmx_sel_assign_variable($1, $3, scanner); }
233 | IDENTIFIER '=' num_expr
234 { $$ = _gmx_sel_assign_variable($1, $3, scanner); }
235 | IDENTIFIER '=' pos_expr
236 { $$ = _gmx_sel_assign_variable($1, $3, scanner); }
239 /* Help requests */
240 help_request:
241 HELP { _gmx_sel_handle_help_cmd(NULL, scanner); }
242 | help_topic
245 help_topic: HELP HELP_TOPIC { _gmx_sel_handle_help_cmd($2, scanner); }
246 | help_topic HELP_TOPIC { _gmx_sel_handle_help_cmd($2, scanner); }
249 /* Selection is made of an expression and zero or more modifiers */
250 selection: pos_expr { $$ = $1; }
251 | sel_expr
253 $$ = _gmx_sel_init_position($1, NULL, scanner);
254 if ($$ == NULL) YYERROR;
256 | '(' selection ')' { $$ = $2; }
257 | selection MODIFIER method_params
259 $$ = _gmx_sel_init_modifier($2, $3, $1, scanner);
260 if ($$ == NULL) YYERROR;
264 /********************************************************************
265 * BASIC NON-TERMINAL SYMBOLS
266 ********************************************************************/
268 number: TOK_INT { $$ = $1; }
269 | TOK_REAL { $$ = $1; }
272 string: STR { $$ = $1; }
273 | IDENTIFIER { $$ = $1; }
276 /********************************************************************
277 * ATOM SELECTION EXPRESSIONS
278 ********************************************************************/
280 /* Boolean expressions and grouping */
281 sel_expr: NOT sel_expr
283 $$ = _gmx_selelem_create(SEL_BOOLEAN);
284 $$->u.boolt = BOOL_NOT;
285 $$->child = $2;
287 | sel_expr AND sel_expr
289 $$ = _gmx_selelem_create(SEL_BOOLEAN);
290 $$->u.boolt = BOOL_AND;
291 $$->child = $1; $$->child->next = $3;
293 | sel_expr OR sel_expr
295 $$ = _gmx_selelem_create(SEL_BOOLEAN);
296 $$->u.boolt = BOOL_OR;
297 $$->child = $1; $$->child->next = $3;
299 /* | sel_expr XOR sel_expr
301 $$ = _gmx_selelem_create(SEL_BOOLEAN);
302 $$->u.boolt = BOOL_XOR;
303 $$->child = $1; $$->child->next = $3;
305 | '(' sel_expr ')' { $$ = $2; }
308 /* Numeric comparisons */
309 sel_expr: num_expr CMP_OP num_expr
311 $$ = _gmx_sel_init_comparison($1, $3, $2, scanner);
312 if ($$ == NULL) YYERROR;
316 /* External groups */
317 sel_expr: GROUP string
319 $$ = _gmx_sel_init_group_by_name($2, scanner);
320 free($2);
321 if ($$ == NULL) YYERROR;
323 | GROUP TOK_INT
325 $$ = _gmx_sel_init_group_by_id($2, scanner);
326 if ($$ == NULL) YYERROR;
330 /* Position modifiers for selection methods */
331 pos_mod: EMPTY_POSMOD { $$ = NULL; }
332 | KEYWORD_POS { $$ = $1; }
335 /* Keyword selections */
336 sel_expr: pos_mod KEYWORD_GROUP
338 $$ = _gmx_sel_init_keyword($2, NULL, $1, scanner);
339 if ($$ == NULL) YYERROR;
341 | pos_mod KEYWORD_STR value_list_nonempty
343 $$ = _gmx_sel_init_keyword($2, process_value_list($3, NULL), $1, scanner);
344 if ($$ == NULL) YYERROR;
346 | pos_mod KEYWORD_NUMERIC value_list_nonempty
348 $$ = _gmx_sel_init_keyword($2, process_value_list($3, NULL), $1, scanner);
349 if ($$ == NULL) YYERROR;
353 /* Custom selection methods */
354 sel_expr: pos_mod METHOD_GROUP method_params
356 $$ = _gmx_sel_init_method($2, $3, $1, scanner);
357 if ($$ == NULL) YYERROR;
361 /********************************************************************
362 * NUMERICAL EXPRESSIONS
363 ********************************************************************/
365 /* Basic numerical values */
366 num_expr: TOK_INT
368 $$ = _gmx_selelem_create(SEL_CONST);
369 _gmx_selelem_set_vtype($$, INT_VALUE);
370 _gmx_selvalue_reserve(&$$->v, 1);
371 $$->v.u.i[0] = $1;
373 | TOK_REAL
375 $$ = _gmx_selelem_create(SEL_CONST);
376 _gmx_selelem_set_vtype($$, REAL_VALUE);
377 _gmx_selvalue_reserve(&$$->v, 1);
378 $$->v.u.r[0] = $1;
382 /* Numeric selection methods */
383 num_expr: pos_mod KEYWORD_NUMERIC
385 $$ = _gmx_sel_init_keyword($2, NULL, $1, scanner);
386 if ($$ == NULL) YYERROR;
388 | pos_mod METHOD_NUMERIC method_params
390 $$ = _gmx_sel_init_method($2, $3, $1, scanner);
391 if ($$ == NULL) YYERROR;
395 /* Arithmetic evaluation and grouping */
396 num_expr: num_expr '+' num_expr
397 { $$ = _gmx_sel_init_arithmetic($1, $3, '+', scanner); }
398 | num_expr '-' num_expr
399 { $$ = _gmx_sel_init_arithmetic($1, $3, '-', scanner); }
400 | num_expr '*' num_expr
401 { $$ = _gmx_sel_init_arithmetic($1, $3, '*', scanner); }
402 | num_expr '/' num_expr
403 { $$ = _gmx_sel_init_arithmetic($1, $3, '/', scanner); }
404 | '-' num_expr %prec UNARY_NEG
405 { $$ = _gmx_sel_init_arithmetic($2, NULL, '-', scanner); }
406 | num_expr '^' num_expr
407 { $$ = _gmx_sel_init_arithmetic($1, $3, '^', scanner); }
408 | '(' num_expr ')' { $$ = $2; }
411 /********************************************************************
412 * STRING EXPRESSIONS
413 ********************************************************************/
415 str_expr: string
417 $$ = _gmx_selelem_create(SEL_CONST);
418 _gmx_selelem_set_vtype($$, STR_VALUE);
419 _gmx_selvalue_reserve(&$$->v, 1);
420 $$->v.u.s[0] = $1;
422 | pos_mod KEYWORD_STR
424 $$ = _gmx_sel_init_keyword($2, NULL, $1, scanner);
425 if ($$ == NULL) YYERROR;
429 /********************************************************************
430 * POSITION EXPRESSIONS
431 ********************************************************************/
433 /* Constant position expressions */
434 pos_expr: '(' number ',' number ',' number ')'
435 { $$ = _gmx_sel_init_const_position($2, $4, $6); }
438 /* Grouping of position expressions */
439 pos_expr: '(' pos_expr ')' { $$ = $2; }
442 /* Expressions with a position value */
443 pos_expr: METHOD_POS method_params
445 $$ = _gmx_sel_init_method($1, $2, NULL, scanner);
446 if ($$ == NULL) YYERROR;
450 /* Evaluation of positions using a keyword */
451 pos_expr: KEYWORD_POS OF sel_expr %prec PARAM_REDUCT
453 $$ = _gmx_sel_init_position($3, $1, scanner);
454 if ($$ == NULL) YYERROR;
458 /********************************************************************
459 * VARIABLES
460 ********************************************************************/
462 sel_expr: VARIABLE_GROUP
463 { $$ = _gmx_sel_init_variable_ref($1); }
466 num_expr: VARIABLE_NUMERIC
467 { $$ = _gmx_sel_init_variable_ref($1); }
470 pos_expr: VARIABLE_POS
471 { $$ = _gmx_sel_init_variable_ref($1); }
474 /********************************************************************
475 * METHOD PARAMETERS
476 ********************************************************************/
478 method_params:
479 method_param_list
480 { $$ = process_param_list($1); }
481 | method_param_list END_OF_METHOD
482 { $$ = process_param_list($1); }
485 method_param_list:
486 /* empty */ { $$ = NULL; }
487 | method_param_list method_param
488 { $2->next = $1; $$ = $2; }
491 method_param:
492 PARAM value_list
494 $$ = _gmx_selexpr_create_param($1);
495 $$->value = process_value_list($2, &$$->nval);
499 value_list: /* empty */ { $$ = NULL; }
500 | value_list_nonempty { $$ = $1; }
503 value_list_nonempty:
504 value_item { $$ = $1; }
505 | value_list_nonempty value_item
506 { $2->next = $1; $$ = $2; }
507 | value_list_nonempty ',' value_item
508 { $3->next = $1; $$ = $3; }
511 value_item: sel_expr %prec PARAM_REDUCT
512 { $$ = _gmx_selexpr_create_value_expr($1); }
513 | pos_expr %prec PARAM_REDUCT
514 { $$ = _gmx_selexpr_create_value_expr($1); }
515 | num_expr %prec PARAM_REDUCT
516 { $$ = _gmx_selexpr_create_value_expr($1); }
517 | str_expr %prec PARAM_REDUCT
518 { $$ = _gmx_selexpr_create_value_expr($1); }
519 | TOK_INT TO TOK_INT
521 $$ = _gmx_selexpr_create_value(INT_VALUE);
522 $$->u.i.i1 = $1; $$->u.i.i2 = $3;
524 | TOK_INT TO TOK_REAL
526 $$ = _gmx_selexpr_create_value(REAL_VALUE);
527 $$->u.r.r1 = $1; $$->u.r.r2 = $3;
529 | TOK_REAL TO number
531 $$ = _gmx_selexpr_create_value(REAL_VALUE);
532 $$->u.r.r1 = $1; $$->u.r.r2 = $3;
538 static t_selexpr_value *
539 process_value_list(t_selexpr_value *values, int *nr)
541 t_selexpr_value *val, *pval, *nval;
543 /* Count values (if needed) and reverse list */
544 if (nr)
546 *nr = 0;
548 pval = NULL;
549 val = values;
550 while (val)
552 if (nr)
554 ++*nr;
556 nval = val->next;
557 val->next = pval;
558 pval = val;
559 val = nval;
561 values = pval;
563 return values;
566 static t_selexpr_param *
567 process_param_list(t_selexpr_param *params)
569 t_selexpr_param *par, *ppar, *npar;
571 /* Reverse list */
572 ppar = NULL;
573 par = params;
574 while (par)
576 npar = par->next;
577 par->next = ppar;
578 ppar = par;
579 par = npar;
581 params = ppar;
583 return params;
586 static void
587 yyerror(yyscan_t scanner, char const *s)
589 _gmx_selparser_error("%s", s);