/* Web Polygraph http://www.web-polygraph.org/
* (C) 2003-2006 The Measurement Factory
* Licensed under the Apache License, Version 2.0 */
#include "pgl/pgl.h"
#include "xstd/h/sstream.h"
#include "xstd/String.h"
#include "xstd/gadgets.h"
#include "pgl/PglStringSym.h"
#include "pgl/PglArraySym.h"
#include "pgl/PglStrRangeLexer.h"
#include "pgl/PglStrBlocks.h"
#include "pgl/PglStrRange.h"
ArraySym *PglStrRange::toSyms(const TokenLoc &loc) const {
ArraySym *arr = new ArraySym(StringSym::TheType);
startIter();
do {
String str;
currentIter(str);
StringSym ss(str);
if (loc)
ss.loc(loc);
arr->add(ss); // XXX: use range!
} while (nextIter());
return arr;
}
bool PglStrRange::parse(const String &val) {
PglStrRangeLexer lexs(this, val);
// convert val into lexems
if (!lexs.parse())
return false;
// convert lexems into blocks
while (lexs) {
if (escapeChar(lexs.next()) && lexs.next(1)) {
lexs.skip();
lexs.step();
} else
if (optRangeBeg(lexs.next())) {
lexs.step(); // keep a separator
(void)lexs.range(true); // optional
} else
if (reqRangeBeg(lexs.next())) {
const char start = lexs.next();
lexs.skip(); // skip the range separator
if (lexs.range(false) && reqRangeEnd(start, lexs.next()))
lexs.skip();
else
return false; // invalid range specs
} else
if (reqRangeEnd(lexs.next())) {
return false; // unbalanced required range separator
} else {
lexs.step(); // simple label
}
}
return true;
}
bool PglStrRange::escapeChar(char ch) const {
return ch == '\\';
}
bool PglStrRange::optRangeBeg(char) const {
return false;
}
bool PglStrRange::reqRangeBeg(char ch) const {
return ch == '[';
}
bool PglStrRange::reqRangeEnd(char ch) const {
return ch == ']';
}
bool PglStrRange::reqRangeEnd(char, char ch) const {
return reqRangeEnd(ch);
}
syntax highlighted by Code2HTML, v. 0.9.1