1#ifndef TEXTMATELIB_MATCHER_H
2#define TEXTMATELIB_MATCHER_H
13using Matcher = std::function<bool(
const T&)>;
17struct MatcherWithPriority {
21 MatcherWithPriority() : priority(0) {}
22 MatcherWithPriority(
const Matcher<T>& m,
int p) : matcher(m), priority(p) {}
26bool isIdentifier(
const std::string& token);
27bool isIdentifier(
const std::string* token);
30class SelectorTokenizer {
36 explicit SelectorTokenizer(
const std::string& input);
42std::vector<MatcherWithPriority<T>> createMatchers(
43 const std::string& selector,
44 std::function<
bool(
const std::vector<std::string>&,
const T&)> matchesName
46 std::vector<MatcherWithPriority<T>> results;
47 SelectorTokenizer tokenizer(selector);
48 std::string* token = tokenizer.next();
51 std::function<Matcher<T>(std::string*&)> parseOperand;
52 std::function<Matcher<T>(std::string*&)> parseConjunction;
53 std::function<Matcher<T>(std::string*&)> parseInnerExpression;
56 parseOperand = [&](std::string*& tok) -> Matcher<T> {
57 if (tok && *tok ==
"-") {
59 tok = tokenizer.next();
60 Matcher<T> expressionToNegate = parseOperand(tok);
61 return [expressionToNegate](
const T& matcherInput) ->
bool {
62 return expressionToNegate ? !expressionToNegate(matcherInput) : true;
65 if (tok && *tok ==
"(") {
67 tok = tokenizer.next();
68 Matcher<T> expressionInParents = parseInnerExpression(tok);
69 if (tok && *tok ==
")") {
71 tok = tokenizer.next();
73 return expressionInParents;
75 if (isIdentifier(tok)) {
76 std::vector<std::string> identifiers;
77 while (isIdentifier(tok)) {
78 identifiers.push_back(*tok);
80 tok = tokenizer.next();
82 return [identifiers, matchesName](
const T& matcherInput) ->
bool {
83 return matchesName(identifiers, matcherInput);
90 parseConjunction = [&](std::string*& tok) -> Matcher<T> {
91 std::vector<Matcher<T>> matchers;
92 Matcher<T> matcher = parseOperand(tok);
94 matchers.push_back(matcher);
95 matcher = parseOperand(tok);
97 return [matchers](
const T& matcherInput) ->
bool {
98 for (
const auto& m : matchers) {
99 if (!m(matcherInput)) {
108 parseInnerExpression = [&](std::string*& tok) -> Matcher<T> {
109 std::vector<Matcher<T>> matchers;
110 Matcher<T> matcher = parseConjunction(tok);
112 matchers.push_back(matcher);
113 if (tok && (*tok ==
"|" || *tok ==
",")) {
116 tok = tokenizer.next();
117 }
while (tok && (*tok ==
"|" || *tok ==
","));
121 matcher = parseConjunction(tok);
123 return [matchers](
const T& matcherInput) ->
bool {
124 for (
const auto& m : matchers) {
125 if (m(matcherInput)) {
134 while (token !=
nullptr) {
136 if (token->length() == 2 && token->at(1) ==
':') {
137 switch (token->at(0)) {
138 case 'R': priority = 1;
break;
139 case 'L': priority = -1;
break;
145 token = tokenizer.next();
147 Matcher<T> matcher = parseConjunction(token);
148 results.push_back(MatcherWithPriority<T>(matcher, priority));
149 if (token ==
nullptr || *token !=
",") {
153 token = tokenizer.next();
156 if (token !=
nullptr) {
Core type definitions and interfaces for TextMateLib.