blob: 28f00374ff71fa8597cc8d1b1f03ba21047f7e2f [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
8#include "regex-pattern-list-matcher.hpp"
9#include "regex-backref-matcher.hpp"
10#include "regex-repeat-matcher.hpp"
11
12#include "../logging.hpp"
13
14INIT_LOGGER ("RegexPatternListMatcher");
15
16using namespace std;
17
18namespace ndn
19{
20RegexPatternListMatcher::RegexPatternListMatcher(const string expr, ptr_lib::shared_ptr<RegexBackrefManager> backrefManager)
21 :RegexMatcher(expr, EXPR_PATTERNLIST, backrefManager)
22{
23 // _LOG_TRACE ("Enter RegexPatternListMatcher Constructor");
24 compile();
25 // _LOG_TRACE ("Exit RegexPatternListMatcher Constructor");
26}
27
28void
29RegexPatternListMatcher::compile()
30{
31 // _LOG_TRACE ("Enter RegexPatternListMatcher::compile");
32
33 const int len = m_expr.size();
34 int index = 0;
35 int subHead = index;
36
37 while(index < len){
38 subHead = index;
39
40 if(!extractPattern(subHead, &index))
41 throw RegexMatcher::Error("RegexPatternListMatcher compile: cannot compile");
42 }
43 // _LOG_TRACE ("Exit RegexPatternListMatcher::compile");
44}
45
46bool
47RegexPatternListMatcher::extractPattern(int index, int* next)
48{
49 // _LOG_DEBUG ("Enter RegexPatternListMatcher::ExtractPattern()");
50
51 string errMsg = "Error: RegexPatternListMatcher.ExtractSubPattern(): ";
52
53 const int start = index;
54 int end = index;
55 int indicator = index;
56
57
58 // _LOG_DEBUG ("m_expr: " << m_expr << " index: " << index);
59
60 switch(m_expr[index]){
61 case '(':
62 index++;
63 index = extractSubPattern('(', ')', index);
64 indicator = index;
65 end = extractRepetition(index);
66 if(indicator == end){
67 ptr_lib::shared_ptr<RegexMatcher> matcher = ptr_lib::make_shared<RegexBackrefMatcher>(m_expr.substr(start, end - start), m_backrefManager);
68 m_backrefManager->pushRef(matcher);
69 boost::dynamic_pointer_cast<RegexBackrefMatcher>(matcher)->lateCompile();
70
71 m_matcherList.push_back(matcher);
72 }
73 else
74 m_matcherList.push_back(ptr_lib::make_shared<RegexRepeatMatcher>(m_expr.substr(start, end - start), m_backrefManager, indicator - start));
75 break;
76
77 case '<':
78 index++;
79 index = extractSubPattern ('<', '>', index);
80 indicator = index;
81 end = extractRepetition(index);
82 m_matcherList.push_back(ptr_lib::make_shared<RegexRepeatMatcher>(m_expr.substr(start, end - start), m_backrefManager, indicator - start));
83 break;
84
85 case '[':
86 index++;
87 index = extractSubPattern ('[', ']', index);
88 indicator = index;
89 end = extractRepetition(index);
90 m_matcherList.push_back(ptr_lib::make_shared<RegexRepeatMatcher>(m_expr.substr(start, end - start), m_backrefManager, indicator - start));
91 break;
92
93 default:
94 throw RegexMatcher::Error("Error: unexpected syntax");
95 }
96
97 *next = end;
98
99 return true;
100}
101
102int
103RegexPatternListMatcher::extractSubPattern(const char left, const char right, int index)
104{
105 // _LOG_DEBUG ("Enter RegexPatternListMatcher::ExtractSubPattern()");
106
107 int lcount = 1;
108 int rcount = 0;
109
110 while(lcount > rcount){
111
112 if(index >= m_expr.size())
113 throw RegexMatcher::Error("Error: parenthesis mismatch");
114
115 if(left == m_expr[index])
116 lcount++;
117
118 if(right == m_expr[index])
119 rcount++;
120
121 index++;
122 }
123 return index;
124}
125
126int
127RegexPatternListMatcher::extractRepetition(int index)
128{
129 // _LOG_DEBUG ("Enter RegexPatternListMatcher::ExtractRepetition()");
130
131 int exprSize = m_expr.size();
132
133 // _LOG_DEBUG ("expr: " << m_expr << " index: " << index << " char: " << (index == exprSize ? 0 : m_expr[index]));
134
135 string errMsg = "Error: RegexPatternListMatcher.ExtractRepetition(): ";
136
137 if(index == exprSize)
138 return index;
139
140 if(('+' == m_expr[index] || '?' == m_expr[index] || '*' == m_expr[index])){
141 return ++index;
142 }
143
144
145 if('{' == m_expr[index]){
146 while('}' != m_expr[index]){
147 index++;
148 if(index == exprSize)
149 break;
150 }
151 if(index == exprSize)
152 throw RegexMatcher::Error(errMsg + "Missing right brace bracket");
153 else
154 return ++index;
155 }
156 else{
157 // _LOG_DEBUG ("return index: " << index);
158 return index;
159 }
160}
161
162}//ndn