blob: 12e3c68bf15a3afab4a818be080ddf0be73da12f [file] [log] [blame]
Yingdi Yu5e974202014-01-29 16:59:06 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
3 * Copyright (C) 2013 Regents of the University of California.
4 * @author: Yingdi Yu <yingdi@cs.ucla.edu>
5 * See COPYING for copyright and distribution information.
6 */
7
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -08008#ifndef NDN_UTIL_REGEX_REGEX_PATTERN_LIST_MATCHER_HPP
9#define NDN_UTIL_REGEX_REGEX_PATTERN_LIST_MATCHER_HPP
Yingdi Yu5e974202014-01-29 16:59:06 -080010
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080011#include "../../common.hpp"
Yingdi Yu5e974202014-01-29 16:59:06 -080012
13#include "regex-matcher.hpp"
14
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080015namespace ndn {
16
17class RegexBackrefManager;
Yingdi Yu5e974202014-01-29 16:59:06 -080018
19class RegexPatternListMatcher : public RegexMatcher
20{
21public:
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080022 RegexPatternListMatcher(const std::string& expr, shared_ptr<RegexBackrefManager> backRefManager);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070023
Yingdi Yu5e974202014-01-29 16:59:06 -080024 virtual ~RegexPatternListMatcher(){};
25
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070026protected:
27 virtual void
Yingdi Yu5e974202014-01-29 16:59:06 -080028 compile();
29
30private:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070031 bool
Yingdi Yu5e974202014-01-29 16:59:06 -080032 extractPattern(int index, int* next);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070033
34 int
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070035 extractSubPattern(const char left, const char right, size_t index);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070036
37 int
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070038 extractRepetition(size_t index);
Yingdi Yu5e974202014-01-29 16:59:06 -080039
40private:
41
42};
Yingdi Yu5e974202014-01-29 16:59:06 -080043
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080044} // namespace ndn
45
46#include "regex-repeat-matcher.hpp"
47#include "regex-backref-matcher.hpp"
48
49namespace ndn {
50
51inline RegexPatternListMatcher::RegexPatternListMatcher(const std::string& expr, shared_ptr<RegexBackrefManager> backrefManager)
52 :RegexMatcher(expr, EXPR_PATTERNLIST, backrefManager)
53{
54 compile();
55}
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070056
57inline void
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080058RegexPatternListMatcher::compile()
59{
60 const int len = m_expr.size();
61 int index = 0;
62 int subHead = index;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070063
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080064 while(index < len){
65 subHead = index;
66
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070067 if (!extractPattern(subHead, &index))
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080068 throw RegexMatcher::Error("RegexPatternListMatcher compile: cannot compile");
69 }
70}
71
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070072inline bool
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080073RegexPatternListMatcher::extractPattern(int index, int* next)
74{
75 // std::string errMsg = "Error: RegexPatternListMatcher.ExtractSubPattern(): ";
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070076
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080077 const int start = index;
78 int end = index;
79 int indicator = index;
80
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070081 switch (m_expr[index]){
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080082 case '(':
83 index++;
84 index = extractSubPattern('(', ')', index);
85 indicator = index;
86 end = extractRepetition(index);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070087 if (indicator == end){
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080088 shared_ptr<RegexMatcher> matcher = make_shared<RegexBackrefMatcher>(m_expr.substr(start, end - start), m_backrefManager);
89 m_backrefManager->pushRef(matcher);
90 boost::dynamic_pointer_cast<RegexBackrefMatcher>(matcher)->lateCompile();
91
92 m_matcherList.push_back(matcher);
93 }
94 else
95 m_matcherList.push_back(make_shared<RegexRepeatMatcher>(m_expr.substr(start, end - start), m_backrefManager, indicator - start));
96 break;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070097
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080098 case '<':
99 index++;
100 index = extractSubPattern ('<', '>', index);
101 indicator = index;
102 end = extractRepetition(index);
103 m_matcherList.push_back(make_shared<RegexRepeatMatcher>(m_expr.substr(start, end - start), m_backrefManager, indicator - start));
104 break;
105
106 case '[':
107 index++;
108 index = extractSubPattern ('[', ']', index);
109 indicator = index;
110 end = extractRepetition(index);
111 m_matcherList.push_back(make_shared<RegexRepeatMatcher>(m_expr.substr(start, end - start), m_backrefManager, indicator - start));
112 break;
113
114 default:
115 throw RegexMatcher::Error("Error: unexpected syntax");
116 }
117
118 *next = end;
119
120 return true;
121}
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700122
123inline int
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700124RegexPatternListMatcher::extractSubPattern(const char left, const char right, size_t index)
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800125{
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700126 size_t lcount = 1;
127 size_t rcount = 0;
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800128
129 while(lcount > rcount){
130
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700131 if (index >= m_expr.size())
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800132 throw RegexMatcher::Error("Error: parenthesis mismatch");
133
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700134 if (left == m_expr[index])
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800135 lcount++;
136
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700137 if (right == m_expr[index])
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800138 rcount++;
139
140 index++;
141 }
142 return index;
143}
144
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700145inline int
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700146RegexPatternListMatcher::extractRepetition(size_t index)
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800147{
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700148 size_t exprSize = m_expr.size();
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800149
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700150 if (index == exprSize)
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800151 return index;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700152
153 if (('+' == m_expr[index] || '?' == m_expr[index] || '*' == m_expr[index])){
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800154 return ++index;
155 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700156
157 if ('{' == m_expr[index]){
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800158 while('}' != m_expr[index]){
159 index++;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700160 if (index == exprSize)
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800161 break;
162 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700163 if (index == exprSize)
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800164 throw RegexMatcher::Error(std::string("Error: RegexPatternListMatcher.ExtractRepetition(): ")
165 + "Missing right brace bracket");
166 else
167 return ++index;
168 }
169 else {
170 return index;
171 }
172}
173
174
175} // namespace ndn
176
177#endif // NDN_UTIL_REGEX_REGEX_PATTERN_LIST_MATCHER_HPP