All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.syntax.jedit.tokenmarker.PHPTokenMarker Maven / Gradle / Ivy

The newest version!
/*
 *  soapUI, copyright (C) 2004-2011 smartbear.com 
 *
 *  soapUI is free software; you can redistribute it and/or modify it under the 
 *  terms of version 2.1 of the GNU Lesser General Public License as published by 
 *  the Free Software Foundation.
 *
 *  soapUI 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 at gnu.org.
 */

package org.syntax.jedit.tokenmarker;

import javax.swing.text.Segment;

import org.syntax.jedit.KeywordMap;
import org.syntax.jedit.SyntaxUtilities;

/**
 * PHP token marker.
 * 
 * @author Clancy Malcolm
 * @version $Id: PHPTokenMarker.java,v 1.1 1999/12/14 04:20:35 sp Exp $
 */
public class PHPTokenMarker extends TokenMarker
{
	public static final byte SCRIPT = Token.INTERNAL_FIRST;

	public byte markTokensImpl( byte token, Segment line, int lineIndex )
	{
		char[] array = line.array;
		int offset = line.offset;
		lastOffset = offset;
		lastKeyword = offset;
		int length = line.count + offset;
		boolean backslash = false;

		loop : for( int i = offset; i < length; i++ )
		{
			int i1 = ( i + 1 );

			char c = array[i];
			if( c == '\\' )
			{
				backslash = !backslash;
				continue;
			}

			switch( token )
			{
			case Token.NULL : // HTML text
				backslash = false;
				switch( c )
				{
				case '<' :
					addToken( i - lastOffset, token );
					lastOffset = lastKeyword = i;
					if( SyntaxUtilities.regionMatches( false, line, i1, "!--" ) )
					{
						i += 3;
						token = Token.COMMENT1;
					}
					else if( SyntaxUtilities.regionMatches( true, line, i1, "?php" ) )
					{
						addToken( 5, Token.LABEL );
						lastOffset = lastKeyword = ( i += 4 ) + 1;
						token = SCRIPT;
					}
					else if( SyntaxUtilities.regionMatches( true, line, i1, "?" ) )
					{
						addToken( 2, Token.LABEL );
						lastOffset = lastKeyword = ( i += 1 ) + 1;
						token = SCRIPT;
					}
					else if( SyntaxUtilities.regionMatches( true, line, i1, "script>" ) )
					{
						addToken( 8, Token.LABEL );
						lastOffset = lastKeyword = ( i += 7 ) + 1;
						token = SCRIPT;
					}
					else
					{
						token = Token.KEYWORD1;
					}
					break;
				case '&' :
					addToken( i - lastOffset, token );
					lastOffset = lastKeyword = i;
					token = Token.KEYWORD2;
					break;
				}
				break;
			case Token.KEYWORD1 : // Inside a tag
				backslash = false;
				if( c == '>' )
				{
					addToken( i1 - lastOffset, token );
					lastOffset = lastKeyword = i1;
					token = Token.NULL;
				}
				break;
			case Token.KEYWORD2 : // Inside an entity
				backslash = false;
				if( c == ';' )
				{
					addToken( i1 - lastOffset, token );
					lastOffset = lastKeyword = i1;
					token = Token.NULL;
					break;
				}
				break;
			case Token.COMMENT1 : // Inside a comment
				backslash = false;
				if( SyntaxUtilities.regionMatches( false, line, i, "-->" ) )
				{
					addToken( i + 3 - lastOffset, token );
					i += 2;
					lastOffset = lastKeyword = i + 1;
					token = Token.NULL;
				}
				break;
			case SCRIPT : // Inside a JavaScript or PHP
				switch( c )
				{
				case '<' :
					backslash = false;
					doKeyword( line, i, c );
					if( SyntaxUtilities.regionMatches( true, line, i1, "/script>" ) )
					{
						// Ending the script
						addToken( i - lastOffset, Token.KEYWORD3 );
						addToken( 9, Token.LABEL );
						lastOffset = lastKeyword = ( i += 8 ) + 1;
						token = Token.NULL;
					}
					else
					{
						// < operator
						addToken( i - lastOffset, Token.KEYWORD3 );
						addToken( 1, Token.OPERATOR );
						lastOffset = lastKeyword = i1;
					}
					break;
				case '?' :
					backslash = false;
					doKeyword( line, i, c );
					if( array[i1] == '>' )
					{
						// Ending the script
						addToken( i - lastOffset, Token.KEYWORD3 );
						addToken( 2, Token.LABEL );
						lastOffset = lastKeyword = ( i += 1 ) + 1;
						token = Token.NULL;
					}
					else
					{
						// ? operator
						addToken( i - lastOffset, Token.KEYWORD3 );
						addToken( 1, Token.OPERATOR );
						lastOffset = lastKeyword = i1;
					}
					break;
				case '"' :
					if( backslash )
						backslash = false;
					else
					{
						doKeyword( line, i, c );
						addToken( i - lastOffset, Token.KEYWORD3 );
						lastOffset = lastKeyword = i;
						token = Token.LITERAL1;
					}
					break;
				case '\'' :
					if( backslash )
						backslash = false;
					else
					{
						doKeyword( line, i, c );
						addToken( i - lastOffset, Token.KEYWORD3 );
						lastOffset = lastKeyword = i;
						token = Token.LITERAL2;
					}
					break;
				case '#' :
					doKeyword( line, i, c );
					addToken( i - lastOffset, Token.KEYWORD3 );
					addToken( length - i, Token.COMMENT2 );
					lastOffset = lastKeyword = length;
					break loop;
				case '/' :
					backslash = false;
					doKeyword( line, i, c );
					if( length - i > 1 ) /* This is the same as if(length > i + 1) */
					{
						addToken( i - lastOffset, Token.KEYWORD3 );
						lastOffset = lastKeyword = i;
						if( array[i1] == '/' )
						{
							addToken( length - i, Token.COMMENT2 );
							lastOffset = lastKeyword = length;
							break loop;
						}
						else if( array[i1] == '*' )
						{
							token = Token.COMMENT2;
						}
						else
						{
							// / operator
							addToken( i - lastOffset, Token.KEYWORD3 );
							addToken( 1, Token.OPERATOR );
							lastOffset = lastKeyword = i1;
						}
					}
					else
					{
						// / operator
						addToken( i - lastOffset, Token.KEYWORD3 );
						addToken( 1, Token.OPERATOR );
						lastOffset = lastKeyword = i1;
					}
					break;
				default :
					backslash = false;
					if( !Character.isLetterOrDigit( c ) && c != '_' && c != '$' )
					{
						doKeyword( line, i, c );
						if( c != ' ' )
						{
							// assume non alphanumeric characters are operators
							addToken( i - lastOffset, Token.KEYWORD3 );
							addToken( 1, Token.OPERATOR );
							lastOffset = lastKeyword = i1;
						}
					}
					break;
				}
				break;
			case Token.LITERAL1 : // Script "..."
				if( backslash )
					backslash = false;
				else if( c == '"' )
				{
					addToken( i1 - lastOffset, Token.LITERAL1 );
					lastOffset = lastKeyword = i1;
					token = SCRIPT;
				}
				break;
			case Token.LITERAL2 : // Script '...'
				if( backslash )
					backslash = false;
				else if( c == '\'' )
				{
					addToken( i1 - lastOffset, Token.LITERAL1 );
					lastOffset = lastKeyword = i1;
					token = SCRIPT;
				}
				break;
			case Token.COMMENT2 : // Inside a Script comment
				backslash = false;
				if( c == '*' && length - i > 1 && array[i1] == '/' )
				{
					addToken( i + 2 - lastOffset, Token.COMMENT2 );
					i += 1;
					lastOffset = lastKeyword = i + 1;
					token = SCRIPT;
				}
				break;
			default :
				throw new InternalError( "Invalid state: " + token );
			}
		}

		switch( token )
		{
		case Token.LITERAL1 :
			addToken( length - lastOffset, Token.LITERAL1 );
			break;
		case Token.LITERAL2 :
			addToken( length - lastOffset, Token.LITERAL2 );
			break;
		case Token.KEYWORD2 :
			addToken( length - lastOffset, Token.INVALID );
			token = Token.NULL;
			break;
		case SCRIPT :
			doKeyword( line, length, '\0' );
			addToken( length - lastOffset, Token.KEYWORD3 );
			break;
		default :
			addToken( length - lastOffset, token );
			break;
		}

		return token;
	}

	// private members
	private static KeywordMap keywords;
	private int lastOffset;
	private int lastKeyword;

	static
	{
		keywords = new KeywordMap( false );
		keywords.add( "function", Token.KEYWORD2 );
		keywords.add( "class", Token.KEYWORD2 );
		keywords.add( "var", Token.KEYWORD2 );
		keywords.add( "require", Token.KEYWORD2 );
		keywords.add( "include", Token.KEYWORD2 );
		keywords.add( "else", Token.KEYWORD1 );
		keywords.add( "elseif", Token.KEYWORD1 );
		keywords.add( "do", Token.KEYWORD1 );
		keywords.add( "for", Token.KEYWORD1 );
		keywords.add( "if", Token.KEYWORD1 );
		keywords.add( "endif", Token.KEYWORD1 );
		keywords.add( "in", Token.KEYWORD1 );
		keywords.add( "new", Token.KEYWORD1 );
		keywords.add( "return", Token.KEYWORD1 );
		keywords.add( "while", Token.KEYWORD1 );
		keywords.add( "endwhile", Token.KEYWORD1 );
		keywords.add( "with", Token.KEYWORD1 );
		keywords.add( "break", Token.KEYWORD1 );
		keywords.add( "switch", Token.KEYWORD1 );
		keywords.add( "case", Token.KEYWORD1 );
		keywords.add( "continue", Token.KEYWORD1 );
		keywords.add( "default", Token.KEYWORD1 );
		keywords.add( "echo", Token.KEYWORD1 );
		keywords.add( "false", Token.KEYWORD1 );
		keywords.add( "this", Token.KEYWORD1 );
		keywords.add( "true", Token.KEYWORD1 );
		keywords.add( "array", Token.KEYWORD1 );
		keywords.add( "extends", Token.KEYWORD1 );
	}

	private boolean doKeyword( Segment line, int i, char c )
	{
		int i1 = i + 1;

		int len = i - lastKeyword;
		byte id = keywords.lookup( line, lastKeyword, len );
		if( id != Token.NULL )
		{
			if( lastKeyword != lastOffset )
				addToken( lastKeyword - lastOffset, Token.KEYWORD3 );
			addToken( len, id );
			lastOffset = i;
		}
		lastKeyword = i1;
		return false;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy