⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tokenmarker.java

📁 Java写的文本编辑器
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * TokenMarker.java - Tokenizes lines of text * Copyright (C) 1998, 1999, 2000, 2001 Slava Pestov * Copyright (C) 1999, 2000 mike dillon * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. */package org.gjt.sp.jedit.syntax;import javax.swing.text.*;import java.util.*;import org.gjt.sp.jedit.*;import org.gjt.sp.util.Log;/** * A token marker splits lines of text into tokens. Each token carries * a length field and an identification tag that can be mapped to a color * or font style for painting that token. * * @author Slava Pestov, mike dillon * @version $Id: TokenMarker.java,v 1.1.1.1 2001/09/02 05:38:02 spestov Exp $ * * @see org.gjt.sp.jedit.syntax.Token */public class TokenMarker{	// major actions (total: 8)	public static final int MAJOR_ACTIONS = 0x000000FF;	public static final int WHITESPACE = 1 << 0;	public static final int SPAN = 1 << 1;	public static final int MARK_PREVIOUS = 1 << 2;	public static final int MARK_FOLLOWING = 1 << 3;	public static final int EOL_SPAN = 1 << 4;//	public static final int MAJOR_ACTION_5 = 1 << 5;//	public static final int MAJOR_ACTION_6 = 1 << 6;//	public static final int MAJOR_ACTION_7 = 1 << 7;	// action hints (total: 8)	public static final int ACTION_HINTS = 0x0000FF00;	public static final int EXCLUDE_MATCH = 1 << 8;	public static final int AT_LINE_START = 1 << 9;	public static final int NO_LINE_BREAK = 1 << 10;	public static final int NO_WORD_BREAK = 1 << 11;	public static final int IS_ESCAPE = 1 << 12;	public static final int DELEGATE = 1 << 13;//	public static final int ACTION_HINT_14 = 1 << 14;//	public static final int ACTION_HINT_15 = 1 << 15;	public TokenMarker()	{		ruleSets = new Hashtable(64);	}	public void addRuleSet(String setName, ParserRuleSet rules)	{		if (rules == null) return;		if (setName == null) setName = "MAIN";		ruleSets.put(rulePfx.concat(setName), rules);	}	public ParserRuleSet getMainRuleSet()	{		return getRuleSet(rulePfx + "MAIN");	}	public ParserRuleSet getRuleSet(String setName)	{		ParserRuleSet rules;		rules = (ParserRuleSet) ruleSets.get(setName);		if (rules == null && !setName.startsWith(rulePfx))		{			int delim = setName.indexOf("::");			String modeName = setName.substring(0, delim);			Mode mode = jEdit.getMode(modeName);			if(mode == null)			{				Log.log(Log.ERROR,TokenMarker.class,					"Unknown edit mode: " + modeName);				rules = null;			}			else			{				TokenMarker marker = mode.getTokenMarker();				rules = marker.getRuleSet(setName);			}			// store external ParserRuleSet in the local hashtable for			// faster lookups later			ruleSets.put(setName, rules);		}		if (rules == null)		{			Log.log(Log.ERROR,this,"Unresolved delegate target: " + setName);		}		return rules;	}	public String getName()	{		return name;	}	public void setName(String name)	{		if (name == null) throw new NullPointerException();		this.name = name;		rulePfx = name.concat("::");	}	/**	 * Do not call this method directly; call Buffer.markTokens() instead.	 */	public void markTokens(Buffer.LineInfo prevInfo,		Buffer.LineInfo info, Segment line)	{		LineContext lastContext = (prevInfo == null ? null			: prevInfo.context);		if(lastContext == null)		{			lastContext = new LineContext(null,				getRuleSet(rulePfx.concat("MAIN")));		}		context = info.context;		context.parent = (lastContext.parent == null ? null			: (LineContext)lastContext.parent.clone());		context.inRule = lastContext.inRule;		context.rules = lastContext.rules;		lastOffset = lastKeyword = line.offset;		lineLength = line.count + line.offset;		int terminateChar = context.rules.getTerminateChar();		int searchLimit = (terminateChar >= 0 && terminateChar < line.count)			? line.offset + terminateChar : lineLength;		escaped = false;		boolean b;		boolean tempEscaped;		Segment tempPattern;		ParserRule rule;		LineContext tempContext;		for(pos = line.offset; pos < searchLimit; pos++)		{			// if we are not in the top level context, we are delegated			if (context.parent != null)			{				tempContext = context;				context = context.parent;				pattern.array = context.inRule.searchChars;				pattern.count = context.inRule.sequenceLengths[1];				pattern.offset = context.inRule.sequenceLengths[0];				b = handleRule(info, line, context.inRule);				context = tempContext;				if (!b)				{					if (escaped)					{						escaped = false;					}					else					{						if (pos != lastOffset)						{							if (context.inRule == null)							{								markKeyword(info,line,lastKeyword,pos);								info.addToken(pos - lastOffset,									context.rules.getDefault());							}							else if ((context.inRule.action & (NO_LINE_BREAK | NO_WORD_BREAK)) == 0)							{								info.addToken(pos - lastOffset,									context.inRule.token);							}							else							{								info.addToken(pos - lastOffset, Token.INVALID);							}						}						context = (LineContext) context.parent;						if ((context.inRule.action & EXCLUDE_MATCH) == EXCLUDE_MATCH)						{							info.addToken(pattern.count,								context.rules.getDefault());						}						else						{							info.addToken(pattern.count,context.inRule.token);						}						context.inRule = null;						lastKeyword = lastOffset = pos + pattern.count;					}					pos += (pattern.count - 1); // move pos to last character of match sequence					continue;				}			}			// check the escape rule for the current context, if there is one			if ((rule = context.rules.getEscapeRule()) != null)			{				// assign tempPattern to mutable "buffer" pattern				tempPattern = pattern;				// swap in the escape pattern				pattern = context.rules.getEscapePattern();				tempEscaped = escaped;				b = handleRule(info, line, rule);				// swap back the buffer pattern				pattern = tempPattern;				if (!b)				{					if (tempEscaped) escaped = false;					continue;				}			}			// if we are inside a span, check for its end sequence			rule = context.inRule;			if(rule != null && (rule.action & SPAN) == SPAN)			{				pattern.array = rule.searchChars;				pattern.count = rule.sequenceLengths[1];				pattern.offset = rule.sequenceLengths[0];				// if we match the end of the span, or if this is a "hard" span,				// we continue to the next character; otherwise, we check all				// applicable rules below				if (!handleRule(info,line,rule)					|| (rule.action & SOFT_SPAN) == 0)				{					escaped = false;					continue;				}			}			// now check every rule			rule = context.rules.getRules(line.array[pos]);			while(rule != null)			{				pattern.array = rule.searchChars;				if (context.inRule == rule && (rule.action & SPAN) == SPAN)				{					pattern.count = rule.sequenceLengths[1];					pattern.offset = rule.sequenceLengths[0];				}				else				{					pattern.count = rule.sequenceLengths[0];					pattern.offset = 0;				}				// stop checking rules if there was a match and go to next pos				if (!handleRule(info,line,rule))					break;				rule = rule.next;			}			escaped = false;		}		// check for keywords at the line's end		if(context.inRule == null)			markKeyword(info, line, lastKeyword, lineLength);		// mark all remaining characters		if(lastOffset != lineLength)		{			if (context.inRule == null)			{				info.addToken(lineLength - lastOffset,					context.rules.getDefault());			}			else if (				(context.inRule.action & SPAN) == SPAN &&				(context.inRule.action & (NO_LINE_BREAK | NO_WORD_BREAK)) != 0			)			{				info.addToken(lineLength - lastOffset,Token.INVALID);				context.inRule = null;			}			else			{				info.addToken(lineLength - lastOffset,context.inRule.token);				if((context.inRule.action & MARK_FOLLOWING) == MARK_FOLLOWING)				{					context.inRule = null;				}			}		}		info.context = context;	}	// private members	private static final int SOFT_SPAN = MARK_FOLLOWING | NO_WORD_BREAK;	private String name;	private String rulePfx;	private Hashtable ruleSets;	private LineContext context;	private Segment pattern = new Segment(new char[0],0,0);	private int lastOffset;	private int lastKeyword;	private int lineLength;	private int pos;	private boolean escaped;	/**	 * Checks if the rule matches the line at the current position	 * and handles the rule if it does match	 * @param line Segment to check rule against	 * @param checkRule ParserRule to check against line	 * @return true,  keep checking other rules	 *     <br>false, stop checking other rules	 */	private boolean handleRule(Buffer.LineInfo info, Segment line,		ParserRule checkRule)	{		if (pattern.count == 0) return true;		if (lineLength - pos < pattern.count) return true;		char a, b;		for (int k = 0; k < pattern.count; k++)		{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -