/* * 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; import java.util.ArrayDeque; /** * @author Santhosh Kumar Tekuri */ public interface Expression{ public Object evaluate(Object root, Object current); public default Object evaluate(Object root){ return evaluate(root, root); } public static Expression compile(String expression) throws ParseException{ return ExpressionParser.compile(expression); } } class Compiler{ private enum Type{ EOF, WHITESPACE, STRING, IDENTIFIER, DOT, OPEN_BRACE, CLOSE_BRACE } private ArrayDeque<ArrayDeque> frames = new ArrayDeque<>(); public Expression compile(String string){ CharBuffer buffer = CharBuffer.wrap(string.toCharArray()); while(true){ Type type = parseToken(buffer); if(type==Type.EOF) return (Expression)frames.pop().pop(); } } private StringBuilder token = new StringBuilder(); private Type parseToken(CharBuffer buffer){ token.setLength(0); if(buffer.hasRemaining()){ char ch = buffer.get(); if(Character.isWhitespace(ch)){ token.append(ch); while(buffer.hasRemaining()){ ch = buffer.get(); if(Character.isWhitespace(ch)) token.append(ch); else{ buffer.position(buffer.position()-1); break; } } return Type.WHITESPACE; }else if(ch=='\''){ while(true){ ch = buffer.get(); if(ch=='\'') break; token.append(ch); } return Type.STRING; }else if(ch=='.') return Type.DOT; else if(ch=='[') return Type.OPEN_BRACE; else if(ch==']') return Type.CLOSE_BRACE; else if(Character.isJavaIdentifierStart(ch)){ token.append(ch); while(buffer.hasRemaining()){ ch = buffer.get(); if(Character.isJavaIdentifierPart(ch)) token.append(ch); else{ buffer.position(buffer.position()-1); break; } } return Type.IDENTIFIER; }else throw new IllegalArgumentException(); }else return Type.EOF; } }