blob: 3ae74f11ef2227b20fdc8da4561df5bb0475eedd [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);
Yingdi Yu5e974202014-01-29 16:59:06 -080023
24 virtual ~RegexPatternListMatcher(){};
25
26protected:
27 virtual void
28 compile();
29
30private:
31 bool
32 extractPattern(int index, int* next);
33
34 int
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070035 extractSubPattern(const char left, const char right, size_t index);
Yingdi Yu5e974202014-01-29 16:59:06 -080036
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}
56
57inline void
58RegexPatternListMatcher::compile()
59{
60 const int len = m_expr.size();
61 int index = 0;
62 int subHead = index;
63
64 while(index < len){
65 subHead = index;
66
67 if(!extractPattern(subHead, &index))
68 throw RegexMatcher::Error("RegexPatternListMatcher compile: cannot compile");
69 }
70}
71
72inline bool
73RegexPatternListMatcher::extractPattern(int index, int* next)
74{
75 // std::string errMsg = "Error: RegexPatternListMatcher.ExtractSubPattern(): ";
76
77 const int start = index;
78 int end = index;
79 int indicator = index;
80
81 switch(m_expr[index]){
82 case '(':
83 index++;
84 index = extractSubPattern('(', ')', index);
85 indicator = index;
86 end = extractRepetition(index);
87 if(indicator == end){
88 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;
97
98 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}
122
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
131 if(index >= m_expr.size())
132 throw RegexMatcher::Error("Error: parenthesis mismatch");
133
134 if(left == m_expr[index])
135 lcount++;
136
137 if(right == m_expr[index])
138 rcount++;
139
140 index++;
141 }
142 return index;
143}
144
145inline 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
150 if(index == exprSize)
151 return index;
152
153 if(('+' == m_expr[index] || '?' == m_expr[index] || '*' == m_expr[index])){
154 return ++index;
155 }
156
157 if('{' == m_expr[index]){
158 while('}' != m_expr[index]){
159 index++;
160 if(index == exprSize)
161 break;
162 }
163 if(index == exprSize)
164 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