001: /*
002: * SQLTokenMarker.java - Generic SQL token marker
003: * Copyright (C) 1999 mike dillon
004: *
005: * You may use and modify this package for any purpose. Redistribution is
006: * permitted, in both source and binary form, provided that this notice
007: * remains intact in all source distributions of this package.
008: */
009:
010: package org.syntax.jedit.tokenmarker;
011:
012: import org.syntax.jedit.*;
013: import javax.swing.text.Segment;
014:
015: /**
016: * SQL token marker.
017: *
018: * @author mike dillon
019: * @version $Id: SQLTokenMarker.java 3074 2004-11-08 04:24:58Z bquig $
020: */
021: public class SQLTokenMarker extends TokenMarker {
022: private int offset, lastOffset, lastKeyword, length;
023:
024: // public members
025: public SQLTokenMarker(KeywordMap k) {
026: this (k, false);
027: }
028:
029: public SQLTokenMarker(KeywordMap k, boolean tsql) {
030: keywords = k;
031: isTSQL = tsql;
032: }
033:
034: public byte markTokensImpl(byte token, Segment line, int lineIndex) {
035: offset = lastOffset = lastKeyword = line.offset;
036: length = line.count + offset;
037:
038: loop: for (int i = offset; i < length; i++) {
039: switch (line.array[i]) {
040: case '*':
041: if (token == Token.COMMENT1 && length - i >= 1
042: && line.array[i + 1] == '/') {
043: token = Token.NULL;
044: i++;
045: addToken((i + 1) - lastOffset, Token.COMMENT1);
046: lastOffset = i + 1;
047: } else if (token == Token.NULL) {
048: searchBack(line, i);
049: addToken(1, Token.OPERATOR);
050: lastOffset = i + 1;
051: }
052: break;
053: case '[':
054: if (token == Token.NULL) {
055: searchBack(line, i);
056: token = Token.LITERAL1;
057: literalChar = '[';
058: lastOffset = i;
059: }
060: break;
061: case ']':
062: if (token == Token.LITERAL1 && literalChar == '[') {
063: token = Token.NULL;
064: literalChar = 0;
065: addToken((i + 1) - lastOffset, Token.LITERAL1);
066: lastOffset = i + 1;
067: }
068: break;
069: case '.':
070: case ',':
071: case '(':
072: case ')':
073: if (token == Token.NULL) {
074: searchBack(line, i);
075: addToken(1, Token.NULL);
076: lastOffset = i + 1;
077: }
078: break;
079: case '+':
080: case '%':
081: case '&':
082: case '|':
083: case '^':
084: case '~':
085: case '<':
086: case '>':
087: case '=':
088: if (token == Token.NULL) {
089: searchBack(line, i);
090: addToken(1, Token.OPERATOR);
091: lastOffset = i + 1;
092: }
093: break;
094: case ' ':
095: case '\t':
096: if (token == Token.NULL) {
097: searchBack(line, i, false);
098: }
099: break;
100: case ':':
101: if (token == Token.NULL) {
102: addToken((i + 1) - lastOffset, Token.LABEL);
103: lastOffset = i + 1;
104: }
105: break;
106: case '/':
107: if (token == Token.NULL) {
108: if (length - i >= 2 && line.array[i + 1] == '*') {
109: searchBack(line, i);
110: token = Token.COMMENT1;
111: lastOffset = i;
112: i++;
113: } else {
114: searchBack(line, i);
115: addToken(1, Token.OPERATOR);
116: lastOffset = i + 1;
117: }
118: }
119: break;
120: case '-':
121: if (token == Token.NULL) {
122: if (length - i >= 2 && line.array[i + 1] == '-') {
123: searchBack(line, i);
124: addToken(length - i, Token.COMMENT1);
125: lastOffset = length;
126: break loop;
127: } else {
128: searchBack(line, i);
129: addToken(1, Token.OPERATOR);
130: lastOffset = i + 1;
131: }
132: }
133: break;
134: case '!':
135: if (isTSQL
136: && token == Token.NULL
137: && length - i >= 2
138: && (line.array[i + 1] == '='
139: || line.array[i + 1] == '<' || line.array[i + 1] == '>')) {
140: searchBack(line, i);
141: addToken(1, Token.OPERATOR);
142: lastOffset = i + 1;
143: }
144: break;
145: case '"':
146: case '\'':
147: if (token == Token.NULL) {
148: token = Token.LITERAL1;
149: literalChar = line.array[i];
150: addToken(i - lastOffset, Token.NULL);
151: lastOffset = i;
152: } else if (token == Token.LITERAL1
153: && literalChar == line.array[i]) {
154: token = Token.NULL;
155: literalChar = 0;
156: addToken((i + 1) - lastOffset, Token.LITERAL1);
157: lastOffset = i + 1;
158: }
159: break;
160: default:
161: break;
162: }
163: }
164: if (token == Token.NULL)
165: searchBack(line, length, false);
166: if (lastOffset != length)
167: addToken(length - lastOffset, token);
168: return token;
169: }
170:
171: // protected members
172: protected boolean isTSQL = false;
173:
174: // private members
175: private KeywordMap keywords;
176: private char literalChar = 0;
177:
178: private void searchBack(Segment line, int pos) {
179: searchBack(line, pos, true);
180: }
181:
182: private void searchBack(Segment line, int pos, boolean padNull) {
183: int len = pos - lastKeyword;
184: byte id = keywords.lookup(line, lastKeyword, len);
185: if (id != Token.NULL) {
186: if (lastKeyword != lastOffset)
187: addToken(lastKeyword - lastOffset, Token.NULL);
188: addToken(len, id);
189: lastOffset = pos;
190: }
191: lastKeyword = pos + 1;
192: if (padNull && lastOffset < pos)
193: addToken(pos - lastOffset, Token.NULL);
194: }
195: }
|