001: /*
002: * PythonTagger.java
003: *
004: * Copyright (C) 1998-2002 Peter Graves
005: * $Id: PythonTagger.java,v 1.1.1.1 2002/09/24 16:09:15 piso Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.armedbear.j;
023:
024: import java.util.ArrayList;
025:
026: public final class PythonTagger extends Tagger {
027: // States.
028: private static final int STATE_NEUTRAL = 0;
029: private static final int STATE_CLASS_NAME = 1;
030: private static final int STATE_FUNCTION_NAME = 2;
031: private static final int STATE_SINGLE_QUOTE = 3;
032: private static final int STATE_DOUBLE_QUOTE = 4;
033: private static final int STATE_TRIPLE_SINGLE = 5;
034: private static final int STATE_TRIPLE_DOUBLE = 6;
035:
036: private static final PythonMode mode = PythonMode.getMode();
037:
038: public PythonTagger(SystemBuffer buffer) {
039: super (buffer);
040: }
041:
042: public void run() {
043: ArrayList tags = new ArrayList();
044: Position pos = new Position(buffer.getFirstLine(), 0);
045: int state = STATE_NEUTRAL;
046: while (!pos.atEnd()) {
047: char c = pos.getChar();
048: if (Character.isWhitespace(c)) {
049: pos.skipWhitespace();
050: continue;
051: }
052: if (c == '\\') {
053: // Escape.
054: if (pos.getOffset() < pos.getLineLength() - 1) {
055: pos.skip(2);
056: } else {
057: pos.setLine(pos.getNextLine());
058: pos.setOffset(0);
059: }
060: continue;
061: }
062: if (state == STATE_SINGLE_QUOTE) {
063: if (c == '\'')
064: state = STATE_NEUTRAL;
065: pos.next();
066: continue;
067: }
068: if (state == STATE_DOUBLE_QUOTE) {
069: if (c == '"')
070: state = STATE_NEUTRAL;
071: pos.next();
072: continue;
073: }
074: if (state == STATE_TRIPLE_SINGLE) {
075: if (c == '\'' && pos.lookingAt("'''")) {
076: pos.skip(3);
077: state = STATE_NEUTRAL;
078: } else
079: pos.next();
080: continue;
081: }
082: if (state == STATE_TRIPLE_DOUBLE) {
083: if (c == '"' && pos.lookingAt("\"\"\"")) {
084: pos.skip(3);
085: state = STATE_NEUTRAL;
086: } else
087: pos.next();
088: continue;
089: }
090: if (c == '\'') {
091: if (pos.lookingAt("'''")) {
092: state = STATE_TRIPLE_SINGLE;
093: pos.skip(3);
094: } else {
095: state = STATE_SINGLE_QUOTE;
096: pos.next();
097: }
098: continue;
099: }
100: if (c == '"') {
101: if (pos.lookingAt("\"\"\"")) {
102: state = STATE_TRIPLE_DOUBLE;
103: pos.skip(3);
104: } else {
105: state = STATE_DOUBLE_QUOTE;
106: pos.next();
107: }
108: continue;
109: }
110: if (c == '#') {
111: // Comment.
112: pos.setLine(pos.getNextLine());
113: pos.setOffset(0);
114: continue;
115: }
116: if (mode.isIdentifierStart(c)) {
117: Position start = pos.copy();
118: String token = gatherToken(pos);
119: if (state == STATE_CLASS_NAME) {
120: LocalTag tag = new PythonTag("class " + token,
121: start, TAG_CLASS);
122: tags.add(tag);
123: state = STATE_NEUTRAL;
124: } else if (state == STATE_FUNCTION_NAME) {
125: LocalTag tag = new PythonTag(token, start,
126: TAG_FUNCTION);
127: tags.add(tag);
128: state = STATE_NEUTRAL;
129: } else if (token.equals("class")) {
130: state = STATE_CLASS_NAME;
131: } else if (token.equals("def")) {
132: state = STATE_FUNCTION_NAME;
133: }
134: continue;
135: }
136: pos.next();
137: }
138: buffer.setTags(tags);
139: }
140:
141: private static String gatherToken(Position pos) {
142: FastStringBuffer sb = new FastStringBuffer();
143: char c;
144: while (mode.isIdentifierPart(c = pos.getChar())) {
145: sb.append(c);
146: if (!pos.next())
147: break;
148: }
149: return sb.toString();
150: }
151: }
|