/* * JLibs: Common Utilities for Java * Copyright (C) 2009 Santhosh Kumar T <santhosh.tekuri@gmail.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package jlibs.nio.http.expr; import java.nio.CharBuffer; import java.text.ParseException; /** * @author Santhosh Kumar Tekuri */ class ExpressionParser{ public static Expression compile(String str) throws ParseException{ CharBuffer buffer = CharBuffer.wrap(str.toCharArray()); skipWhitespace(buffer); Expression expr = parseValue(buffer); skipWhitespace(buffer); if(buffer.hasRemaining()) throw new ParseException("invalid expression", buffer.position()); return expr; } private static Expression parseValue(CharBuffer buffer) throws ParseException{ char ch = buffer.get(buffer.position()); if(ch=='\'') return parseString(buffer); else{ Variable var = new Variable(); var.children.add(new GetField(parseIdentifier(buffer))); skipWhitespace(buffer); while(buffer.hasRemaining()){ ch = buffer.get(buffer.position()); if(ch=='.'){ buffer.get(); skipWhitespace(buffer); var.children.add(new GetField(parseIdentifier(buffer))); }else if(ch=='['){ buffer.get(); skipWhitespace(buffer); var.children.add(new Lookup(parseValue(buffer))); skipWhitespace(buffer); if(buffer.get()!=']') throw new ParseException("expected ]", buffer.position()-1); }else break; } return var; } } private static Literal parseString(CharBuffer buffer) throws ParseException{ buffer.get(); StringBuilder builder = new StringBuilder(); while(true){ if(buffer.hasRemaining()){ char ch = buffer.get(); if(ch=='\'') break; builder.append(ch); }else throw new ParseException("Unexpected EOF", buffer.position()); } return new Literal(builder.toString()); } private static String parseIdentifier(CharBuffer buffer) throws ParseException{ if(!buffer.hasRemaining()) throw new ParseException("Unexpected EOF", buffer.position()); StringBuilder builder = new StringBuilder(); char ch = buffer.get(); if(!Character.isJavaIdentifierStart(ch)) throw new ParseException("Invalid Identifier", buffer.position()-1); builder.append(ch); while(buffer.hasRemaining()){ ch = buffer.get(); if(Character.isJavaIdentifierPart(ch)) builder.append(ch); else{ buffer.position(buffer.position()-1); break; } } return builder.toString(); } private static void skipWhitespace(CharBuffer buffer){ while(buffer.hasRemaining()){ if(!Character.isWhitespace(buffer.get())){ buffer.position(buffer.position()-1); break; } } } }