Added "position in original character stream" marker to Token class
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@490 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
dc685e9ad8
commit
224e92720e
@ -51,6 +51,7 @@ public:
|
||||
void Unset();
|
||||
status_t InitCheck() const;
|
||||
bool IsEmpty() const;
|
||||
size_t Pos() const;
|
||||
|
||||
char Get();
|
||||
void Unget();
|
||||
@ -83,7 +84,7 @@ const char* tokenTypeToString(TokenType type);
|
||||
|
||||
class Token {
|
||||
public:
|
||||
Token(TokenType type = EmptyToken);
|
||||
Token(TokenType type = EmptyToken, const size_t posInStream = -1);
|
||||
virtual ~Token();
|
||||
TokenType Type() const;
|
||||
virtual const char* String() const;
|
||||
@ -92,11 +93,12 @@ public:
|
||||
bool operator==(Token &ref);
|
||||
protected:
|
||||
TokenType fType;
|
||||
size_t fPosInStream;
|
||||
};
|
||||
|
||||
class StringToken : public Token {
|
||||
public:
|
||||
StringToken(const char *string);
|
||||
StringToken(const char *string, const size_t posInStream);
|
||||
virtual ~StringToken();
|
||||
virtual const char* String() const;
|
||||
protected:
|
||||
@ -105,7 +107,7 @@ protected:
|
||||
|
||||
class IntToken : public Token {
|
||||
public:
|
||||
IntToken(const int32 value);
|
||||
IntToken(const int32 value, const size_t posInStream);
|
||||
virtual int32 Int() const;
|
||||
virtual double Float() const;
|
||||
protected:
|
||||
@ -114,7 +116,7 @@ protected:
|
||||
|
||||
class FloatToken : public Token {
|
||||
public:
|
||||
FloatToken(const double value);
|
||||
FloatToken(const double value, const size_t posInStream);
|
||||
virtual double Float() const;
|
||||
protected:
|
||||
double fValue;
|
||||
@ -135,10 +137,10 @@ public:
|
||||
bool IsEmpty();
|
||||
|
||||
private:
|
||||
void AddToken(TokenType type);
|
||||
void AddString(const char *str);
|
||||
void AddInt(const char *str);
|
||||
void AddFloat(const char *str);
|
||||
void AddToken(TokenType type, size_t posInStream);
|
||||
void AddString(const char *str, size_t posInStream);
|
||||
void AddInt(const char *str, size_t posInStream);
|
||||
void AddFloat(const char *str, size_t posInStream);
|
||||
|
||||
BList fTokenList;
|
||||
status_t fCStatus;
|
||||
|
@ -27,8 +27,8 @@ using namespace Sniffer;
|
||||
TokenStream stream;
|
||||
|
||||
// Private parsing functions
|
||||
/*
|
||||
double parsePriority();
|
||||
/*
|
||||
BList* parseExprList();
|
||||
Expr* parseExpr();
|
||||
Range parseRange();
|
||||
@ -63,7 +63,7 @@ Sniffer::parse(const char *rule, Rule *result, BString *parseError = NULL) {
|
||||
double priority;
|
||||
BList* exprList;
|
||||
|
||||
// priority = parsePriority();
|
||||
priority = parsePriority();
|
||||
|
||||
} catch (Err *err) {
|
||||
if (parseError && err)
|
||||
@ -168,6 +168,11 @@ CharStream::IsEmpty() const {
|
||||
return fPos >= fLen;
|
||||
}
|
||||
|
||||
size_t
|
||||
CharStream::Pos() const {
|
||||
return fPos;
|
||||
}
|
||||
|
||||
char
|
||||
CharStream::Get() {
|
||||
if (fCStatus != B_OK)
|
||||
@ -194,8 +199,9 @@ CharStream::Unget() {
|
||||
// Token
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
Token::Token(TokenType type)
|
||||
Token::Token(TokenType type, const size_t posInStream)
|
||||
: fType(type)
|
||||
, fPosInStream(posInStream)
|
||||
{
|
||||
// if (type != EmptyToken)
|
||||
// cout << "New Token, fType == " << tokenTypeToString(fType) << endl;
|
||||
@ -272,8 +278,8 @@ Token::operator==(Token &ref) {
|
||||
// StringToken
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
StringToken::StringToken(const char *string)
|
||||
: Token(CharacterString)
|
||||
StringToken::StringToken(const char *string, const size_t posInStream)
|
||||
: Token(CharacterString, posInStream)
|
||||
, fString(NULL)
|
||||
{
|
||||
if (string) {
|
||||
@ -296,8 +302,8 @@ StringToken::String() const {
|
||||
// IntToken
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
IntToken::IntToken(const int32 value)
|
||||
: Token(Integer)
|
||||
IntToken::IntToken(const int32 value, const size_t posInStream)
|
||||
: Token(Integer, posInStream)
|
||||
, fValue(value)
|
||||
{
|
||||
}
|
||||
@ -316,8 +322,8 @@ IntToken::Float() const {
|
||||
// FloatToken
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
FloatToken::FloatToken(const double value)
|
||||
: Token(FloatingPoint)
|
||||
FloatToken::FloatToken(const double value, const size_t posInStream)
|
||||
: Token(FloatingPoint, posInStream)
|
||||
, fValue(value)
|
||||
{
|
||||
}
|
||||
@ -381,6 +387,7 @@ TokenStream::SetTo(const char *string) {
|
||||
char lastLastChar; // For three char lookahead
|
||||
bool keepLooping = true;
|
||||
while (keepLooping) {
|
||||
size_t pos = stream.Pos();
|
||||
char ch = stream.Get();
|
||||
switch (state) {
|
||||
case tsssStart:
|
||||
@ -437,11 +444,11 @@ TokenStream::SetTo(const char *string) {
|
||||
state = tsssIntOrFloat;
|
||||
break;
|
||||
|
||||
case '&': AddToken(Ampersand); break;
|
||||
case '(': AddToken(LeftParen); break;
|
||||
case ')': AddToken(RightParen); break;
|
||||
case ':': AddToken(Colon); break;
|
||||
case '[': AddToken(LeftBracket); break;
|
||||
case '&': AddToken(Ampersand, pos); break;
|
||||
case '(': AddToken(LeftParen, pos); break;
|
||||
case ')': AddToken(RightParen, pos); break;
|
||||
case ':': AddToken(Colon, pos); break;
|
||||
case '[': AddToken(LeftBracket, pos); break;
|
||||
|
||||
case '\\':
|
||||
charStr = ""; // Clear our string
|
||||
@ -449,8 +456,8 @@ TokenStream::SetTo(const char *string) {
|
||||
escapedState = tsssUnquoted; // Unquoted strings begin with an escaped character
|
||||
break;
|
||||
|
||||
case ']': AddToken(RightBracket); break;
|
||||
case '|': AddToken(Divider); break;
|
||||
case ']': AddToken(RightBracket, pos); break;
|
||||
case '|': AddToken(Divider, pos); break;
|
||||
|
||||
default:
|
||||
throw new Err(std::string("Sniffer scanner error: unexpected character '") + ch + "'");
|
||||
@ -464,7 +471,7 @@ TokenStream::SetTo(const char *string) {
|
||||
state = tsssEscape; // Handle the escape sequence
|
||||
break;
|
||||
case '\'':
|
||||
AddString(charStr.c_str());
|
||||
AddString(charStr.c_str(), pos);
|
||||
state = tsssStart;
|
||||
break;
|
||||
case 0x3:
|
||||
@ -486,7 +493,7 @@ TokenStream::SetTo(const char *string) {
|
||||
state = tsssEscape; // Handle the escape sequence
|
||||
break;
|
||||
case '"':
|
||||
AddString(charStr.c_str());
|
||||
AddString(charStr.c_str(), pos);
|
||||
state = tsssStart;
|
||||
break;
|
||||
case 0x3:
|
||||
@ -513,11 +520,11 @@ TokenStream::SetTo(const char *string) {
|
||||
state = tsssFloat;
|
||||
} else if (ch == 0x3 && stream.IsEmpty()) {
|
||||
// Terminate the number and then the loop
|
||||
AddInt(charStr.c_str());
|
||||
AddInt(charStr.c_str(), pos);
|
||||
keepLooping = false;
|
||||
} else {
|
||||
// Terminate the number
|
||||
AddInt(charStr.c_str());
|
||||
AddInt(charStr.c_str(), pos);
|
||||
|
||||
// Push the last char back on and try again
|
||||
stream.Unget();
|
||||
@ -550,11 +557,11 @@ TokenStream::SetTo(const char *string) {
|
||||
lastChar = ch;
|
||||
state = tsssOneHex;
|
||||
} else if (isWhiteSpace(ch) || isPunctuation(ch)) {
|
||||
AddString(charStr.c_str());
|
||||
AddString(charStr.c_str(), pos);
|
||||
stream.Unget(); // So punctuation gets handled properly
|
||||
state = tsssStart;
|
||||
} else if (ch == 0x3 && stream.IsEmpty()) {
|
||||
AddString(charStr.c_str());
|
||||
AddString(charStr.c_str(), pos);
|
||||
keepLooping = false;
|
||||
} else
|
||||
throw Err(std::string("Sniffer scanner error: unexpected character '") + ch + "'");
|
||||
@ -568,7 +575,7 @@ TokenStream::SetTo(const char *string) {
|
||||
state = tsssFloat;
|
||||
} else {
|
||||
// Terminate the number
|
||||
AddInt(charStr.c_str());
|
||||
AddInt(charStr.c_str(), pos);
|
||||
|
||||
// Push the last char back on and try again
|
||||
stream.Unget();
|
||||
@ -581,7 +588,7 @@ TokenStream::SetTo(const char *string) {
|
||||
charStr += ch;
|
||||
else {
|
||||
// Terminate the number
|
||||
AddFloat(charStr.c_str());
|
||||
AddFloat(charStr.c_str(), pos);
|
||||
|
||||
// Push the last char back on and try again
|
||||
stream.Unget();
|
||||
@ -616,7 +623,7 @@ TokenStream::SetTo(const char *string) {
|
||||
throw new Err(std::string("Sniffer scanner error: negative floating point numbers are useless and thus signs (both + and -) are disallowed on floating points"));
|
||||
else {
|
||||
// Terminate the number
|
||||
AddInt(charStr.c_str());
|
||||
AddInt(charStr.c_str(), pos);
|
||||
|
||||
// Push the last char back on and try again
|
||||
stream.Unget();
|
||||
@ -629,13 +636,13 @@ TokenStream::SetTo(const char *string) {
|
||||
escapedState = state; // Save our state
|
||||
state = tsssEscape; // Handle the escape sequence
|
||||
} else if (isWhiteSpace(ch) || isPunctuation(ch)) {
|
||||
AddString(charStr.c_str());
|
||||
AddString(charStr.c_str(), pos);
|
||||
stream.Unget(); // In case it's punctuation, let tsssStart handle it
|
||||
state = tsssStart;
|
||||
} else if (ch == '\'' || ch == '"') {
|
||||
throw new Err(std::string("Sniffer scanner error: illegal unquoted character '") + ch + "'");
|
||||
} else if (ch == 0x3 && stream.IsEmpty()) {
|
||||
AddString(charStr.c_str());
|
||||
AddString(charStr.c_str(), pos);
|
||||
keepLooping = false;
|
||||
} else {
|
||||
charStr += ch;
|
||||
@ -745,30 +752,30 @@ TokenStream::IsEmpty() {
|
||||
}
|
||||
|
||||
void
|
||||
TokenStream::AddToken(TokenType type) {
|
||||
Token *token = new Token(type);
|
||||
TokenStream::AddToken(TokenType type, size_t posInStream) {
|
||||
Token *token = new Token(type, posInStream);
|
||||
fTokenList.AddItem(token);
|
||||
}
|
||||
|
||||
void
|
||||
TokenStream::AddString(const char *str) {
|
||||
Token *token = new StringToken(str);
|
||||
TokenStream::AddString(const char *str, size_t posInStream) {
|
||||
Token *token = new StringToken(str, posInStream);
|
||||
fTokenList.AddItem(token);
|
||||
}
|
||||
|
||||
void
|
||||
TokenStream::AddInt(const char *str) {
|
||||
TokenStream::AddInt(const char *str, size_t posInStream) {
|
||||
// Convert the string to an int
|
||||
int32 value = atol(str);
|
||||
Token *token = new IntToken(value);
|
||||
Token *token = new IntToken(value, posInStream);
|
||||
fTokenList.AddItem(token);
|
||||
}
|
||||
|
||||
void
|
||||
TokenStream::AddFloat(const char *str) {
|
||||
TokenStream::AddFloat(const char *str, size_t posInStream) {
|
||||
// Convert the string to a float
|
||||
double value = atof(str);
|
||||
Token *token = new FloatToken(value);
|
||||
Token *token = new FloatToken(value, posInStream);
|
||||
fTokenList.AddItem(token);
|
||||
}
|
||||
|
||||
@ -917,3 +924,11 @@ Sniffer::tokenTypeToString(TokenType type) {
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Parsing functions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
double
|
||||
parsePriority() {
|
||||
// stream.Read(LeftBracket);
|
||||
}
|
||||
|
@ -31,10 +31,10 @@ ParserTest::ScannerTest() {
|
||||
|
||||
// Define some useful macros for dynamically allocating
|
||||
// various Token classes
|
||||
#define T(type) (new Token(type))
|
||||
#define S(str) (new StringToken(str))
|
||||
#define I(val) (new IntToken(val))
|
||||
#define F(val) (new FloatToken(val))
|
||||
#define T(type) (new Token(type, -1))
|
||||
#define S(str) (new StringToken(str, -1))
|
||||
#define I(val) (new IntToken(val, -1))
|
||||
#define F(val) (new FloatToken(val, -1))
|
||||
|
||||
struct test_case {
|
||||
const char *rule;
|
||||
|
Loading…
Reference in New Issue
Block a user