3 * This source code is part of
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
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.
47 #include "parsetree.h"
52 static t_selexpr_value
*
53 process_value_list
(t_selexpr_value
*values
, int *nr
);
54 static t_selexpr_param
*
55 process_param_list
(t_selexpr_param
*params
);
58 yyerror(yyscan_t
, char const *s
);
65 struct gmx_ana_selmethod_t
*meth
;
67 struct t_selelem
*sel
;
69 struct t_selexpr_value
*val
;
70 struct t_selexpr_param
*param
;
73 /* Invalid token to report lexer errors */
76 /* Tokens for help requests */
78 %token
<str
> HELP_TOPIC
80 /* Simple input tokens */
84 %token
<str
> IDENTIFIER
87 /* Simple keyword tokens */
92 %token
<sel
> VARIABLE_NUMERIC
93 %token
<sel
> VARIABLE_GROUP
94 %token
<sel
> VARIABLE_POS
96 /* Selection method tokens */
97 %token
<meth
> KEYWORD_NUMERIC
98 %token
<meth
> KEYWORD_STR
99 %token
<str
> KEYWORD_POS
100 %token
<meth
> KEYWORD_GROUP
101 %token
<meth
> METHOD_NUMERIC
102 %token
<meth
> METHOD_GROUP
103 %token
<meth
> METHOD_POS
104 %token
<meth
> MODIFIER
106 %token
<str
> PARAM_BASIC
107 %token
<str
> PARAM_EXPR
110 /* Simple tokens with precedence */
112 /* A dummy token that determines the precedence of parameter reduction */
113 %nonassoc PARAM_REDUCT
115 /* Operator tokens */
118 %nonassoc
<str
> CMP_OP
120 /* Simple non-terminals */
125 /* Expression non-terminals */
126 %type
<sel
> commands command cmd_plain
127 %type
<sel
> selection
132 /* Parameter/value non-terminals */
133 %type
<param
> method_params method_param_list method_param
134 %type
<val
> value_list value_list_nonempty value_item
136 %destructor
{ free
($$
); } HELP_TOPIC STR IDENTIFIER
string
137 %destructor
{ if
($$
) free
($$
); } PARAM_BASIC PARAM_EXPR
138 %destructor
{ if
($$
) _gmx_selelem_free
($$
); } command cmd_plain
139 %destructor
{ _gmx_selelem_free_chain
($$
); } selection
140 %destructor
{ _gmx_selelem_free
($$
); } sel_expr num_expr
141 %destructor
{ _gmx_selelem_free
($$
); } pos_expr
142 %destructor
{ _gmx_selexpr_free_params
($$
); } method_params method_param_list method_param
143 %destructor
{ _gmx_selexpr_free_values
($$
); } value_list value_list_nonempty value_item
149 /* If you change these, you also need to update the prototype in parsetree.c. */
150 %name
-prefix
="_gmx_sel_yy"
151 %parse
-param
{ yyscan_t scanner
}
152 %lex
-param
{ yyscan_t scanner
}
156 /* The start rule: allow one or more commands */
157 commands: /* empty */ { $$
= NULL
}
160 $$
= _gmx_sel_append_selection
($2, $1, scanner
);
161 if
(_gmx_sel_parser_should_finish
(scanner
))
166 /* A command is formed from an actual command and a separator */
167 command: cmd_plain CMD_SEP
{ $$
= $1; }
171 _gmx_selparser_error
("invalid selection '%s'",
172 _gmx_sel_lexer_pselstr
(scanner
));
173 if
(_gmx_sel_is_lexer_interactive
(scanner
))
175 _gmx_sel_lexer_clear_pselstr
(scanner
);
185 /* Commands can be selections or variable assignments */
186 cmd_plain: /* empty */
189 _gmx_sel_handle_empty_cmd
(scanner
);
191 | help_request
{ $$
= NULL
; }
195 s
= _gmx_sel_init_group_by_id
($1, scanner
);
196 if
(s
== NULL
) YYERROR;
197 p
= _gmx_sel_init_position
(s
, NULL
, scanner
);
198 if
(p
== NULL
) YYERROR;
199 $$
= _gmx_sel_init_selection
(strdup
(s
->name
), p
, scanner
);
204 s
= _gmx_sel_init_group_by_name
($1, scanner
);
206 if
(s
== NULL
) YYERROR;
207 p
= _gmx_sel_init_position
(s
, NULL
, scanner
);
208 if
(p
== NULL
) YYERROR;
209 $$
= _gmx_sel_init_selection
(strdup
(s
->name
), p
, scanner
);
212 { $$
= _gmx_sel_init_selection
(NULL
, $1, scanner
); }
214 { $$
= _gmx_sel_init_selection
($1, $2, scanner
); }
215 | IDENTIFIER
'=' sel_expr
216 { $$
= _gmx_sel_assign_variable
($1, $3, scanner
); }
217 | IDENTIFIER
'=' num_expr
218 { $$
= _gmx_sel_assign_variable
($1, $3, scanner
); }
219 | IDENTIFIER
'=' pos_expr
220 { $$
= _gmx_sel_assign_variable
($1, $3, scanner
); }
225 HELP
{ _gmx_sel_handle_help_cmd
(NULL
, scanner
); }
229 help_topic: HELP HELP_TOPIC
{ _gmx_sel_handle_help_cmd
($2, scanner
); }
230 | help_topic HELP_TOPIC
{ _gmx_sel_handle_help_cmd
($2, scanner
); }
233 /* Selection is made of an expression and zero or more modifiers */
234 selection: pos_expr
{ $$
= $1; }
237 $$
= _gmx_sel_init_position
($1, NULL
, scanner
);
238 if
($$
== NULL
) YYERROR;
240 |
'(' selection
')' { $$
= $2; }
241 | selection MODIFIER method_params
243 $$
= _gmx_sel_init_modifier
($2, process_param_list
($3), $1, scanner
);
244 _gmx_sel_finish_method
(scanner
);
248 /********************************************************************
249 * BASIC NON-TERMINAL SYMBOLS
250 ********************************************************************/
252 number: INTEGER
{ $$
= $1; }
256 string: STR
{ $$
= $1; }
257 | IDENTIFIER
{ $$
= $1; }
260 /********************************************************************
261 * ATOM SELECTION EXPRESSIONS
262 ********************************************************************/
264 /* Boolean expressions and grouping */
265 sel_expr: NOT sel_expr
267 $$
= _gmx_selelem_create
(SEL_BOOLEAN
);
268 $$
->u.boolt
= BOOL_NOT
;
271 | sel_expr AND sel_expr
273 $$
= _gmx_selelem_create
(SEL_BOOLEAN
);
274 $$
->u.boolt
= BOOL_AND
;
275 $$
->child
= $1; $$
->child
->next
= $3;
277 | sel_expr OR sel_expr
279 $$
= _gmx_selelem_create
(SEL_BOOLEAN
);
280 $$
->u.boolt
= BOOL_OR
;
281 $$
->child
= $1; $$
->child
->next
= $3;
283 /* | sel_expr XOR sel_expr
285 $$ = _gmx_selelem_create(SEL_BOOLEAN);
286 $$->u.boolt = BOOL_XOR;
287 $$->child = $1; $$->child->next = $3;
289 |
'(' sel_expr
')' { $$
= $2; }
292 /* Numeric comparisons */
293 sel_expr: num_expr CMP_OP num_expr
295 $$
= _gmx_sel_init_comparison
($1, $3, $2, scanner
);
296 if
($$
== NULL
) YYERROR;
300 /* External groups */
301 sel_expr: GROUP
string
303 $$
= _gmx_sel_init_group_by_name
($2, scanner
);
305 if
($$
== NULL
) YYERROR;
309 $$
= _gmx_sel_init_group_by_id
($2, scanner
);
310 if
($$
== NULL
) YYERROR;
314 /* Position modifiers for selection methods */
315 pos_mod: /* empty */ { $$
= NULL
; }
316 | KEYWORD_POS
{ $$
= $1; }
319 /* Keyword selections */
320 sel_expr: pos_mod KEYWORD_GROUP
322 $$
= _gmx_sel_init_keyword
($2, NULL
, $1, scanner
);
323 if
($$
== NULL
) YYERROR;
325 | pos_mod KEYWORD_STR value_list_nonempty
327 $$
= _gmx_sel_init_keyword
($2, process_value_list
($3, NULL
), $1, scanner
);
328 if
($$
== NULL
) YYERROR;
330 | pos_mod KEYWORD_NUMERIC value_list_nonempty
332 $$
= _gmx_sel_init_keyword
($2, process_value_list
($3, NULL
), $1, scanner
);
333 if
($$
== NULL
) YYERROR;
337 /* Custom selection methods */
338 sel_expr: pos_mod METHOD_GROUP method_params
340 $$
= _gmx_sel_init_method
($2, process_param_list
($3), $1, scanner
);
341 if
($$
== NULL
) YYERROR;
342 _gmx_sel_finish_method
(scanner
);
346 /********************************************************************
347 * NUMERICAL EXPRESSIONS
348 ********************************************************************/
350 /* Basic numerical values */
353 $$
= _gmx_selelem_create
(SEL_CONST
);
354 _gmx_selelem_set_vtype
($$
, INT_VALUE
);
355 _gmx_selvalue_reserve
(&$$
->v
, 1);
360 $$
= _gmx_selelem_create
(SEL_CONST
);
361 _gmx_selelem_set_vtype
($$
, REAL_VALUE
);
362 _gmx_selvalue_reserve
(&$$
->v
, 1);
367 /* Numeric selection methods */
368 num_expr: pos_mod KEYWORD_NUMERIC
370 $$
= _gmx_sel_init_keyword
($2, NULL
, $1, scanner
);
371 if
($$
== NULL
) YYERROR;
373 | pos_mod METHOD_NUMERIC method_params
375 $$
= _gmx_sel_init_method
($2, process_param_list
($3), $1, scanner
);
376 if
($$
== NULL
) YYERROR;
377 _gmx_sel_finish_method
(scanner
);
381 /* Grouping of numeric expressions */
382 num_expr: '(' num_expr
')' { $$
= $2; }
385 /********************************************************************
386 * POSITION EXPRESSIONS
387 ********************************************************************/
389 /* Constant position expressions */
390 pos_expr: '(' number
',' number
',' number
')'
391 { $$
= _gmx_sel_init_const_position
($2, $4, $6); }
394 /* Grouping of position expressions */
395 pos_expr: '(' pos_expr
')' { $$
= $2; }
398 /* Expressions with a position value */
399 pos_expr: METHOD_POS method_params
401 $$
= _gmx_sel_init_method
($1, process_param_list
($2), NULL
, scanner
);
402 if
($$
== NULL
) YYERROR;
403 _gmx_sel_finish_method
(scanner
);
407 /* Evaluation of positions using a keyword */
408 pos_expr: KEYWORD_POS OF sel_expr
410 $$
= _gmx_sel_init_position
($3, $1, scanner
);
411 if
($$
== NULL
) YYERROR;
415 /********************************************************************
417 ********************************************************************/
419 sel_expr: VARIABLE_GROUP
420 { $$
= _gmx_sel_init_variable_ref
($1); }
423 num_expr: VARIABLE_NUMERIC
424 { $$
= _gmx_sel_init_variable_ref
($1); }
427 pos_expr: VARIABLE_POS
428 { $$
= _gmx_sel_init_variable_ref
($1); }
431 /********************************************************************
433 ********************************************************************/
436 method_param_list
{ $$
= $1; }
437 | method_param_list END_OF_METHOD
{ $$
= $1; }
441 /* empty */ { $$
= NULL
; }
442 | method_param_list method_param
443 { $2->next
= $1; $$
= $2; }
447 PARAM_BASIC value_list
449 $$
= _gmx_selexpr_create_param
($1);
450 $$
->value
= process_value_list
($2, &$$
->nval
);
452 | PARAM_EXPR pos_expr %prec PARAM_REDUCT
454 $$
= _gmx_selexpr_create_param
($1);
456 $$
->value
= _gmx_selexpr_create_value_expr
($2);
458 | PARAM_EXPR sel_expr %prec PARAM_REDUCT
460 $$
= _gmx_selexpr_create_param
($1);
462 $$
->value
= _gmx_selexpr_create_value_expr
($2);
466 value_list: /* empty */ { $$
= NULL
; }
467 | value_list_nonempty
{ $$
= $1; }
471 value_item
{ $$
= $1; }
472 | value_list_nonempty value_item
{ $2->next
= $1; $$
= $2; }
477 $$
= _gmx_selexpr_create_value
(INT_VALUE
);
478 $$
->u.i.i1
= $$
->u.i.i2
= $1;
482 $$
= _gmx_selexpr_create_value
(REAL_VALUE
);
483 $$
->u.r.r1
= $$
->u.r.r2
= $1;
487 $$
= _gmx_selexpr_create_value
(INT_VALUE
);
488 $$
->u.i.i1
= $1; $$
->u.i.i2
= $3;
492 $$
= _gmx_selexpr_create_value
(REAL_VALUE
);
493 $$
->u.r.r1
= $1; $$
->u.r.r2
= $3;
497 $$
= _gmx_selexpr_create_value
(REAL_VALUE
);
498 $$
->u.r.r1
= $1; $$
->u.r.r2
= $3;
502 $$
= _gmx_selexpr_create_value
(STR_VALUE
);
509 static t_selexpr_value
*
510 process_value_list
(t_selexpr_value
*values
, int *nr
)
512 t_selexpr_value
*val
, *pval
, *nval
;
514 /* Count values (if needed) and reverse list */
537 static t_selexpr_param
*
538 process_param_list
(t_selexpr_param
*params
)
540 t_selexpr_param
*par
, *ppar
, *npar
;
558 yyerror(yyscan_t scanner
, char const *s
)
560 _gmx_selparser_error
("%s", s
);