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