46 using boost::match_results;
47 using boost::regex_search;
48 using boost::regex_match;
59 (
"^([\\+\\-]?((((\\d+\\.\\d*)|(\\d*\\.\\d+))([eE][\\-\\+]?\\d{1,3})?)"
60 "|(\\d+[eE][\\-\\+]?\\d{1,3})))\\s*");
81 : PolicyParser(policy), _buffer(), _lineno(0), _depth(0)
83 PAFParser::PAFParser(Policy& policy,
bool strict)
84 : PolicyParser(policy, strict), _buffer(), _lineno(0), _depth(0)
90 PAFParser::~PAFParser() { }
97 int PAFParser::parse(istream& is) {
98 int count = _parseIntoPolicy(is, _pol);
104 ios::iostate PAFParser::_nextLine(istream& is,
string&
line) {
105 if (_buffer.size() > 0) {
106 line = _buffer.front();
112 if (is.fail())
return is.rdstate();
113 if (is.eof() and line.length() == 0)
return ios::eofbit;
116 return ios::iostate(0);
119 void PAFParser::_pushBackLine(
const string& line) {
120 _buffer.push_front(line);
124 int PAFParser::_parseIntoPolicy(istream& is, Policy& policy) {
130 while (!_nextLine(is, line)) {
131 if (regex_search(line, COMMENT_LINE))
134 if (regex_search(line, matched, CLOSE_SRCH)) {
137 string msg =
"extra '}' character encountered.";
138 if (_strict)
throw LSST_EXCEPT(FormatSyntaxError, msg, _lineno);
142 _pushBackLine(matched.suffix());
145 else if (regex_search(line, matched, PARAM_SRCH)) {
147 name = matched.str(2);
148 if (! regex_search(name, NAME_MTCH)) {
149 string msg =
"Not a legal names designation: ";
152 throw LSST_EXCEPT(FormatSyntaxError, msg, _lineno);
157 value = matched.suffix();
158 count += _addValue(name, value, policy, is);
160 else if (! regex_search(line, matched, EMPTY_LINE)) {
161 string msg =
"Bad parameter name format: " +
line;
163 throw LSST_EXCEPT(FormatSyntaxError, msg, _lineno);
168 if (! is.eof() && is.fail())
throw LSST_EXCEPT(ParserError,
"read error", _lineno);
173 int PAFParser::_addValue(
const string& propname,
string& value,
174 Policy& policy, istream& is)
180 if (value.size() == 0 || regex_search(value, COMMENT_LINE))
184 if (regex_search(value, matched, OPEN_SRCH)) {
189 policy.add(propname, subpolicy);
192 value = matched.suffix();
193 if (value.size() > 0 && ! regex_search(value, COMMENT_LINE))
194 _pushBackLine(value);
197 count += _parseIntoPolicy(is, *subpolicy);
199 else if (regex_search(value, matched, DOUBLE_VALUE)) {
201 element = matched.str(1);
202 value = matched.suffix();
205 double d = strtod(element.c_str(), &unparsed);
206 if (unparsed && (*unparsed)) {
207 msg =
"value contains unparsable non-numeric data: ";
209 if (_strict)
throw LSST_EXCEPT(FormatSyntaxError, msg, _lineno);
213 policy.add(propname, d);
215 if (value.size() > 0) {
216 if (regex_search(value,COMMENT_LINE)) {
220 else if (regex_search(value, CLOSE_SRCH)) {
221 _pushBackLine(value);
227 }
while (regex_search(value, matched, DOUBLE_VALUE));
229 if (value.size() > 0) {
230 msg =
"Expecting double value, found: ";
232 if (_strict)
throw LSST_EXCEPT(FormatSyntaxError, msg, _lineno);
236 else if (regex_search(value, matched, INT_VALUE)) {
238 element = matched.str(1);
239 value = matched.suffix();
242 long lval = strtol(element.c_str(), &unparsed, 10);
243 if (unparsed && (*unparsed)) {
244 msg =
"value contains unparsable non-integer data: ";
246 if (_strict)
throw LSST_EXCEPT(FormatSyntaxError, msg, _lineno);
250 int ival = int(lval);
251 if (lval-ival != 0) {
253 msg =
"unsupported long integer value found: ";
255 if (_strict)
throw LSST_EXCEPT(UnsupportedSyntax, msg, _lineno);
259 policy.add(propname, ival);
262 if (value.size() > 0) {
263 if (regex_search(value,COMMENT_LINE)) {
267 else if (regex_search(value, CLOSE_SRCH)) {
268 _pushBackLine(value);
274 }
while (regex_search(value, matched, INT_VALUE));
276 if (value.size() > 0) {
277 msg =
"Expecting integer value, found: ";
279 if (_strict)
throw LSST_EXCEPT(FormatSyntaxError, msg, _lineno);
283 else if (regex_search(value, matched, ATRUE_VALUE) ||
284 regex_search(value, matched, AFALSE_VALUE))
287 element = matched.str(1);
288 value = matched.suffix();
289 if (element[0] ==
't' || element[0] ==
'T')
290 policy.add(propname,
true);
292 policy.add(propname,
false);
295 if (value.size() > 0) {
296 if (regex_search(value,COMMENT_LINE)) {
300 else if (regex_search(value, CLOSE_SRCH)) {
301 _pushBackLine(value);
307 }
while (regex_search(value, matched, ATRUE_VALUE) ||
308 regex_search(value, matched, AFALSE_VALUE));
310 if (value.size() > 0) {
311 msg =
"Expecting boolean value, found: ";
314 throw LSST_EXCEPT(FormatSyntaxError, msg, _lineno);
318 else if (value.at(0) ==
'\'' || value.at(0) ==
'"') {
321 if (regex_search(value, matched, QQSTRING_VALUE) ||
322 regex_search(value, matched, QSTRING_VALUE))
324 element = matched.str(1);
325 value = matched.suffix();
327 policy.add(propname, element);
330 if (value.size() > 0 && regex_search(value, COMMENT_LINE))
333 else if (regex_search(value, matched, QQSTRING_EMPTYSTART) ||
334 regex_search(value, matched, QQSTRING_START) ) {
336 element = (matched.size() > 1) ? matched.str(1) :
"";
337 while (!_nextLine(is, value)) {
339 if (regex_search(value, matched, QQSTRING_END)) {
340 element.append(matched.str(1));
341 policy.add(propname, element);
343 value = matched.suffix();
346 else if (regex_search(value, matched, BARE_STRING_LINE)) {
347 element.append(matched.str(1));
355 throw LSST_EXCEPT(ParserError,
"read error", _lineno);
357 else if (regex_search(value, matched, QSTRING_EMPTYSTART) ||
358 regex_match(value, matched, QSTRING_START)) {
360 element = (matched.size() > 1) ? matched.str(1) :
"";
361 while (!_nextLine(is, value)) {
363 if (regex_search(value, matched, QSTRING_END)) {
364 element.append(matched.str(1));
365 policy.add(propname, element);
367 value = matched.suffix();
370 else if (regex_match(value, matched, BARE_STRING_LINE)) {
371 element.append(matched.str(1));
379 throw LSST_EXCEPT(ParserError,
"read error", _lineno);
382 if (value.size() > 0) {
383 if (regex_search(value,COMMENT_LINE)) {
387 else if (regex_search(value, CLOSE_SRCH)) {
388 _pushBackLine(value);
394 }
while (value.size() > 0 &&
395 (value.at(0) ==
'\'' || value.at(0) ==
'"'));
397 if (value.size() > 0) {
398 msg =
"Expecting quoted string value, found: ";
400 if (_strict)
throw LSST_EXCEPT(FormatSyntaxError, msg, _lineno);
404 else if (regex_search(value, matched, BARE_STRING)) {
405 string trimmed = matched.str(1);
406 string lowered(trimmed);
407 transform(lowered.begin(), lowered.end(), lowered.begin(), ::tolower);
408 int resume = matched.position(1) + matched.length(1);
409 if (regex_search(lowered, matched, URN_VALUE)) {
413 else if (regex_search(trimmed, matched, FILE_VALUE)) {
418 policy.add(propname, trimmed);
421 value = value.substr(resume);
422 if (regex_search(value, matched, CLOSE_SRCH)) {
423 _pushBackLine(value);
an abstract class for parsing serialized Policy data and loading it into a Policy object...
static const boost::regex URN_VALUE
static const boost::regex OPEN_SRCH
static const boost::regex ATRUE_VALUE
definition of the PolicyFile class
static const boost::regex CLOSE_SRCH
table::Key< std::string > name
boost::shared_ptr< PolicyFile > FilePtr
definition of the PAFParser class
static const boost::regex QQSTRING_VALUE
a container for holding hierarchical configuration data in memory.
static const boost::regex QSTRING_END
PAFParser(Policy &policy)
definition of Policy parsing exceptions
boost::shared_ptr< Policy > Ptr
static const boost::regex PARAM_SRCH
static const boost::regex QSTRING_START
static const boost::regex BARE_STRING
static const boost::regex BARE_STRING_LINE
static const boost::regex EMPTY_LINE
static const boost::regex QSTRING_EMPTYSTART
static const boost::regex FILE_VALUE
static const boost::regex COMMENT_LINE
static const boost::regex QQSTRING_EMPTYSTART
static const boost::regex DOUBLE_VALUE
static const boost::regex SPACE_SRCH
#define LSST_EXCEPT(type,...)
static const boost::regex QSTRING_VALUE
static const boost::regex NAME_MTCH
static const boost::regex QQSTRING_START
static const boost::regex QQSTRING_END
static const boost::regex AFALSE_VALUE
static const boost::regex INT_VALUE
the definition of the UrnPolicyFile class