1 46 47 package org.codehaus.groovy.syntax.parser; 48 49 import java.util.ArrayList ; 50 51 import org.codehaus.groovy.control.CompilationFailedException; 52 import org.codehaus.groovy.syntax.*; 53 import org.codehaus.groovy.GroovyBugError; 54 55 56 57 66 67 public class ExpressionStack 68 { 69 private ArrayList stack = new ArrayList (); 70 private Parser parser = null; 71 private int open = 0; 72 73 74 ExpressionStack( Parser context ) 75 { 76 this.parser = context; 77 } 78 79 80 81 84 85 88 89 boolean isEmpty() 90 { 91 return stack.isEmpty(); 92 } 93 94 95 96 100 101 public boolean isComplete() 102 { 103 return size() == 1 && topIsAnExpression(); 104 } 105 106 107 108 114 115 public boolean canComplete() 116 { 117 121 if( open > 0 || !topIsAnExpression() ) 122 { 123 return false; 124 } 125 126 127 130 if( size() == 1 ) 131 { 132 return true; 133 } 134 135 136 147 return true; 148 } 149 150 151 152 155 156 int size() 157 { 158 return stack.size(); 159 } 160 161 162 163 166 167 void push( CSTNode node ) 168 { 169 if( (node.isA(Types.LEFT_PARENTHESIS) || node.isA(Types.QUESTION)) && node.size() == 1 ) 170 { 171 open++; 172 } 173 174 stack.add( node ); 175 } 176 177 178 179 182 183 CSTNode pop() 184 { 185 CSTNode node = (CSTNode)stack.remove( stack.size() - 1 ); 186 187 if( (node.isA(Types.LEFT_PARENTHESIS) || node.isA(Types.QUESTION)) && node.size() == 1 ) 188 { 189 open--; 190 } 191 192 return node; 193 } 194 195 196 197 200 201 CSTNode top() 202 { 203 return top(0); 204 } 205 206 207 208 212 213 CSTNode top( int offset ) 214 { 215 if( offset < stack.size() ) 216 { 217 return (CSTNode)stack.get( stack.size() - 1 - offset ); 218 } 219 else 220 { 221 return Token.NULL; 222 } 223 } 224 225 226 227 228 231 232 236 237 void shift( int count ) throws SyntaxException, CompilationFailedException 238 { 239 for( int i = 0; i < count; i++ ) 240 { 241 push( parser.consume() ); 242 } 243 } 244 245 246 247 250 251 void shift() throws SyntaxException, CompilationFailedException 252 { 253 push( parser.consume() ); 254 } 255 256 257 258 264 265 void reduce( int count, int rootOffset, boolean mark ) 266 { 267 if( count <= rootOffset || rootOffset < 0 || count > size() ) 268 { 269 throw new GroovyBugError( "error in call to ExpressionStack.reduce(): count=" + count + ", rootOffset=" + rootOffset ); 270 } 271 272 CSTNode root = null; 273 CSTNode[] children = new CSTNode[count-1]; 274 275 for( int child = count - 2, element = 0; element < count; element++ ) 276 { 277 if( element == rootOffset ) 278 { 279 root = pop(); 280 } 281 else 282 { 283 children[child--] = pop(); 284 } 285 } 286 287 root = root.asReduction(); 288 for( int i = 0; i < children.length; i++ ) 289 { 290 root.add( children[i] ); 291 } 292 293 if( mark ) 294 { 295 root.markAsExpression(); 296 } 297 298 push( root ); 299 300 } 301 302 303 304 305 308 309 313 314 boolean atStartOfExpression() 315 { 316 return isEmpty() || (top().isA(Types.LEFT_PARENTHESIS) && !top().hasChildren()); 317 } 318 319 320 321 324 325 boolean topIsAnOperator( ) 326 { 327 return ExpressionSupport.isAnOperator( top(), false ); 328 } 329 330 331 332 336 337 boolean topIsAnOperator( int offset, boolean unknownReturns ) 338 { 339 return ExpressionSupport.isAnOperator( top(offset), unknownReturns ); 340 } 341 342 343 344 347 348 boolean topIsAModifiableExpression() 349 { 350 return ExpressionSupport.isAModifiableExpression( top() ); 351 } 352 353 354 355 358 359 boolean topIsAnExpression( ) 360 { 361 return top().isAnExpression(); 362 } 363 364 365 366 369 370 373 374 void shiftIf( boolean flag, String error ) throws SyntaxException, CompilationFailedException 375 { 376 if( flag ) 377 { 378 push( parser.consume() ); 379 } 380 else 381 { 382 parser.error( error ); 383 } 384 } 385 386 387 388 391 392 void shiftUnless( boolean flag, String error ) throws SyntaxException, CompilationFailedException 393 { 394 if( flag ) 395 { 396 parser.error( error ); 397 } 398 else 399 { 400 push( parser.consume() ); 401 } 402 } 403 404 405 406 410 411 void shiftIfTopIsAnExpression( String error ) throws SyntaxException, CompilationFailedException 412 { 413 shiftIf( ExpressionSupport.isAnExpression(top(), false), error ); 414 } 415 416 417 418 422 423 void shiftIfTopIsAnOperator( String error ) throws SyntaxException, CompilationFailedException 424 { 425 shiftIf( ExpressionSupport.isAnOperator(top(), false), error ); 426 } 427 428 429 430 434 435 void shiftUnlessTopIsAnExpression( String error ) throws SyntaxException, CompilationFailedException 436 { 437 shiftUnless( ExpressionSupport.isAnExpression(top(), false), error ); 438 } 439 440 441 442 446 447 void shiftUnlessTopIsAnOperator( String error ) throws SyntaxException, CompilationFailedException 448 { 449 shiftUnless( ExpressionSupport.isAnOperator(top(), false), error ); 450 } 451 452 453 454 455 458 459 462 463 public String toString( ) 464 { 465 StringBuffer buffer = new StringBuffer (); 466 String newline = System.getProperty( "line.separator", "\n" ); 467 int count = stack.size(); 468 469 buffer.append( "ExpressionStack with " ).append( size() ).append( " elements" ).append( newline ); 470 for( int i = count - 1; i >= 0; i-- ) 471 { 472 buffer.append( top(i).toString() ).append( newline ); 473 } 474 475 return buffer.toString(); 476 } 477 478 } 479 | Popular Tags |