我正在使用自定义语言的编辑器插件,并且我已设法设置它,以便突出显示所有必要的关键字。问题是即使单词是另一个单词的一部分,单词也会突出显示。
例如:我们说public
是一个关键字,我初始化一个名为publicVar
的变量,因此它看起来像public int publicVar
。 public
按预期突出显示,但公众' publicVar
的一部分也会突出显示,这不是我想要的。
public WFSPartitionScanner()
{
int index = 0;
int numOfRules = 5 + reversedWords.length + commonFunctions.length+directives.length +
BIFs.length + operators.length + strongOperators.length;
IToken string = new Token(WFS_STRING);
IToken comment = new Token(WFS_COMMENT);
IToken reversedWord = new Token(WFS_REVERSED_WORD);
IToken commonFunction = new Token(WFS_COMMON_FUNCTION);
IToken directive = new Token(WFS_DIRECTIVE);
IToken bif = new Token(WFS_BIF);
IToken operator = new Token(WFS_OPERATOR);
IToken strongOperator = new Token(WFS_STRONG_OPERATOR);
IToken numberToken = new Token(WFS_NUMBER);
IPredicateRule[] rules= new IPredicateRule[numOfRules];
rules[index] = new MultiLineRule("\"","\"", string, '\\');
rules[++index] = new MultiLineRule("\'", "\'", string, '\\');
rules[++index] = new SingleLineRule("//","\n", comment);
rules[++index] = new MultiLineRule("/*", "*/", comment);
rules[++index] = new WFSNumberRule(numberToken);
for(int i = 0; i < reversedWords.length; i++)
{
rules[++index] = new WordPatternRule(new WordDetector(reversedWords[i]), reversedWords[i], "",reversedWord);
}
for(int i = 0; i < commonFunctions.length; i++)
{
rules[++index] = new WordPatternRule(new WordDetector(commonFunctions[i]), commonFunctions[i], "",commonFunction);
}
for(int i = 0; i < BIFs.length;i++)
{
rules[++index] = new WordPatternRule(new WordDetector(BIFs[i]), BIFs[i], "",bif);
}
for(int i = 0; i < directives.length;i++)
{
rules[++index] = new WordPatternRule(new WordDetector(directives[i]), directives[i], "",directive);
}
for(int i=0; i < operators.length; i++)
{
rules[++index]= new WordPatternRule(new WordDetector(operators[i]), operators[i], "", operator);
}
for(int i=0; i < strongOperators.length; i++)
{
rules[++index]= new WordPatternRule(new WordDetector(strongOperators[i]), strongOperators[i], "", strongOperator);
}
setPredicateRules(rules);
}
public class WordDetector implements IWordDetector{
private char start;
private char[] part;
public WordDetector(String word)
{
this.start = word.charAt(0);
this.part = new char[word.length() - 1];
for(int i = 1; i < word.length(); i++)
{
part[i-1] = word.charAt(i);
}
}
@Override
public boolean isWordPart(char c) {
for(int i = 0; i < part.length; i++)
{
if(c == part[i])
{
return true;
}
}
return false;
}
@Override
public boolean isWordStart(char c) {
return (c == start);
}
}
我还尝试更改WordPatternRule
来自
WordPatternRule(new WordDetector('KEYWORD'), 'KEYWORD', "",reversedWord);
到
WordPatternRule(new WordDetector('KEYWORD'), 'FIRST LETTER OF KEYWORD', 'LAST LETTER OF KEYWORD,reversedWord);
但我得到了相同的结果。
答案 0 :(得分:0)
好的我找出了部分问题。为了解决这个问题,我制作了自己的单词
public class WFSWordRule extends WordRule implements IPredicateRule{
private IToken successToken;
public WFSWordRule(IWordDetector detector, String[] keywords, IToken token ) {
super(detector);
this.successToken= token;
for (String word : keywords) {
addWord(word, token);
}
}
@Override
public IToken evaluate(ICharacterScanner scanner, boolean arg1) {
return super.evaluate(scanner);
}
@Override
public IToken getSuccessToken() {
return successToken;
}
}
但是,这并没有完全解决问题。现在,如果单词末尾有关键字,则关键字仍会突出显示。使用与以前相同的示例,如果我有一个关键字&#39; Public&#39;我有一个名为&#39; varPublic&#39;两种情况都突出了公众。但如果我有一个名为&#39; PublicVar&#39;公众没有突出显示。任何提示?答案 1 :(得分:0)
如果你试图突出显示单词,而不是单词的一部分,我认为你应该使用WordRule而不是WordPatternRule。据我所知,WordPatternRule用于查找单词中的模式,而WordRule用于查找单个单词。
我已经在Eclipse插件中使用过WordRules,我一直在努力工作,而且我不会在其他单词中突出显示单词的问题。您可以查看its code并将其用作示例。基本上,它需要IWordDetector实现,并使用其 addWord 方法添加您想要检测的所有单词。
与greg-449提到的CombinedWordRule不同,它是您已经使用的JFace框架的公共部分。
答案 2 :(得分:0)
不确定,如果这仍然有用,但我通过覆盖扫描程序中的方法nextToken
来解决此问题:
public IToken nextToken() {
if (this.fContentType == null || this.fRules == null) {
// don't try to resume
this.fTokenOffset = this.fOffset;
this.fColumn = RuleBasedScanner.UNDEFINED;
if (this.fRules != null) {
for (IRule fRule : this.fRules) {
IToken token = fRule.evaluate(this);
try {
if (!token.isUndefined()) {
if (this.fTokenOffset > 0 && (isWordEnd(this.fDocument.getChar(this.fTokenOffset - 1))
|| isSpecialKey(this.fDocument.getChar(this.fTokenOffset)))) {
this.fContentType = null;
return token;
}
}
} catch (BadLocationException ex) {
ex.printStackTrace();
}
}
}
if (this.read() == ICharacterScanner.EOF) {
return Token.EOF;
}
return this.fDefaultReturnToken;
}
}
isWordEnd检查:
c == (char) 0 || c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '(' || c == ')' || c == ',' || c == ';'
isSpecialKey检查:
c == '%'
对于另一个问题,您已修复,我在我的规则中重新实现了endSequenceDetected
方法:
@Override
protected boolean endSequenceDetected(ICharacterScanner scanner) {
int c = scanner.read();
scanner.unread();
return isWordEnd((char) c);
}