如何为CDT实现"input port"等组合词的关键词高亮?
解决「仅在input/output搭配时高亮port」的问题
这个问题的核心在于词法分析器的token拆分逻辑——你现在把"input port"当成单个关键词,但Eclipse的C/C++词法分析会把它拆成两个独立的token:input和port,所以直接添加短语关键词根本不会被识别到。要实现「仅在和input/output搭配时高亮port」的效果,得从词法分析的上下文判断入手,而不是简单扩展关键词列表。
下面是具体的实现步骤:
1. 自定义Scanner,添加上下文判断逻辑
默认的GPPScanner只会根据单个token匹配关键词,我们需要继承它并扩展token识别逻辑,在扫描到port时检查它的前一个有效token是否是input或output:
import org.eclipse.cdt.internal.core.parser.scanner.GPPScanner; import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.core.parser.IScannerExtensionConfiguration; import org.eclipse.cdt.core.parser.ParserLanguage; import java.io.Reader; public class MyCustomScanner extends GPPScanner { private String previousToken; // 记录上一个有效token的内容 public MyCustomScanner(Reader reader, IScannerExtensionConfiguration config, ParserLanguage language) { super(reader, config, language); this.previousToken = ""; } @Override public int nextToken() { int tokenType = super.nextToken(); // 跳过空白、注释等无效token,只记录有效标识符/关键词 if (tokenType != IToken.TokenWhitespace && tokenType != IToken.TokenComment) { String currentToken = getCurrentTokenSource(); // 当前token是port,检查前一个token是否是input/output if ("port".equals(currentToken) && tokenType == IToken.TokenIdentifier) { if ("input".equals(previousToken) || "output".equals(previousToken)) { // 符合上下文,将port标记为关键词 tokenType = IToken.TokenKeyword; } } // 更新上一个token记录 previousToken = currentToken; } return tokenType; } }
这里的关键是:
- 维护
previousToken记录上一个有效token的内容 - 当扫描到
port且它是普通标识符时,检查前一个token是否是input或output,如果是就把它的token类型改成关键词 - 跳过空白和注释,避免错误判断上下文
2. 在plugin.xml中关联自定义Scanner
找到你定义自定义语言的扩展点,指定你的Scanner实现类:
<extension point="org.eclipse.cdt.core.Language"> <language id="com.yourplugin.mylanguage" name="My Custom Language" scannerClass="com.yourplugin.scanner.MyCustomScanner" parserClass="org.eclipse.cdt.internal.core.parser.GPPParser" ...> </language> </extension>
3. 调整关键词列表,移除无效短语
修改你的MyLanguageKeywords,只保留单个关键词,去掉input port和output port(因为它们不会被词法分析器识别为单个token):
public class MyLanguageKeywords extends CLanguageKeywords { public MyLanguageKeywords(ParserLanguage language, IScannerExtensionConfiguration config) { super(language, config); } @Override public String[] getKeywords() { String[] cppKeywords = super.getKeywords(); String[] myKeywords = new String[] { "input", "output" }; return (String[]) ArrayUtils.addAll(cppKeywords, myKeywords); } }
额外注意事项
- 注释处理:如果不想让注释里的
input port高亮,可以在判断时添加!isInComment()的条件(Scanner提供了isInComment()方法) - 多空格/换行:词法分析器会忽略空白符,所以
input port或者换行后的input\nport都会被正确识别 - 缓存清理:修改后记得重启Eclipse或者重新构建插件项目,确保自定义类被正确加载
内容的提问来源于stack exchange,提问作者Sadık
相关产品推荐
相关产品推荐

