2009/04/15 - Apache HiveMind has been retired.

For more information, please explore the Attic.

Clover coverage report - Code Coverage for hivemind release 1.2.1
Coverage timestamp: Fri Feb 10 2006 16:33:43 PST
file stats: LOC: 194   Methods: 8
NCLOC: 117   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
Parser.java 100% 100% 100% 100%
coverage
 1    // Copyright 2004, 2005 The Apache Software Foundation
 2    //
 3    // Licensed under the Apache License, Version 2.0 (the "License");
 4    // you may not use this file except in compliance with the License.
 5    // You may obtain a copy of the License at
 6    //
 7    // http://www.apache.org/licenses/LICENSE-2.0
 8    //
 9    // Unless required by applicable law or agreed to in writing, software
 10    // distributed under the License is distributed on an "AS IS" BASIS,
 11    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12    // See the License for the specific language governing permissions and
 13    // limitations under the License.
 14   
 15    package org.apache.hivemind.conditional;
 16   
 17    import org.apache.hivemind.util.Defense;
 18   
 19    /**
 20    * Parser for conditional expressions. This class is not threadsafe; it is inexpensive to create,
 21    * however, and can be discarded after parsing one or more expressions.
 22    *
 23    * @author Howard M. Lewis Ship
 24    * @since 1.1
 25    */
 26    public class Parser
 27    {
 28    private String _input;
 29   
 30    private Lexer _lexer;
 31   
 32    private Token _nextToken;
 33   
 34    private boolean _onDeck;
 35   
 36    // No reason to have multiple instances of these, since they are always
 37    // identical (one of the advantages of the NodeImpl being purely structural.
 38   
 39    private static final Evaluator NOT_EVALUATOR = new NotEvaluator();
 40   
 41    private static final Evaluator OR_EVALUATOR = new OrEvaluator();
 42   
 43    private static final Evaluator AND_EVALUATOR = new AndEvaluator();
 44   
 45  12 public Node parse(String input)
 46    {
 47  12 Defense.notNull(input, "input");
 48   
 49  12 try
 50    {
 51  12 _input = input;
 52  12 _lexer = new Lexer(input);
 53   
 54  12 Node result = expression();
 55   
 56  8 Token token = next();
 57   
 58  8 if (token != null)
 59  1 throw new RuntimeException(ConditionalMessages.unparsedToken(token, _input));
 60   
 61  7 return result;
 62    }
 63    finally
 64    {
 65  12 _input = null;
 66  12 _nextToken = null;
 67  12 _lexer = null;
 68  12 _onDeck = false;
 69    }
 70    }
 71   
 72  44 private Token next()
 73    {
 74  44 Token result = _onDeck ? _nextToken : _lexer.next();
 75   
 76  44 _onDeck = false;
 77  44 _nextToken = null;
 78   
 79  44 return result;
 80    }
 81   
 82  17 private Token match(TokenType expected)
 83    {
 84  17 Token actual = next();
 85   
 86  17 if (actual == null)
 87  1 throw new RuntimeException(ConditionalMessages.unexpectedEndOfInput(_input));
 88   
 89  16 if (actual.getType() != expected)
 90  1 throw new RuntimeException(ConditionalMessages.unexpectedToken(expected, actual
 91    .getType(), _input));
 92   
 93  15 return actual;
 94    }
 95   
 96  79 private Token peek()
 97    {
 98  79 if (! _onDeck)
 99    {
 100  30 _nextToken = _lexer.next();
 101  30 _onDeck = true;
 102    }
 103   
 104  79 return _nextToken;
 105    }
 106   
 107  79 private TokenType peekType()
 108    {
 109  79 Token next = peek();
 110   
 111  79 return next == null ? null : next.getType();
 112    }
 113   
 114  79 private boolean isPeek(TokenType type)
 115    {
 116  79 return peekType() == type;
 117    }
 118   
 119  17 private Node expression()
 120    {
 121  17 Node lnode = term();
 122   
 123  13 if (isPeek(TokenType.OR))
 124    {
 125  1 next();
 126   
 127  1 Node rnode = expression();
 128   
 129  1 return new NodeImpl(lnode, rnode, OR_EVALUATOR);
 130    }
 131   
 132  12 if (isPeek(TokenType.AND))
 133    {
 134  1 next();
 135   
 136  1 Node rnode = expression();
 137   
 138  1 return new NodeImpl(lnode, rnode, AND_EVALUATOR);
 139    }
 140   
 141  11 return lnode;
 142    }
 143   
 144  17 private Node term()
 145    {
 146  17 if (isPeek(TokenType.OPAREN))
 147    {
 148  1 next();
 149   
 150  1 Node result = expression();
 151   
 152  1 match(TokenType.CPAREN);
 153   
 154  1 return result;
 155    }
 156   
 157  16 if (isPeek(TokenType.NOT))
 158    {
 159  3 next();
 160   
 161  3 match(TokenType.OPAREN);
 162   
 163  2 Node expression = expression();
 164   
 165  2 match(TokenType.CPAREN);
 166   
 167  1 return new NodeImpl(expression, null, NOT_EVALUATOR);
 168    }
 169   
 170  13 if (isPeek(TokenType.PROPERTY))
 171    {
 172  5 next();
 173   
 174  5 Token symbolToken = match(TokenType.SYMBOL);
 175   
 176  5 Evaluator ev = new PropertyEvaluator(symbolToken.getValue());
 177   
 178  5 return new NodeImpl(ev);
 179    }
 180   
 181  8 if (isPeek(TokenType.CLASS))
 182    {
 183  6 next();
 184   
 185  6 Token symbolToken = match(TokenType.SYMBOL);
 186   
 187  6 Evaluator ev = new ClassNameEvaluator(symbolToken.getValue());
 188   
 189  6 return new NodeImpl(ev);
 190    }
 191   
 192  2 throw new RuntimeException(ConditionalMessages.unparsedToken(next(), _input));
 193    }
 194    }