blob: d6e3a7209212eef1af3ae7390b2f12ce42e83cd1 [file] [log] [blame]
Yingdi Yu5e974202014-01-29 16:59:06 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07003 * Copyright (c) 2013-2014, Regents of the University of California.
4 * All rights reserved.
5 *
6 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
7 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
8 *
9 * This file licensed under New BSD License. See COPYING for detailed information about
10 * ndn-cxx library copyright, permissions, and redistribution restrictions.
11 *
12 * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
Yingdi Yu5e974202014-01-29 16:59:06 -080013 */
14
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080015#ifndef NDN_UTIL_REGEX_REGEX_PATTERN_LIST_MATCHER_HPP
16#define NDN_UTIL_REGEX_REGEX_PATTERN_LIST_MATCHER_HPP
Yingdi Yu5e974202014-01-29 16:59:06 -080017
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080018#include "../../common.hpp"
Yingdi Yu5e974202014-01-29 16:59:06 -080019
20#include "regex-matcher.hpp"
21
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080022namespace ndn {
23
24class RegexBackrefManager;
Yingdi Yu5e974202014-01-29 16:59:06 -080025
26class RegexPatternListMatcher : public RegexMatcher
27{
28public:
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080029 RegexPatternListMatcher(const std::string& expr, shared_ptr<RegexBackrefManager> backRefManager);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070030
Yingdi Yu5e974202014-01-29 16:59:06 -080031 virtual ~RegexPatternListMatcher(){};
32
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070033protected:
34 virtual void
Yingdi Yu5e974202014-01-29 16:59:06 -080035 compile();
36
37private:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070038 bool
Yingdi Yu5e974202014-01-29 16:59:06 -080039 extractPattern(int index, int* next);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070040
41 int
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070042 extractSubPattern(const char left, const char right, size_t index);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070043
44 int
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070045 extractRepetition(size_t index);
Yingdi Yu5e974202014-01-29 16:59:06 -080046
47private:
48
49};
Yingdi Yu5e974202014-01-29 16:59:06 -080050
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080051} // namespace ndn
52
53#include "regex-repeat-matcher.hpp"
54#include "regex-backref-matcher.hpp"
55
56namespace ndn {
57
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070058inline
59RegexPatternListMatcher::RegexPatternListMatcher(const std::string& expr,
60 shared_ptr<RegexBackrefManager> backrefManager)
61 : RegexMatcher(expr, EXPR_PATTERNLIST, backrefManager)
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080062{
63 compile();
64}
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070065
66inline void
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080067RegexPatternListMatcher::compile()
68{
69 const int len = m_expr.size();
70 int index = 0;
71 int subHead = index;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070072
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080073 while(index < len){
74 subHead = index;
75
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070076 if (!extractPattern(subHead, &index))
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080077 throw RegexMatcher::Error("RegexPatternListMatcher compile: cannot compile");
78 }
79}
80
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070081inline bool
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080082RegexPatternListMatcher::extractPattern(int index, int* next)
83{
84 // std::string errMsg = "Error: RegexPatternListMatcher.ExtractSubPattern(): ";
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070085
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080086 const int start = index;
87 int end = index;
88 int indicator = index;
89
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070090 switch (m_expr[index]){
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080091 case '(':
92 index++;
93 index = extractSubPattern('(', ')', index);
94 indicator = index;
95 end = extractRepetition(index);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070096 if (indicator == end){
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070097 shared_ptr<RegexMatcher> matcher =
98 make_shared<RegexBackrefMatcher>(m_expr.substr(start, end - start), m_backrefManager);
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080099 m_backrefManager->pushRef(matcher);
100 boost::dynamic_pointer_cast<RegexBackrefMatcher>(matcher)->lateCompile();
101
102 m_matcherList.push_back(matcher);
103 }
104 else
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -0700105 m_matcherList.push_back(make_shared<RegexRepeatMatcher>(m_expr.substr(start, end - start),
106 m_backrefManager, indicator - start));
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800107 break;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700108
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800109 case '<':
110 index++;
111 index = extractSubPattern ('<', '>', index);
112 indicator = index;
113 end = extractRepetition(index);
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -0700114 m_matcherList.push_back(make_shared<RegexRepeatMatcher>(m_expr.substr(start, end - start),
115 m_backrefManager, indicator - start));
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800116 break;
117
118 case '[':
119 index++;
120 index = extractSubPattern ('[', ']', index);
121 indicator = index;
122 end = extractRepetition(index);
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -0700123 m_matcherList.push_back(make_shared<RegexRepeatMatcher>(m_expr.substr(start, end - start),
124 m_backrefManager, indicator - start));
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800125 break;
126
127 default:
128 throw RegexMatcher::Error("Error: unexpected syntax");
129 }
130
131 *next = end;
132
133 return true;
134}
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700135
136inline int
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700137RegexPatternListMatcher::extractSubPattern(const char left, const char right, size_t index)
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800138{
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700139 size_t lcount = 1;
140 size_t rcount = 0;
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800141
142 while(lcount > rcount){
143
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700144 if (index >= m_expr.size())
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800145 throw RegexMatcher::Error("Error: parenthesis mismatch");
146
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700147 if (left == m_expr[index])
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800148 lcount++;
149
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700150 if (right == m_expr[index])
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800151 rcount++;
152
153 index++;
154 }
155 return index;
156}
157
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700158inline int
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700159RegexPatternListMatcher::extractRepetition(size_t index)
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800160{
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700161 size_t exprSize = m_expr.size();
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800162
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700163 if (index == exprSize)
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800164 return index;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700165
166 if (('+' == m_expr[index] || '?' == m_expr[index] || '*' == m_expr[index])){
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800167 return ++index;
168 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700169
170 if ('{' == m_expr[index]){
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800171 while('}' != m_expr[index]){
172 index++;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700173 if (index == exprSize)
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800174 break;
175 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700176 if (index == exprSize)
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800177 throw RegexMatcher::Error(std::string("Error: RegexPatternListMatcher.ExtractRepetition(): ")
178 + "Missing right brace bracket");
179 else
180 return ++index;
181 }
182 else {
183 return index;
184 }
185}
186
187
188} // namespace ndn
189
190#endif // NDN_UTIL_REGEX_REGEX_PATTERN_LIST_MATCHER_HPP