Geant4 Cross Reference |
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 208