/******************************************************************************* * Copyright (c) 2007 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.common.el.internal.core.parser.token; import org.jboss.tools.common.el.core.ElCoreMessages; import org.jboss.tools.common.el.core.parser.ITokenDescription; import org.jboss.tools.common.el.core.parser.SyntaxError; import org.jboss.tools.common.el.core.parser.Tokenizer; import org.jboss.tools.common.el.internal.core.parser.rule.BasicStates; /** * * @author V. Kabanovich * */ public class PrimitiveValueTokenDescription implements ITokenDescription { public static final int PRIMITIVE_VALUE = 6; public static PrimitiveValueTokenDescription INSTANCE = new PrimitiveValueTokenDescription(); private static final String[] OPS_2 = { "null", "true", "false", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ }; public String getName() { return ElCoreMessages.PrimitiveValueTokenDescription_Name; } public int getType() { return PRIMITIVE_VALUE; } public boolean isStart(Tokenizer tokenizer, int offset) { if(isNumber(tokenizer, offset)) { return true; } int end = -1; boolean canBeFollowedByOperand = true; for (int i = 0; end < 0 && i < OPS_2.length; i++) { if(tokenizer.startsWith(OPS_2[i])) { end = offset + OPS_2[i].length(); canBeFollowedByOperand = false; } } if(end < 0) return false; char ch = tokenizer.lookUpChar(end); if(Character.isWhitespace(ch) || ch == '\0' || !Character.isJavaIdentifierPart(ch) || (canBeFollowedByOperand && Character.isJavaIdentifierPart(ch))) { return true; } return false; } private boolean isNumber(Tokenizer tokenizer, int offset) { char ch = tokenizer.lookUpChar(offset); if(ch == '.') { ch = tokenizer.lookUpChar(offset + 1); } return ch != '\0' && Character.isDigit(ch); } public boolean read(Tokenizer tokenizer, int offset) { if(isNumber(tokenizer, offset)) { return readNumber(tokenizer, offset); } int end = -1; for (int i = 0; end < 0 && i < OPS_2.length; i++) { if(tokenizer.startsWith(OPS_2[i])) { end = offset + OPS_2[i].length(); } } tokenizer.addToken(getType(), offset, end); return true; } static String TYPE_CHAR = "lLfFdD"; //$NON-NLS-1$ private boolean readNumber(Tokenizer tokenizer, int offset) { int i = offset; int dotCount = 1; int dotOffset = -1; if(tokenizer.startsWith("0x")) { //$NON-NLS-1$ i += 2; dotCount = 0; } char ch = '\0'; boolean lastCharIsWrong = false; boolean inE = false; while((ch = tokenizer.readNextChar()) != '\0') { if(ch == '.') { dotCount--; if(dotCount < 0) { lastCharIsWrong = true; break; } else { dotOffset = tokenizer.getCurrentIndex() - 1; } } else if(!Character.isDigit(ch)) { if(inE) { // } if(TYPE_CHAR.indexOf(ch) >= 0) { char ch1 = tokenizer.lookUpChar(i + 1); if(ch1 == '\0' || !Character.isJavaIdentifierPart(ch1)) { i++; break; } } else if(ch == 'e' || ch == 'E') { char ch1 = tokenizer.lookUpChar(i + 1); char ch2 = tokenizer.lookUpChar(i + 2); if((ch1 == '+' || ch1 == '-') && Character.isDigit(ch2)) { tokenizer.readNextChar(); tokenizer.readNextChar(); i += 3; inE = true; dotCount = 0; continue; } else if(Character.isDigit(ch1)) { tokenizer.readNextChar(); i += 2; inE = true; dotCount = 0; continue; } } lastCharIsWrong = true; break; } i++; } if(lastCharIsWrong) { tokenizer.releaseChar(); } if(tokenizer.getLastToken() != null && tokenizer.getLastToken().getType() == ArgStartTokenDescription.ARG_START && dotCount < 1) { SyntaxError error = new SyntaxError(dotOffset, BasicStates.STATE_EXPECTING_ARG); error.setProblem(ElCoreMessages.PrimitiveValueTokenDescription_ArgMustResolveToIntegerOrString); tokenizer.addSyntaxError(error); } tokenizer.addToken(getType(), offset, i); return true; } }