+ Got rid of global TokenStream object

+ Started on Parser class
+ Moved parsing functions into Parser class
+ Added Pos() member to Err class to allow for
snazzy BMimeType::CheckSnifferRule() error strings.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@531 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Tyler Dauwalder
2002-07-29 07:01:56 +00:00
parent 51156f1f46
commit 4574a75fc5
2 changed files with 237 additions and 103 deletions
+46 -13
View File
@@ -10,14 +10,23 @@
#define _sk_sniffer_parser_h_ #define _sk_sniffer_parser_h_
#include <SupportDefs.h> #include <SupportDefs.h>
#include <sniffer/Range.h>
#include <sniffer/Rule.h>
#include <List.h> #include <List.h>
#include <string> #include <string>
#include <vector>
class BString; class BString;
namespace Sniffer { namespace Sniffer {
class Rule; class Rule;
class Expr;
class Range;
class RPattern;
class Pattern;
typedef std::vector<Expr*> ExprList;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// The mighty parsing function ;-) // The mighty parsing function ;-)
@@ -31,15 +40,17 @@ status_t parse(const char *rule, Rule *result, BString *parseError = NULL);
class Err { class Err {
public: public:
Err(const char *msg); Err(const char *msg, const ssize_t pos);
Err(const std::string &msg); Err(const std::string &msg, const ssize_t pos);
Err(const Err &ref); Err(const Err &ref);
Err& operator=(const Err &ref); Err& operator=(const Err &ref);
const char* Msg() const; const char* Msg() const;
ssize_t Pos() const;
private: private:
void SetMsg(const char *msg); void SetMsg(const char *msg);
char *fMsg; char *fMsg;
ssize_t fPos;
}; };
class CharStream { class CharStream {
@@ -51,14 +62,14 @@ public:
void Unset(); void Unset();
status_t InitCheck() const; status_t InitCheck() const;
bool IsEmpty() const; bool IsEmpty() const;
size_t Pos() const; ssize_t Pos() const;
char Get(); char Get();
void Unget(); void Unget();
private: private:
char *fString; char *fString;
size_t fPos; ssize_t fPos;
ssize_t fLen; ssize_t fLen;
status_t fCStatus; status_t fCStatus;
@@ -84,21 +95,22 @@ const char* tokenTypeToString(TokenType type);
class Token { class Token {
public: public:
Token(TokenType type = EmptyToken, const size_t posInStream = -1); Token(TokenType type = EmptyToken, const ssize_t pos = -1);
virtual ~Token(); virtual ~Token();
TokenType Type() const; TokenType Type() const;
virtual const char* String() const; virtual const char* String() const;
virtual int32 Int() const; virtual int32 Int() const;
virtual double Float() const; virtual double Float() const;
ssize_t Pos() const;
bool operator==(Token &ref); bool operator==(Token &ref);
protected: protected:
TokenType fType; TokenType fType;
size_t fPosInStream; ssize_t fPos;
}; };
class StringToken : public Token { class StringToken : public Token {
public: public:
StringToken(const char *string, const size_t posInStream); StringToken(const char *string, const ssize_t pos);
virtual ~StringToken(); virtual ~StringToken();
virtual const char* String() const; virtual const char* String() const;
protected: protected:
@@ -107,7 +119,7 @@ protected:
class IntToken : public Token { class IntToken : public Token {
public: public:
IntToken(const int32 value, const size_t posInStream); IntToken(const int32 value, const ssize_t pos);
virtual int32 Int() const; virtual int32 Int() const;
virtual double Float() const; virtual double Float() const;
protected: protected:
@@ -116,7 +128,7 @@ protected:
class FloatToken : public Token { class FloatToken : public Token {
public: public:
FloatToken(const double value, const size_t posInStream); FloatToken(const double value, const ssize_t pos);
virtual double Float() const; virtual double Float() const;
protected: protected:
double fValue; double fValue;
@@ -137,10 +149,10 @@ public:
bool IsEmpty(); bool IsEmpty();
private: private:
void AddToken(TokenType type, size_t posInStream); void AddToken(TokenType type, ssize_t pos);
void AddString(const char *str, size_t posInStream); void AddString(const char *str, ssize_t pos);
void AddInt(const char *str, size_t posInStream); void AddInt(const char *str, ssize_t pos);
void AddFloat(const char *str, size_t posInStream); void AddFloat(const char *str, ssize_t pos);
BList fTokenList; BList fTokenList;
status_t fCStatus; status_t fCStatus;
@@ -149,6 +161,27 @@ private:
TokenStream& operator=(const TokenStream &ref); TokenStream& operator=(const TokenStream &ref);
}; };
class Parser {
public:
Parser();
status_t Parse(const char *rule, Rule *result, BString *parseError = NULL);
private:
std::string ErrorMessage(Err *err, const char *rule);
// Parsing functions
void ParseRule(Rule *result);
double ParsePriority();
ExprList* ParseExprList();
Expr* ParseExpr();
Range ParseRange();
Expr* ParsePatternList();
Expr* ParseRPatternList();
RPattern* ParseRPattern();
Pattern* ParsePattern();
TokenStream stream;
};
} // namespace Sniffer } // namespace Sniffer
+190 -89
View File
@@ -23,20 +23,6 @@
using namespace Sniffer; using namespace Sniffer;
// Our global token stream object
TokenStream stream;
// Private parsing functions
double parsePriority();
/*
BList* parseExprList();
Expr* parseExpr();
Range parseRange();
Expr* parsePatternList();
Expr* parseRPatternList();
Pattern* parsePattern();
*/
// Miscellaneous helper functions // Miscellaneous helper functions
char escapeChar(char ch); char escapeChar(char ch);
char hexToChar(char hi, char low); char hexToChar(char hi, char low);
@@ -51,42 +37,33 @@ bool isDecimalChar(char ch);
bool isPunctuation(char ch); bool isPunctuation(char ch);
status_t status_t
Sniffer::parse(const char *rule, Rule *result, BString *parseError = NULL) { Sniffer::parse(const char *rule, Rule *result, BString *parseError) {
try { Parser parser;
if (!rule) return parser.Parse(rule, result, parseError);
throw new Err("Sniffer pattern error: NULL pattern");
if (!result)
return B_BAD_VALUE;
if (stream.SetTo(rule) != B_OK)
throw new Err("Sniffer parser error: Unable to intialize token stream");
double priority;
BList* exprList;
priority = parsePriority();
} catch (Err *err) {
if (parseError && err)
parseError->SetTo((err->Msg() ? err->Msg() : "Sniffer parser rule: Unexpected error with no supplied error message"));
return B_BAD_MIME_SNIFFER_RULE;
}
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Sniffer::Err // Err
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Err::Err(const char *msg) Err::Err(const char *msg, const ssize_t pos)
: fMsg(NULL) : fMsg(NULL)
, fPos(pos)
{ {
SetMsg(msg); SetMsg(msg);
} }
Err::Err(const std::string &msg) { Err::Err(const std::string &msg, const ssize_t pos)
: fMsg(NULL)
, fPos(pos)
{
SetMsg(msg.c_str()); SetMsg(msg.c_str());
} }
Err::Err(const Err &ref) { Err::Err(const Err &ref)
: fMsg(NULL)
, fPos(-1)
{
*this = ref; *this = ref;
} }
@@ -101,6 +78,11 @@ Err::Msg() const {
return fMsg; return fMsg;
} }
ssize_t
Err::Pos() const {
return fPos;
}
void void
Err::SetMsg(const char *msg) { Err::SetMsg(const char *msg) {
if (fMsg) { if (fMsg) {
@@ -116,7 +98,6 @@ Err::SetMsg(const char *msg) {
} }
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// CharStream // CharStream
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -168,7 +149,7 @@ CharStream::IsEmpty() const {
return fPos >= fLen; return fPos >= fLen;
} }
size_t ssize_t
CharStream::Pos() const { CharStream::Pos() const {
return fPos; return fPos;
} }
@@ -176,7 +157,7 @@ CharStream::Pos() const {
char char
CharStream::Get() { CharStream::Get() {
if (fCStatus != B_OK) if (fCStatus != B_OK)
throw new Err("Sniffer parser error: CharStream::Get() called on uninitialized CharStream object"); throw new Err("Sniffer parser error: CharStream::Get() called on uninitialized CharStream object", -1);
if (fPos < fLen) if (fPos < fLen)
return fString[fPos++]; return fString[fPos++];
else { else {
@@ -188,20 +169,20 @@ CharStream::Get() {
void void
CharStream::Unget() { CharStream::Unget() {
if (fCStatus != B_OK) if (fCStatus != B_OK)
throw new Err("Sniffer parser error: CharStream::Unget() called on uninitialized CharStream object"); throw new Err("Sniffer parser error: CharStream::Unget() called on uninitialized CharStream object", -1);
if (fPos > 0) if (fPos > 0)
fPos--; fPos--;
else else
throw new Err("Sniffer parser error: CharStream::Unget() called at beginning of character stream"); throw new Err("Sniffer parser error: CharStream::Unget() called at beginning of character stream", -1);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Token // Token
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Token::Token(TokenType type, const size_t posInStream) Token::Token(TokenType type, const ssize_t pos)
: fType(type) : fType(type)
, fPosInStream(posInStream) , fPos(pos)
{ {
// if (type != EmptyToken) // if (type != EmptyToken)
// cout << "New Token, fType == " << tokenTypeToString(fType) << endl; // cout << "New Token, fType == " << tokenTypeToString(fType) << endl;
@@ -217,17 +198,22 @@ Token::Type() const {
const char* const char*
Token::String() const { Token::String() const {
throw new Err("Sniffer scanner error: Token::String() called on non-string token"); throw new Err("Sniffer scanner error: Token::String() called on non-string token", fPos);
} }
int32 int32
Token::Int() const { Token::Int() const {
throw new Err("Sniffer scanner error: Token::Int() called on non-integer token"); throw new Err("Sniffer scanner error: Token::Int() called on non-integer token", fPos);
} }
double double
Token::Float() const { Token::Float() const {
throw new Err("Sniffer scanner error: Token::Float() called on non-float token"); throw new Err("Sniffer scanner error: Token::Float() called on non-float token", fPos);
}
ssize_t
Token::Pos() const {
return fPos;
} }
bool bool
@@ -278,8 +264,8 @@ Token::operator==(Token &ref) {
// StringToken // StringToken
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
StringToken::StringToken(const char *string, const size_t posInStream) StringToken::StringToken(const char *string, const ssize_t pos)
: Token(CharacterString, posInStream) : Token(CharacterString, pos)
, fString(NULL) , fString(NULL)
{ {
if (string) { if (string) {
@@ -302,8 +288,8 @@ StringToken::String() const {
// IntToken // IntToken
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
IntToken::IntToken(const int32 value, const size_t posInStream) IntToken::IntToken(const int32 value, const ssize_t pos)
: Token(Integer, posInStream) : Token(Integer, pos)
, fValue(value) , fValue(value)
{ {
} }
@@ -322,8 +308,8 @@ IntToken::Float() const {
// FloatToken // FloatToken
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
FloatToken::FloatToken(const double value, const size_t posInStream) FloatToken::FloatToken(const double value, const ssize_t pos)
: Token(FloatingPoint, posInStream) : Token(FloatingPoint, pos)
, fValue(value) , fValue(value)
{ {
} }
@@ -353,7 +339,7 @@ TokenStream::SetTo(const char *string) {
if (string) { if (string) {
CharStream stream(string); CharStream stream(string);
if (stream.InitCheck() != B_OK) if (stream.InitCheck() != B_OK)
throw new Err("Sniffer scanner error: Unable to intialize character stream"); throw new Err("Sniffer scanner error: Unable to intialize character stream", -1);
typedef enum TokenStreamScannerState { typedef enum TokenStreamScannerState {
tsssStart, tsssStart,
@@ -387,7 +373,7 @@ TokenStream::SetTo(const char *string) {
char lastLastChar; // For three char lookahead char lastLastChar; // For three char lookahead
bool keepLooping = true; bool keepLooping = true;
while (keepLooping) { while (keepLooping) {
size_t pos = stream.Pos(); ssize_t pos = stream.Pos();
char ch = stream.Get(); char ch = stream.Get();
switch (state) { switch (state) {
case tsssStart: case tsssStart:
@@ -396,7 +382,7 @@ TokenStream::SetTo(const char *string) {
if (stream.IsEmpty()) if (stream.IsEmpty())
keepLooping = false; keepLooping = false;
else else
throw new Err(std::string("Sniffer scanner error: unexpected character '") + ch + "'"); throw new Err(std::string("Sniffer scanner error: unexpected character '") + ch + "'", pos);
break; break;
case '\t': case '\t':
@@ -460,7 +446,7 @@ TokenStream::SetTo(const char *string) {
case '|': AddToken(Divider, pos); break; case '|': AddToken(Divider, pos); break;
default: default:
throw new Err(std::string("Sniffer scanner error: unexpected character '") + ch + "'"); throw new Err(std::string("Sniffer scanner error: unexpected character '") + ch + "'", pos);
} }
break; break;
@@ -476,7 +462,7 @@ TokenStream::SetTo(const char *string) {
break; break;
case 0x3: case 0x3:
if (stream.IsEmpty()) if (stream.IsEmpty())
throw new Err(std::string("Sniffer scanner error: unterminated single-quoted string")); throw new Err(std::string("Sniffer scanner error: unterminated single-quoted string"), pos);
else else
charStr += ch; charStr += ch;
break; break;
@@ -498,7 +484,7 @@ TokenStream::SetTo(const char *string) {
break; break;
case 0x3: case 0x3:
if (stream.IsEmpty()) if (stream.IsEmpty())
throw new Err(std::string("Sniffer scanner error: unterminated single-quoted string")); throw new Err(std::string("Sniffer scanner error: unterminated single-quoted string"), pos);
else else
charStr += ch; charStr += ch;
break; break;
@@ -537,9 +523,9 @@ TokenStream::SetTo(const char *string) {
lastChar = ch; lastChar = ch;
state = tsssOneHex; state = tsssOneHex;
} else if (ch == 0x3 && stream.IsEmpty()) } else if (ch == 0x3 && stream.IsEmpty())
throw new Err(std::string("Sniffer scanner error: incomplete hex code")); throw new Err(std::string("Sniffer scanner error: incomplete hex code"), pos);
else else
throw new Err(std::string("Sniffer scanner error: unexpected character '") + ch + "'"); throw new Err(std::string("Sniffer scanner error: unexpected character '") + ch + "'", pos);
break; break;
case tsssOneHex: case tsssOneHex:
@@ -547,9 +533,9 @@ TokenStream::SetTo(const char *string) {
charStr += hexToChar(lastChar, ch); charStr += hexToChar(lastChar, ch);
state = tsssTwoHex; state = tsssTwoHex;
} else if (ch == 0x3 && stream.IsEmpty()) } else if (ch == 0x3 && stream.IsEmpty())
throw Err(std::string("Sniffer scanner error: incomplete hex code (the number of hex digits must be a multiple of two)")); throw new Err(std::string("Sniffer scanner error: incomplete hex code (the number of hex digits must be a multiple of two)"), pos);
else else
throw Err(std::string("Sniffer scanner error: unexpected character '") + ch + "'"); throw new Err(std::string("Sniffer scanner error: unexpected character '") + ch + "'", pos);
break; break;
case tsssTwoHex: case tsssTwoHex:
@@ -564,7 +550,7 @@ TokenStream::SetTo(const char *string) {
AddString(charStr.c_str(), pos); AddString(charStr.c_str(), pos);
keepLooping = false; keepLooping = false;
} else } else
throw Err(std::string("Sniffer scanner error: unexpected character '") + ch + "'"); throw new Err(std::string("Sniffer scanner error: unexpected character '") + ch + "'", pos);
break; break;
case tsssIntOrFloat: case tsssIntOrFloat:
@@ -601,9 +587,9 @@ TokenStream::SetTo(const char *string) {
charStr += ch; charStr += ch;
state = tsssFloat; state = tsssFloat;
} else if (ch == 0x3 && stream.IsEmpty()) } else if (ch == 0x3 && stream.IsEmpty())
throw new Err(std::string("Sniffer scanner error: incomplete floating point number")); throw new Err(std::string("Sniffer scanner error: incomplete floating point number"), pos);
else else
throw new Err(std::string("Sniffer scanner error: unexpected character '") + ch + "'"); throw new Err(std::string("Sniffer scanner error: unexpected character '") + ch + "'", pos);
break; break;
case tsssLonelyMinusOrPlusSign: case tsssLonelyMinusOrPlusSign:
@@ -611,16 +597,16 @@ TokenStream::SetTo(const char *string) {
charStr += ch; charStr += ch;
state = tsssPosNegInt; state = tsssPosNegInt;
} else if (ch == 0x3 && stream.IsEmpty()) } else if (ch == 0x3 && stream.IsEmpty())
throw new Err(std::string("Sniffer scanner error: incomplete signed integer")); throw new Err(std::string("Sniffer scanner error: incomplete signed integer"), pos);
else else
throw new Err(std::string("Sniffer scanner error: unexpected character '") + ch + "'"); throw new Err(std::string("Sniffer scanner error: unexpected character '") + ch + "'", pos);
break; break;
case tsssPosNegInt: case tsssPosNegInt:
if (isDecimalChar(ch)) if (isDecimalChar(ch))
charStr += ch; charStr += ch;
else if (ch == '.') else if (ch == '.')
throw new Err(std::string("Sniffer scanner error: negative floating point numbers are useless and thus signs (both + and -) are disallowed on floating points")); throw new Err(std::string("Sniffer scanner error: negative floating point numbers are useless and thus signs (both + and -) are disallowed on floating points"), pos);
else { else {
// Terminate the number // Terminate the number
AddInt(charStr.c_str(), pos); AddInt(charStr.c_str(), pos);
@@ -640,7 +626,7 @@ TokenStream::SetTo(const char *string) {
stream.Unget(); // In case it's punctuation, let tsssStart handle it stream.Unget(); // In case it's punctuation, let tsssStart handle it
state = tsssStart; state = tsssStart;
} else if (ch == '\'' || ch == '"') { } else if (ch == '\'' || ch == '"') {
throw new Err(std::string("Sniffer scanner error: illegal unquoted character '") + ch + "'"); throw new Err(std::string("Sniffer scanner error: illegal unquoted character '") + ch + "'", pos);
} else if (ch == 0x3 && stream.IsEmpty()) { } else if (ch == 0x3 && stream.IsEmpty()) {
AddString(charStr.c_str(), pos); AddString(charStr.c_str(), pos);
keepLooping = false; keepLooping = false;
@@ -656,7 +642,7 @@ TokenStream::SetTo(const char *string) {
} else { } else {
// Check for a true end-of-text marker // Check for a true end-of-text marker
if (ch == 0x3 && stream.IsEmpty()) if (ch == 0x3 && stream.IsEmpty())
throw new Err(std::string("Sniffer scanner error: unterminated escape sequence")); throw new Err(std::string("Sniffer scanner error: unterminated escape sequence"), pos);
else { else {
charStr += escapeChar(ch); charStr += escapeChar(ch);
state = escapedState; // Return to the state we were in before the escape state = escapedState; // Return to the state we were in before the escape
@@ -669,7 +655,7 @@ TokenStream::SetTo(const char *string) {
lastChar = ch; lastChar = ch;
state = tsssEscapeOneHex; state = tsssEscapeOneHex;
} else } else
throw new Err(std::string("Sniffer scanner error: incomplete hex code")); throw new Err(std::string("Sniffer scanner error: incomplete hex code"), pos);
break; break;
case tsssEscapeOneOctal: case tsssEscapeOneOctal:
@@ -708,9 +694,9 @@ TokenStream::SetTo(const char *string) {
charStr += hexToChar(lastChar, ch); charStr += hexToChar(lastChar, ch);
state = escapedState; state = escapedState;
} else if (ch == 0x3 && stream.IsEmpty()) } else if (ch == 0x3 && stream.IsEmpty())
throw new Err(std::string("Sniffer scanner error: incomplete escaped hex code (the number of hex digits must be a multiple of two)")); throw new Err(std::string("Sniffer scanner error: incomplete escaped hex code (the number of hex digits must be a multiple of two)"), pos);
else else
throw new Err(std::string("Sniffer scanner error: unexpected character '") + ch + "'"); throw new Err(std::string("Sniffer scanner error: unexpected character '") + ch + "'", pos);
break; break;
} }
@@ -718,7 +704,7 @@ TokenStream::SetTo(const char *string) {
if (state == tsssStart) if (state == tsssStart)
fCStatus = B_OK; fCStatus = B_OK;
else else
throw new Err("Sniffer pattern error: unterminated rule"); throw new Err("Sniffer pattern error: unterminated rule", stream.Pos());
} }
return fCStatus; return fCStatus;
@@ -752,30 +738,30 @@ TokenStream::IsEmpty() {
} }
void void
TokenStream::AddToken(TokenType type, size_t posInStream) { TokenStream::AddToken(TokenType type, ssize_t pos) {
Token *token = new Token(type, posInStream); Token *token = new Token(type, pos);
fTokenList.AddItem(token); fTokenList.AddItem(token);
} }
void void
TokenStream::AddString(const char *str, size_t posInStream) { TokenStream::AddString(const char *str, ssize_t pos) {
Token *token = new StringToken(str, posInStream); Token *token = new StringToken(str, pos);
fTokenList.AddItem(token); fTokenList.AddItem(token);
} }
void void
TokenStream::AddInt(const char *str, size_t posInStream) { TokenStream::AddInt(const char *str, ssize_t pos) {
// Convert the string to an int // Convert the string to an int
int32 value = atol(str); int32 value = atol(str);
Token *token = new IntToken(value, posInStream); Token *token = new IntToken(value, pos);
fTokenList.AddItem(token); fTokenList.AddItem(token);
} }
void void
TokenStream::AddFloat(const char *str, size_t posInStream) { TokenStream::AddFloat(const char *str, ssize_t pos) {
// Convert the string to a float // Convert the string to a float
double value = atof(str); double value = atof(str);
Token *token = new FloatToken(value, posInStream); Token *token = new FloatToken(value, pos);
fTokenList.AddItem(token); fTokenList.AddItem(token);
} }
@@ -826,7 +812,7 @@ hexToChar(char hex) {
else if ('A' <= hex && hex <= 'F') else if ('A' <= hex && hex <= 'F')
return hex-'a'+10; return hex-'a'+10;
else else
throw new Err(std::string("Sniffer parser error: invalid hex digit '") + hex + "' passed to hexToChar()"); throw new Err(std::string("Sniffer parser error: invalid hex digit '") + hex + "' passed to hexToChar()", -1);
} }
char char
@@ -844,7 +830,7 @@ octalToChar(char hi, char mid, char low) {
if (isOctalChar(hi) && isOctalChar(mid) && isOctalChar(low)) { if (isOctalChar(hi) && isOctalChar(mid) && isOctalChar(low)) {
return ((hi-'0') << 6) | ((mid-'0') << 3) | (low-'0'); return ((hi-'0') << 6) | ((mid-'0') << 3) | (low-'0');
} else } else
throw new Err(std::string("Sniffer parser error: invalid octal digit passed to hexToChar()")); throw new Err(std::string("Sniffer parser error: invalid octal digit passed to hexToChar()"), -1);
} }
bool bool
@@ -925,10 +911,125 @@ Sniffer::tokenTypeToString(TokenType type) {
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Parsing functions // Parser
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
double Parser::Parser() {
parsePriority() {
// stream.Read(LeftBracket);
} }
status_t
Parser::Parse(const char *rule, Rule *result, BString *parseError) {
try {
if (!rule)
throw new Err("Sniffer pattern error: NULL pattern", -1);
if (!result)
return B_BAD_VALUE;
if (stream.SetTo(rule) != B_OK)
throw new Err("Sniffer parser error: Unable to intialize token stream", -1);
ParseRule(result);
return B_OK;
} catch (Err *err) {
// cout << "Caught error" << endl;
if (parseError)
parseError->SetTo(ErrorMessage(err, rule).c_str());
delete err;
return B_BAD_MIME_SNIFFER_RULE;
}
}
std::string
Parser::ErrorMessage(Err *err, const char *rule) {
const char* msg = (err && err->Msg())
? err->Msg()
: "Sniffer parser error: Unexpected error with no supplied error message";
size_t pos = err && (err->Pos() >= 0) ? err->Pos() : 0;
std::string str = std::string(rule) + "\n";
for (int i = 0; i < pos; i++)
str += " ";
str += "^ ";
str += msg;
return str;
}
void
Parser::ParseRule(Rule *result) {
// Priority
double priority = ParsePriority();
// Expression List
// ExprList* list = ParseExprList();
}
double
Parser::ParsePriority() {
Token *t = stream.Get();
Err *err = NULL;
double result;
// cout << tokenTypeToString(t->Type()) << endl;
if (t->Type() == FloatingPoint || t->Type() == Integer)
result = t->Float();
else
err = new Err("Sniffer pattern error: match level expected", t->Pos());
delete t;
if (err)
throw err;
else
return result;
}
ExprList*
Parser::ParseExprList() {
// Expr+
}
Expr*
Parser::ParseExpr() {
// PatternList
// RangeList
// Range + PatternList
}
Range
Parser::ParseRange() {
// LeftBracket
// Integer
// [Colon
// Integer]
// RightBracket
}
Expr*
Parser::ParsePatternList() {
// LeftParen
// Pattern
// [Divider
// Pattern]*
// RightParen
}
Expr*
Parser::ParseRPatternList() {
// LeftParen
// RPattern
// [Divider
// RPattern]*
// RightParen
}
RPattern*
Parser::ParseRPattern() {
// Range
// Pattern
}
Pattern*
Parser::ParsePattern() {
// String
// [Ampersand
// String]
}