blob: b8c0b007c52d838c47a96c365458231a9801e947 [file] [log] [blame]
Qiuhan Ding699725d2015-05-24 01:41:09 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2013-2015 Regents of the University of California.
4 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
22#include "regex-pattern-list-matcher.hpp"
23
24#include "regex-repeat-matcher.hpp"
25#include "regex-backref-matcher.hpp"
26
27namespace ndn {
28
29RegexPatternListMatcher::RegexPatternListMatcher(const std::string& expr,
30 shared_ptr<RegexBackrefManager> backrefManager)
31 : RegexMatcher(expr, EXPR_PATTERN_LIST, backrefManager)
32{
33 compile();
34}
35
36RegexPatternListMatcher::~RegexPatternListMatcher()
37{
38}
39
40void
41RegexPatternListMatcher::compile()
42{
43 size_t len = m_expr.size();
44 size_t index = 0;
45 size_t subHead = index;
46
47 while (index < len) {
48 subHead = index;
49
50 if (!extractPattern(subHead, &index))
51 throw Error("Compile error");
52 }
53}
54
55bool
56RegexPatternListMatcher::extractPattern(size_t index, size_t* next)
57{
58 size_t start = index;
59 size_t end = index;
60 size_t indicator = index;
61
62 switch (m_expr[index]) {
63 case '(':
64 index++;
65 index = extractSubPattern('(', ')', index);
66 indicator = index;
67 end = extractRepetition(index);
68 if (indicator == end) {
69 auto matcher = make_shared<RegexBackrefMatcher>(m_expr.substr(start, end - start),
70 m_backrefManager);
71 m_backrefManager->pushRef(matcher);
72 dynamic_pointer_cast<RegexBackrefMatcher>(matcher)->lateCompile();
73
74 m_matchers.push_back(matcher);
75 }
76 else
77 m_matchers.push_back(make_shared<RegexRepeatMatcher>(m_expr.substr(start, end - start),
78 m_backrefManager, indicator - start));
79 break;
80
81 case '<':
82 index++;
83 index = extractSubPattern('<', '>', index);
84 indicator = index;
85 end = extractRepetition(index);
86 m_matchers.push_back(make_shared<RegexRepeatMatcher>(m_expr.substr(start, end - start),
87 m_backrefManager, indicator - start));
88 break;
89
90 case '[':
91 index++;
92 index = extractSubPattern('[', ']', index);
93 indicator = index;
94 end = extractRepetition(index);
95 m_matchers.push_back(make_shared<RegexRepeatMatcher>(m_expr.substr(start, end - start),
96 m_backrefManager, indicator - start));
97 break;
98
99 default:
100 throw Error("Unexpected syntax");
101 }
102
103 *next = end;
104
105 return true;
106}
107
108int
109RegexPatternListMatcher::extractSubPattern(const char left, const char right, size_t index)
110{
111 size_t lcount = 1;
112 size_t rcount = 0;
113
114 while (lcount > rcount) {
115
116 if (index >= m_expr.size())
117 throw Error("Parenthesis mismatch");
118
119 if (left == m_expr[index])
120 lcount++;
121
122 if (right == m_expr[index])
123 rcount++;
124
125 index++;
126 }
127 return index;
128}
129
130int
131RegexPatternListMatcher::extractRepetition(size_t index)
132{
133 size_t exprSize = m_expr.size();
134
135 if (index == exprSize)
136 return index;
137
138 if (('+' == m_expr[index] || '?' == m_expr[index] || '*' == m_expr[index])) {
139 return ++index;
140 }
141
142 if ('{' == m_expr[index]) {
143 while ('}' != m_expr[index]) {
144 index++;
145 if (index == exprSize)
146 break;
147 }
148 if (index == exprSize)
149 throw Error("Missing right brace bracket");
150 else
151 return ++index;
152 }
153 else {
154 return index;
155 }
156}
157
158} // namespace ndn
159