001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.jexl2.parser; 018 019 import org.apache.commons.jexl2.DebugInfo; 020 import org.apache.commons.jexl2.JexlEngine; 021 import org.apache.commons.jexl2.JexlException; 022 023 /** 024 * The base class for parsing, manages the parameter/local variable frame. 025 * @author henri 026 */ 027 public class JexlParser extends StringParser { 028 /** 029 * The map of named registers aka script parameters. 030 * Each parameter is associated to a register and is materialized as an offset in the registers array used 031 * during evaluation. 032 */ 033 protected JexlEngine.Scope frame; 034 035 /** 036 * Sets the frame to use bythis parser. 037 * <p> 038 * This is used to allow parameters to be declared before parsing. 039 * </p> 040 * @param theFrame the register map 041 */ 042 public void setFrame(JexlEngine.Scope theFrame) { 043 frame = theFrame; 044 } 045 046 /** 047 * Gets the frame used by this parser. 048 * <p> 049 * Since local variables create new named registers, it is important to regain access after 050 * parsing to known which / how-many registers are needed. 051 * </p> 052 * @return the named register map 053 */ 054 public JexlEngine.Scope getFrame() { 055 return frame; 056 } 057 058 059 /** 060 * Checks whether an identifier is a local variable or argument, ie stored in a register. 061 * @param identifier the identifier 062 * @param image the identifier image 063 * @return the image 064 */ 065 public String checkVariable(ASTIdentifier identifier, String image) { 066 if (frame != null) { 067 Integer register = frame.getRegister(image); 068 if (register != null) { 069 identifier.setRegister(register.intValue()); 070 } 071 } 072 return image; 073 } 074 075 /** 076 * Declares a local variable. 077 * <p> 078 * This method creates an new entry in the named register map. 079 * </p> 080 * @param identifier the identifier used to declare 081 * @param image the variable name 082 */ 083 public void declareVariable(ASTVar identifier, String image) { 084 if (frame == null) { 085 frame = new JexlEngine.Scope((String[])null); 086 } 087 Integer register = frame.declareVariable(image); 088 identifier.setRegister(register.intValue()); 089 identifier.image = image; 090 } 091 092 /** 093 * Default implementation does nothing but is overriden by generated code. 094 * @param top whether the identifier is beginning an l/r value 095 * @throws ParseException subclasses may throw this 096 */ 097 public void Identifier(boolean top) throws ParseException { 098 // Overriden by generated code 099 } 100 101 final public void Identifier() throws ParseException { 102 Identifier(false); 103 } 104 105 public Token getToken(int index) { 106 return null; 107 } 108 109 void jjtreeOpenNodeScope(JexlNode n) { 110 } 111 112 /** 113 * Ambiguous statement detector. 114 * @param n the node 115 * @throws ParseException 116 */ 117 void jjtreeCloseNodeScope(JexlNode n) throws ParseException { 118 if (n instanceof ASTAmbiguous && n.jjtGetNumChildren() > 0) { 119 DebugInfo dbgInfo = null; 120 Token tok = this.getToken(0); 121 if (tok != null) { 122 dbgInfo = new DebugInfo(tok.image, tok.beginLine, tok.beginColumn); 123 } else { 124 dbgInfo = n.debugInfo(); 125 } 126 throw new JexlException.Parsing(dbgInfo, "Ambiguous statement, missing ';' between expressions", null); 127 } 128 } 129 }