/*******************************************************************************
* Copyright (c) 2015 Bruno Medeiros and other Contributors.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Bruno Medeiros - initial API and implementation
*******************************************************************************/
package com.github.rustdt.tooling.lexer;
import static melnorme.utilbox.core.CoreUtil.areEqual;
import melnorme.lang.tooling.parser.lexer.CharacterReader_SubReader;
import melnorme.lang.tooling.parser.lexer.WordLexerRule;
import melnorme.lang.utils.parse.ICharacterReader;
import melnorme.lang.utils.parse.LexingUtils;
/**
* A lexer rule used for coloring purposes.
*/
public class RustWordLexerRule extends WordLexerRule<RustColoringTokens> {
public static final String[] keywords_control = {
"abstract", "alignof", "as", "become", "box", "break", "const", "continue", "crate",
"do", "else", "enum", "extern", "final", "fn", "for", "if", "impl", "in", "let",
"loop", "macro", "match", "mod", "move", "mut", "offsetof", "override",
"priv", "proc", "pub", "pure", "ref", "return", "sizeof", "static", "struct",
"trait", "type", "typeof", "unsafe", "unsized", "use", "virtual", "where", "while", "yield"
};
public static final String[] keywords_boolean_lit = {
"true", "false",
};
public static final String[] keywords_self = {
"self", "Self", "super"
};
/* ----------------- ----------------- */
protected final RustNumberLexingRule rustNumberLexingRule = new RustNumberLexingRule();
public RustWordLexerRule() {
super(RustColoringTokens.WS, RustColoringTokens.WORD);
addKeywords(RustColoringTokens.KEYWORD, RustWordLexerRule.keywords_control);
addKeywords(RustColoringTokens.KEYWORD_BOOL, RustWordLexerRule.keywords_boolean_lit);
addKeywords(RustColoringTokens.KEYWORD_SELF, RustWordLexerRule.keywords_self);
}
@Override
public RustColoringTokens doEvaluateToken(ICharacterReader reader) {
if(reader.tryConsume('?')) {
return RustColoringTokens.TRY_OP;
}
RustColoringTokens result = super.doEvaluateToken(reader);
if(result == null) {
if(rustNumberLexingRule.tryMatch(reader)) {
return RustColoringTokens.NUMBER;
}
}
if(result != defaultWordToken) {
return result;
}
// We found a word then. Let's see if it's a macro invocation
CharacterReader_SubReader subReader = new CharacterReader_SubReader(reader);
LexingUtils.skipWhitespace(subReader);
if(subReader.tryConsume('!')) {
int afterWS = LexingUtils.countWhitespace(subReader);
int lookahead = subReader.lookahead(afterWS);
if(areEqual(lastEvaluatedWord, "macro_rules")) {
subReader.consumeInParentReader();
return RustColoringTokens.MACRO_RULES;
}
if(lookahead == '(' || lookahead == '[') {
subReader.consumeInParentReader();
return RustColoringTokens.MACRO_CALL;
}
}
return result;
}
}