elparser.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 883 行 · 第 1/2 页

JAVA
883
字号
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source 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, or any warranty * of NON-INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * *   Free Software Foundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Scott Ferguson */package com.caucho.el;import com.caucho.util.CharBuffer;import com.caucho.util.L10N;import javax.el.ELContext;import javax.el.FunctionMapper;import javax.el.ValueExpression;import javax.el.VariableMapper;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.logging.Logger;import java.util.logging.Level;/** * Parses the expression. */public class ELParser{  private static final Logger log = Logger.getLogger(ELParser.class.getName());  private static final L10N L = new L10N(ELParser.class);  // The expression string  private String _string;  // Current parse index into the string  private int _index;  // The peek token  private int _peek = -1;  // The current lexeme  private String _lexeme;  // Temporary buffer  private CharBuffer _cb = new CharBuffer();  protected final ELContext _elContext;  private boolean _checkEscape = true;  public ELParser(ELContext elContext, String string)  {    if (elContext == null)      throw new NullPointerException();        _elContext = elContext;    _string = string;  }  protected ELParser create(String string)  {    ELParser parser = new ELParser(_elContext, string);    copyTo(parser);    return parser;  }  /**   * Copy to the dest parser.   */  protected void copyTo(ELParser parser)  {  }  /**   * Set true if escapes are checked.   */  public void setCheckEscape(boolean checkEscape)  {    _checkEscape = checkEscape;  }  /**   * Parses the expression string.   */  public Expr parse()    throws ELParseException  {    return parseInterpolate();  }  /**   * Parses interpolated code.   */  public Expr parseInterpolate()    throws ELParseException  {    CharBuffer text = CharBuffer.allocate();    CharBuffer exprString = CharBuffer.allocate();    Expr expr = null;    int ch;    while ((ch = read()) >= 0) {      if (_checkEscape && ch == '\\') {	ch = read();	if (ch == '$' || ch == '#' || ch == '\\')	  text.append((char) ch);	else {	  text.append('\\');	  unread();	}      }      else if (ch == '$' || ch == '#') {	int origChar = ch;	        ch = read();                if (ch == '{') {          if (text.length() > 0) {            StringLiteral right = new StringLiteral(text.toString());            if (expr == null)              expr = right;            else              expr = new InterpolateExpr(expr, right);            text.clear();          }          exprString.clear();          for (ch = read(); ch > 0 && ch != '}'; ch = read()) {            exprString.append((char) ch);	    	    if (ch == '\'' || ch == '"') {	      int end = ch;	      for (ch = read(); ch > 0 && ch != end; ch = read()) {		exprString.append((char) ch);		if (ch == '\\') {		  ch = read();		  if (ch > 0)		    exprString.append((char) ch);		}	      }	      if (ch > 0)		exprString.append((char) ch);	    }	  }	  if (ch != '}')	    throw error(L.l("expected '}' at end of EL expression",			    exprString));          Expr right = create(exprString.toString()).parseExpr();          if (expr == null)            expr = right;          else            expr = new InterpolateExpr(expr, right);        }        else {          text.append((char) origChar);          unread();        }      }      else        text.append((char) ch);    }    if (text.length() > 0) {      StringLiteral right = new StringLiteral(text.toString());      if (expr == null)        expr = right;      else        expr = new InterpolateExpr(expr, right);    }    if (expr == null)      expr = new StringLiteral("");    return expr;  }  /**   * expr ::= term   */  private Expr parseExpr()    throws ELParseException  {    Expr left = parseTerm();    while (true) {      int token = scanToken();            switch (token) {      case '?':	{	  Expr trueExpr = parseExpr();	  token = scanToken();	  if (token != ':')	    throw error(L.l("Expected ':' at {0}.  Conditional syntax is 'expr ? expr : expr'.", badChar(token)));	  Expr falseExpr = parseExpr();	  left = new ConditionalExpr(left, trueExpr, falseExpr);	}	break;	      case Expr.OR:	left = parseOrExpr(token, left, parseTerm());	break;      case Expr.AND:	left = parseAndExpr(token, left, parseTerm());	break;      case Expr.EQ: case Expr.NE: case Expr.LT:      case Expr.LE: case Expr.GT: case Expr.GE:	left = parseCmpExpr(token, left, parseTerm());	break;              case Expr.ADD: case Expr.SUB:	left = parseAddExpr(token, left, parseTerm());	break;      case Expr.MUL: case Expr.DIV: case Expr.MOD:	left = parseMulExpr(token, left, parseTerm());	break;      default:        _peek = token;	return left;      }    }  }  /**   * or-expr ::= or-expr 'or' expr   *         ::= and-expr   */  private Expr parseOrExpr(int code, Expr left, Expr right)    throws ELParseException  {    while (true) {      int token = scanToken();      switch (token) {      case Expr.OR:        left = new BooleanExpr(code, left, right);	code = token;	right = parseTerm();	break;              case Expr.AND:	right = parseAndExpr(token, right, parseTerm());	break;              case Expr.EQ: case Expr.NE:      case Expr.LT: case Expr.GT:      case Expr.LE: case Expr.GE:	right = parseCmpExpr(token, right, parseTerm());	break;              case Expr.ADD: case Expr.SUB:	right = parseAddExpr(token, right, parseTerm());	break;      case Expr.MUL: case Expr.DIV: case Expr.MOD:	right = parseMulExpr(token, right, parseTerm());	break;      default:	_peek = token;        return new BooleanExpr(code, left, right);      }    }  }  /**   * and-expr ::= and-expr 'and' expr   *          ::= cmp-expr   */  private Expr parseAndExpr(int code, Expr left, Expr right)    throws ELParseException  {    while (true) {      int token = scanToken();      switch (token) {      case Expr.AND:        left = new BooleanExpr(code, left, right);	code = token;	right = parseTerm();	break;              case Expr.EQ: case Expr.NE:      case Expr.LT: case Expr.GT:      case Expr.LE: case Expr.GE:	right = parseCmpExpr(token, right, parseTerm());	break;              case Expr.ADD: case Expr.SUB:	right = parseAddExpr(token, right, parseTerm());	break;      case Expr.MUL: case Expr.DIV: case Expr.MOD:	right = parseMulExpr(token, right, parseTerm());	break;      default:	_peek = token;        return new BooleanExpr(code, left, right);      }    }  }  /**   * cmp-expr ::= cmp-expr '=' expr   *          ::= add-expr   */  private Expr parseCmpExpr(int code, Expr left, Expr right)    throws ELParseException  {    while (true) {      int token = scanToken();      switch (token) {      case Expr.EQ: case Expr.NE:      case Expr.GT: case Expr.LT:      case Expr.LE: case Expr.GE:	left = CmpExpr.create(code, left, right);          	code = token;	right = parseTerm();	break;              case Expr.ADD: case Expr.SUB:	right = parseAddExpr(token, right, parseTerm());	break;      case Expr.MUL: case Expr.DIV: case Expr.MOD:	right = parseMulExpr(token, right, parseTerm());	break;      default:	_peek = token;	return CmpExpr.create(code, left, right);      }    }  }  /**   * add-expr ::= add-expr '+' expr   *          ::= mul-expr   */  private Expr parseAddExpr(int code, Expr left, Expr right)    throws ELParseException  {    while (true) {      int token = scanToken();      switch (token) {      case Expr.ADD: case Expr.SUB:	left = BinaryExpr.create(code, left, right);	code = token;	right = parseTerm();	break;      case Expr.MUL: case Expr.DIV: case Expr.MOD:	right = parseMulExpr(token, right, parseTerm());	break;      default:	_peek = token;	return BinaryExpr.create(code, left, right);      }    }  }  /**   * mul-expr ::= mul-expr '*' expr   *          ::= expr   */  private Expr parseMulExpr(int code, Expr left, Expr right)    throws ELParseException  {    while (true) {      int token = scanToken();      switch (token) {      case Expr.MUL: case Expr.DIV: case Expr.MOD:	left = BinaryExpr.create(code, left, right);	right = parseTerm();	code = token;	break;      default:	_peek = token;	return BinaryExpr.create(code, left, right);      }    }  }  /**   * term ::= simple-term   *      ::= term '[' expr ']'   *      ::= term . identifier   */  private Expr parseTerm()    throws ELParseException  {    Expr term = parseSimpleTerm();        while (true) {      int token = scanToken();      switch (token) {      case '[':      {	Expr expr = parseExpr();        token = scanToken();	if (token != ']')	  throw error(L.l("Expected `]' at {0}.  All open array braces must have matching closing brace.", badChar(token)));	term = term.createField(expr);        break;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?