package org.jtwig.parser.parboiled.base; import org.jtwig.parser.parboiled.ParserContext; import org.jtwig.parser.parboiled.model.Keyword; import org.parboiled.Rule; import org.parboiled.annotations.Label; import java.util.Collection; public class LexicParser extends BasicParser<String> { final Collection<String> extraKeywords; Rule[] keywordRules = null; LexicParser(ParserContext context, Collection<String> extraKeywords) { super(LexicParser.class, context); this.extraKeywords = extraKeywords; } public Rule Identifier() { Rule identifier = Sequence( TestNot(Keyword()), Letter() ); if (keywordRules.length == 0) { identifier = Letter(); } return Sequence( identifier, ZeroOrMore(LetterOrDigit()) ); } @Label("Keywork") public Rule Keyword(Keyword keyword) { return Sequence( String(keyword.toString()), TestNot( LetterOrDigit() ) ); } @Label("Keywork") public Rule Keyword(String keyword) { return Sequence( String(keyword), TestNot( LetterOrDigit() ) ); } Rule Keyword() { return FirstOf( keywordRules() ); } Rule[] keywordRules() { Keyword[] keywords = Keyword.values(); keywordRules = new Rule[keywords.length + extraKeywords.size()]; int i = 0; for (; i < keywords.length; i++) { keywordRules[i] = Keyword(keywords[i]); } for (String extraKeyword : extraKeywords) { keywordRules[i++] = Keyword(extraKeyword); } return keywordRules; } public Rule Letter() { return FirstOf(CharRange('a', 'z'), CharRange('A', 'Z'), '_', '$'); } public Rule LetterOrDigit() { return FirstOf(CharRange('a', 'z'), CharRange('A', 'Z'), CharRange('0', '9'), '_', '$'); } }