View Javadoc

    1   /*
    2    * SQLTokenMarker.java - Generic SQL token marker
    3    * Copyright (C) 1999 mike dillon
    4    *
    5    * You may use and modify this package for any purpose. Redistribution is
    6    * permitted, in both source and binary form, provided that this notice
    7    * remains intact in all source distributions of this package.
    8    */
    9
    10  package org.syntax.jedit.tokenmarker;
    11
    12  import javax.swing.text.Segment;
    13
    14  import org.syntax.jedit.KeywordMap;
    15
    16  /***
    17   * SQL token marker.
    18   *
    19   * @author mike dillon
    20   * @version $Id: SQLTokenMarker.java,v 1.6 1999/04/19 05:38:20 sp Exp $
    21   */
    22  public class SQLTokenMarker extends TokenMarker
    23  {
    24  	private int offset, lastOffset, lastKeyword, length;
    25
    26  	// public members
    27  	public SQLTokenMarker(KeywordMap k)
    28  	{
    29  		this(k, false);
    30  	}
    31
    32  	public SQLTokenMarker(KeywordMap k, boolean tsql)
    33  	{
    34  		keywords = k;
    35  		isTSQL = tsql;
    36  	}
    37
    38  	public byte markTokensImpl(byte token, Segment line, int lineIndex)
    39  	{
    40  		offset = lastOffset = lastKeyword = line.offset;
    41  		length = line.count + offset;
    42
    43  loop:
    44  		for(int i = offset; i < length; i++)
    45  		{
    46  			switch(line.array[i])
    47  			{
    48  			case '*':
    49  				if(token == Token.COMMENT1 && length - i >= 1 && line.array[i+1] == '/')
    50  				{
    51  					token = Token.NULL;
    52  					i++;
    53  					addToken((i + 1) - lastOffset,Token.COMMENT1);
    54  					lastOffset = i + 1;
    55  				}
    56  				else if (token == Token.NULL)
    57  				{
    58  					searchBack(line, i);
    59  					addToken(1,Token.OPERATOR);
    60  					lastOffset = i + 1;
    61  				}
    62  				break;
    63  			case '[':
    64  				if(token == Token.NULL)
    65  				{
    66  					searchBack(line, i);
    67  					token = Token.LITERAL1;
    68  					literalChar = '[';
    69  					lastOffset = i;
    70  				}
    71  				break;
    72  			case ']':
    73  				if(token == Token.LITERAL1 && literalChar == '[')
    74  				{
    75  					token = Token.NULL;
    76  					literalChar = 0;
    77  					addToken((i + 1) - lastOffset,Token.LITERAL1);
    78  					lastOffset = i + 1;
    79  				}
    80  				break;
    81  			case '.': case ',': case '(': case ')':
    82  				if (token == Token.NULL) {
    83  					searchBack(line, i);
    84  					addToken(1, Token.NULL);
    85  					lastOffset = i + 1;
    86  				}
    87  				break;
    88  			case '+': case '%': case '&': case '|': case '^':
    89  			case '~': case '<': case '>': case '=':
    90  				if (token == Token.NULL) {
    91  					searchBack(line, i);
    92  					addToken(1,Token.OPERATOR);
    93  					lastOffset = i + 1;
    94  				}
    95  				break;
    96  			case ' ': case '\t':
    97  				if (token == Token.NULL) {
    98  					searchBack(line, i, false);
    99  				}
    100 				break;
    101 			case ':':
    102 				if(token == Token.NULL)
    103 				{
    104 					addToken((i+1) - lastOffset,Token.LABEL);
    105 					lastOffset = i + 1;
    106 				}
    107 				break;
    108 			case '/':
    109 				if(token == Token.NULL)
    110 				{
    111 					if (length - i >= 2 && line.array[i + 1] == '*')
    112 					{
    113 						searchBack(line, i);
    114 						token = Token.COMMENT1;
    115 						lastOffset = i;
    116 						i++;
    117 					}
    118 					else
    119 					{
    120 						searchBack(line, i);
    121 						addToken(1,Token.OPERATOR);
    122 						lastOffset = i + 1;
    123 					}
    124 				}
    125 				break;
    126 			case '-':
    127 				if(token == Token.NULL)
    128 				{
    129 					if (length - i >= 2 && line.array[i+1] == '-')
    130 					{
    131 						searchBack(line, i);
    132 						addToken(length - i,Token.COMMENT1);
    133 						lastOffset = length;
    134 						break loop;
    135 					}
    136 					else
    137 					{
    138 						searchBack(line, i);
    139 						addToken(1,Token.OPERATOR);
    140 						lastOffset = i + 1;
    141 					}
    142 				}
    143 				break;
    144 			case '!':
    145 				if(isTSQL && token == Token.NULL && length - i >= 2 &&
    146 				(line.array[i+1] == '=' || line.array[i+1] == '<' || line.array[i+1] == '>'))
    147 				{
    148 					searchBack(line, i);
    149 					addToken(1,Token.OPERATOR);
    150 					lastOffset = i + 1;
    151 				}
    152 				break;
    153 			case '"': case '\'':
    154 				if(token == Token.NULL)
    155 				{
    156 					token = Token.LITERAL1;
    157 					literalChar = line.array[i];
    158 					addToken(i - lastOffset,Token.NULL);
    159 					lastOffset = i;
    160 				}
    161 				else if(token == Token.LITERAL1 && literalChar == line.array[i])
    162 				{
    163 					token = Token.NULL;
    164 					literalChar = 0;
    165 					addToken((i + 1) - lastOffset,Token.LITERAL1);
    166 					lastOffset = i + 1;
    167 				}
    168 				break;
    169 			default:
    170 				break;
    171 			}
    172 		}
    173 		if(token == Token.NULL)
    174 			searchBack(line, length, false);
    175 		if(lastOffset != length)
    176 			addToken(length - lastOffset,token);
    177 		return token;
    178 	}
    179
    180 	// protected members
    181 	protected boolean isTSQL = false;
    182
    183 	// private members
    184 	private KeywordMap keywords;
    185 	private char literalChar = 0;
    186
    187 	private void searchBack(Segment line, int pos)
    188 	{
    189 		searchBack(line, pos, true);
    190 	}
    191
    192 	private void searchBack(Segment line, int pos, boolean padNull)
    193 	{
    194 		int len = pos - lastKeyword;
    195 		byte id = keywords.lookup(line,lastKeyword,len);
    196 		if(id != Token.NULL)
    197 		{
    198 			if(lastKeyword != lastOffset)
    199 				addToken(lastKeyword - lastOffset,Token.NULL);
    200 			addToken(len,id);
    201 			lastOffset = pos;
    202 		}
    203 		lastKeyword = pos + 1;
    204 		if (padNull && lastOffset < pos)
    205 			addToken(pos - lastOffset, Token.NULL);
    206 	}
    207 }