ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CexmcCustomFilter.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file CexmcCustomFilter.cc
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 /*
27  * =============================================================================
28  *
29  * Filename: CexmcCustomFilter.cc
30  *
31  * Description: custom filter grammar and compiler
32  *
33  * Version: 1.0
34  * Created: 17.07.2010 15:37:38
35  * Revision: none
36  * Compiler: gcc
37  *
38  * Author: Alexey Radkov (),
39  * Company: PNPI
40  *
41  * =============================================================================
42  */
43 
44 #ifdef CEXMC_USE_CUSTOM_FILTER
45 
46 #include "CexmcCustomFilter.hh"
47 
48 
49 namespace CexmcCustomFilter
50 {
51  void Compiler::operator()( ParseResult & parseResult, Action value )
52  const
53  {
54  parseResult.action = value;
55  }
56 
57 
58  void Compiler::operator()( ParseResult & parseResult, Subtree & value )
59  const
60  {
61  parseResult.expression = value;
62  }
63 
64 
65  void Compiler::operator()( Subtree & ast, Node & node ) const
66  {
67  try
68  {
69  ast = boost::get< Subtree >( node );
70  }
71  catch ( const boost::bad_get & )
72  {
73  ast.type = Operator( Top );
74  ast.children.push_back( node );
75  }
76  }
77 
78 
79  void Compiler::operator()( Node & self, Node & left, Node & right,
80  Operator value ) const
81  {
82  Subtree & ast( boost::get< Subtree >( self ) );
83 
84  ast.children.push_back( left );
85  ast.type = value;
86 
87  Subtree * astRight( boost::get< Subtree >( &right ) );
88 
89  if ( ! astRight )
90  {
91  ast.children.push_back( right );
92  return;
93  }
94 
95  bool haveSamePriorities( false );
96  Operator * rightOp( boost::get< Operator >( &astRight->type ) );
97 
98  if ( rightOp )
99  haveSamePriorities = value.priority == rightOp->priority;
100 
101  if ( value.hasRLAssoc || ! haveSamePriorities )
102  {
103  ast.children.push_back( right );
104  return;
105  }
106 
107  Subtree * astDeepestRight( astRight );
108 
109  /* propagate left binary operators with LR associativity (i.e. all in
110  * our grammar) deep into the AST until any operator with a different
111  * priority (which includes operators in parentheses that have priority
112  * 0) or a unary operator or a function occured */
113  while ( true )
114  {
115  Subtree * candidate = boost::get< Subtree >(
116  &astDeepestRight->children[ 0 ] );
117  if ( ! candidate )
118  break;
119 
120  if ( candidate->children.size() < 2 )
121  break;
122 
123  bool haveSamePriorities_( false );
124  Operator * candidateOp( boost::get< Operator >(
125  &candidate->type ) );
126 
127  if ( candidateOp )
128  haveSamePriorities_ = value.priority == candidateOp->priority;
129 
130  /* FIXME: what to do if candidate has RL association? Our grammar is
131  * not a subject of this issue; probably no grammar is a subject */
132  if ( ! haveSamePriorities_ )
133  break;
134 
135  astDeepestRight = candidate;
136  }
137 
138  Subtree astResult;
139  astResult.children.push_back( ast.children[ 0 ] );
140  astResult.children.push_back( astDeepestRight->children[ 0 ] );
141  astResult.type = value;
142  astDeepestRight->children[ 0 ] = astResult;
143  self = right;
144  }
145 
146 
147  void Compiler::operator()( Node & self, Node & child, Operator value )
148  const
149  {
150  Subtree & ast( boost::get< Subtree >( self ) );
151  ast.children.push_back( child );
152  ast.type = value;
153  }
154 
155 
156  void Compiler::operator()( Node & self, Node & primary ) const
157  {
158  self = primary;
159 
160  Subtree * ast( boost::get< Subtree >( &self ) );
161 
162  if ( ! ast )
163  return;
164 
165  Operator * op( boost::get< Operator >( &ast->type ) );
166 
167  if ( op )
168  op->priority = 0;
169  }
170 
171 
172  void Compiler::operator()( Node & self, Node & child,
173  std::string & value ) const
174  {
175  Subtree & ast( boost::get< Subtree >( self ) );
176 
177  ast.children.push_back( child );
178  ast.type = value;
179  }
180 
181 
182  void Compiler::operator()( Leaf & self, std::string & name ) const
183  {
184  Variable & variable( boost::get< Variable >( self ) );
185  variable.name = name;
186  }
187 
188 
189  void Compiler::operator()( Leaf & self, int value, size_t index ) const
190  {
191  Variable & variable( boost::get< Variable >( self ) );
192  switch ( index )
193  {
194  case 0 :
195  variable.index1 = value;
196  break;
197  case 1 :
198  variable.index2 = value;
199  break;
200  default :
201  break;
202  }
203  }
204 }
205 
206 #endif
207