diff options
author | Andreas Krennmair <ak@synflood.at> | 2009-01-31 10:57:44 +0100 |
---|---|---|
committer | Andreas Krennmair <ak@synflood.at> | 2009-01-31 10:57:44 +0100 |
commit | 9e33f9e6fd15c399190b68b46e80a5748aa113da (patch) | |
tree | 9f9524c63ff1a71f5977fab525a4ffafc6b71879 /filter | |
parent | 970a242aab3fd35bc718901eb48aeb566339a1b8 (diff) |
implemented and documented "between" operator to match integer values for ranges.
Diffstat (limited to 'filter')
-rw-r--r-- | filter/FilterParser.h | 2 | ||||
-rw-r--r-- | filter/Parser.cpp | 92 | ||||
-rw-r--r-- | filter/Parser.h | 1 | ||||
-rw-r--r-- | filter/Scanner.cpp | 80 | ||||
-rw-r--r-- | filter/filter.atg | 4 |
5 files changed, 103 insertions, 76 deletions
diff --git a/filter/FilterParser.h b/filter/FilterParser.h index 4b169146..ab83d81e 100644 --- a/filter/FilterParser.h +++ b/filter/FilterParser.h @@ -6,7 +6,7 @@ #include <regex.h> -enum { LOGOP_INVALID = 0, LOGOP_AND = 1, LOGOP_OR, MATCHOP_EQ, MATCHOP_NE, MATCHOP_RXEQ, MATCHOP_RXNE, MATCHOP_LT, MATCHOP_GT, MATCHOP_LE, MATCHOP_GE, MATCHOP_CONTAINS, MATCHOP_CONTAINSNOT }; +enum { LOGOP_INVALID = 0, LOGOP_AND = 1, LOGOP_OR, MATCHOP_EQ, MATCHOP_NE, MATCHOP_RXEQ, MATCHOP_RXNE, MATCHOP_LT, MATCHOP_GT, MATCHOP_LE, MATCHOP_GE, MATCHOP_CONTAINS, MATCHOP_CONTAINSNOT, MATCHOP_BETWEEN }; struct expression { expression(const std::string& n, const std::string& lit, int o); diff --git a/filter/Parser.cpp b/filter/Parser.cpp index 08400159..9ae6f9e4 100644 --- a/filter/Parser.cpp +++ b/filter/Parser.cpp @@ -67,7 +67,9 @@ void Parser::stringlit(char* &lit) { Get(); } else if (la->kind == 5) { Get(); - } else SynErr(20); + } else if (la->kind == 6) { + Get(); + } else SynErr(22); lit = coco_string_create_char(t->val); } @@ -78,73 +80,78 @@ void Parser::matchattrib(char* &name) { void Parser::matchop(int &op) { switch (la->kind) { - case 6: { + case 7: { Get(); op = MATCHOP_EQ; break; } - case 7: { + case 8: { Get(); op = MATCHOP_EQ; break; } - case 8: { + case 9: { Get(); op = MATCHOP_NE; break; } - case 9: { + case 10: { Get(); op = MATCHOP_RXEQ; break; } - case 10: { + case 11: { Get(); op = MATCHOP_RXNE; break; } - case 11: { + case 12: { Get(); op = MATCHOP_LT; break; } - case 12: { + case 13: { Get(); op = MATCHOP_GT; break; } - case 13: { + case 14: { Get(); op = MATCHOP_LE; break; } - case 14: { + case 15: { Get(); op = MATCHOP_GE; break; } - case 15: { + case 16: { Get(); op = MATCHOP_CONTAINS; break; } - case 16: { + case 17: { Get(); op = MATCHOP_CONTAINSNOT; break; } - default: SynErr(21); break; + case 18: { + Get(); + op = MATCHOP_BETWEEN; + break; + } + default: SynErr(23); break; } } void Parser::logop(int &lop) { - if (la->kind == 17) { + if (la->kind == 19) { Get(); lop = LOGOP_AND; - } else if (la->kind == 18) { + } else if (la->kind == 20) { Get(); lop = LOGOP_OR; - } else SynErr(22); + } else SynErr(24); } void Parser::matchexpr() { @@ -169,15 +176,15 @@ void Parser::expr() { matchexpr(); } else if (la->kind == 1) { blockexpr(); - } else SynErr(23); - while (la->kind == 17 || la->kind == 18) { + } else SynErr(25); + while (la->kind == 19 || la->kind == 20) { logop(lop); gen->add_logop(lop); if (la->kind == 3) { matchexpr(); } else if (la->kind == 1) { blockexpr(); - } else SynErr(24); + } else SynErr(26); } } @@ -204,7 +211,8 @@ Parser::Parser(Scanner *scanner) { _ident = 3; _stringliteral = 4; _numliteral = 5; - maxT = 19; + _rangeliteral = 6; + maxT = 21; minErrDist = 2; errDist = minErrDist; @@ -216,8 +224,8 @@ bool Parser::StartOf(int s) { const bool T = true; const bool x = false; - static bool set[1][21] = { - {T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x} + static bool set[1][23] = { + {T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x} }; @@ -243,25 +251,27 @@ void Errors::SynErr(int n) { case 3: s = coco_string_create(L"ident expected"); break; case 4: s = coco_string_create(L"stringliteral expected"); break; case 5: s = coco_string_create(L"numliteral expected"); break; - case 6: s = coco_string_create(L"\"==\" expected"); break; - case 7: s = coco_string_create(L"\"=\" expected"); break; - case 8: s = coco_string_create(L"\"!=\" expected"); break; - case 9: s = coco_string_create(L"\"=~\" expected"); break; - case 10: s = coco_string_create(L"\"!~\" expected"); break; - case 11: s = coco_string_create(L"\"<\" expected"); break; - case 12: s = coco_string_create(L"\">\" expected"); break; - case 13: s = coco_string_create(L"\"<=\" expected"); break; - case 14: s = coco_string_create(L"\">=\" expected"); break; - case 15: s = coco_string_create(L"\"#\" expected"); break; - case 16: s = coco_string_create(L"\"!#\" expected"); break; - case 17: s = coco_string_create(L"\"and\" expected"); break; - case 18: s = coco_string_create(L"\"or\" expected"); break; - case 19: s = coco_string_create(L"??? expected"); break; - case 20: s = coco_string_create(L"invalid stringlit"); break; - case 21: s = coco_string_create(L"invalid matchop"); break; - case 22: s = coco_string_create(L"invalid logop"); break; - case 23: s = coco_string_create(L"invalid expr"); break; - case 24: s = coco_string_create(L"invalid expr"); break; + case 6: s = coco_string_create(L"rangeliteral expected"); break; + case 7: s = coco_string_create(L"\"==\" expected"); break; + case 8: s = coco_string_create(L"\"=\" expected"); break; + case 9: s = coco_string_create(L"\"!=\" expected"); break; + case 10: s = coco_string_create(L"\"=~\" expected"); break; + case 11: s = coco_string_create(L"\"!~\" expected"); break; + case 12: s = coco_string_create(L"\"<\" expected"); break; + case 13: s = coco_string_create(L"\">\" expected"); break; + case 14: s = coco_string_create(L"\"<=\" expected"); break; + case 15: s = coco_string_create(L"\">=\" expected"); break; + case 16: s = coco_string_create(L"\"#\" expected"); break; + case 17: s = coco_string_create(L"\"!#\" expected"); break; + case 18: s = coco_string_create(L"\"between\" expected"); break; + case 19: s = coco_string_create(L"\"and\" expected"); break; + case 20: s = coco_string_create(L"\"or\" expected"); break; + case 21: s = coco_string_create(L"??? expected"); break; + case 22: s = coco_string_create(L"invalid stringlit"); break; + case 23: s = coco_string_create(L"invalid matchop"); break; + case 24: s = coco_string_create(L"invalid logop"); break; + case 25: s = coco_string_create(L"invalid expr"); break; + case 26: s = coco_string_create(L"invalid expr"); break; default: { diff --git a/filter/Parser.h b/filter/Parser.h index 1663d1c4..2e292a1c 100644 --- a/filter/Parser.h +++ b/filter/Parser.h @@ -34,6 +34,7 @@ private: int _ident; int _stringliteral; int _numliteral; + int _rangeliteral; int maxT; Token *dummyToken; diff --git a/filter/Scanner.cpp b/filter/Scanner.cpp index df3c7e92..624f7538 100644 --- a/filter/Scanner.cpp +++ b/filter/Scanner.cpp @@ -341,25 +341,26 @@ Scanner::~Scanner() { void Scanner::Init() { EOL = '\n'; eofSym = 0; - maxT = 19; - noSym = 19; + maxT = 21; + noSym = 21; for (int i = 46; i <= 46; ++i) start.set(i, 3); for (int i = 65; i <= 90; ++i) start.set(i, 3); for (int i = 95; i <= 95; ++i) start.set(i, 3); for (int i = 97; i <= 122; ++i) start.set(i, 3); - for (int i = 48; i <= 57; ++i) start.set(i, 6); + for (int i = 48; i <= 57; ++i) start.set(i, 9); start.set(40, 1); start.set(41, 2); start.set(34, 4); - start.set(45, 7); - start.set(61, 16); - start.set(33, 17); - start.set(60, 18); - start.set(62, 19); - start.set(35, 14); + start.set(45, 10); + start.set(61, 19); + start.set(33, 20); + start.set(60, 21); + start.set(62, 22); + start.set(35, 17); start.set(Buffer::EoF, -1); - keywords.set(L"and", 17); - keywords.set(L"or", 18); + keywords.set(L"between", 18); + keywords.set(L"and", 19); + keywords.set(L"or", 20); tvalLength = 128; @@ -504,47 +505,60 @@ Token* Scanner::NextToken() { if (ch >= L'0' && ch <= L'9') {AddCh(); goto case_6;} else {t->kind = 5; break;} case 7: - if (ch >= L'-' && ch <= L'.' || ch >= L'A' && ch <= L'Z' || ch == L'_' || ch >= L'a' && ch <= L'z') {AddCh(); goto case_3;} - else if (ch >= L'0' && ch <= L'9') {AddCh(); goto case_6;} - else {t->kind = 3; wchar_t *literal = coco_string_create(tval, 0, tlen); t->kind = keywords.get(literal, t->kind); coco_string_delete(literal); break;} + case_7: + if (ch >= L'0' && ch <= L'9') {AddCh(); goto case_8;} + else {t->kind = noSym; break;} case 8: case_8: - {t->kind = 6; break;} + if (ch >= L'0' && ch <= L'9') {AddCh(); goto case_8;} + else {t->kind = 6; break;} case 9: case_9: - {t->kind = 8; break;} + if (ch >= L'0' && ch <= L'9') {AddCh(); goto case_9;} + else if (ch == L':') {AddCh(); goto case_7;} + else {t->kind = 5; break;} case 10: - case_10: - {t->kind = 9; break;} + if (ch >= L'-' && ch <= L'.' || ch >= L'A' && ch <= L'Z' || ch == L'_' || ch >= L'a' && ch <= L'z') {AddCh(); goto case_3;} + else if (ch >= L'0' && ch <= L'9') {AddCh(); goto case_6;} + else {t->kind = 3; wchar_t *literal = coco_string_create(tval, 0, tlen); t->kind = keywords.get(literal, t->kind); coco_string_delete(literal); break;} case 11: case_11: - {t->kind = 10; break;} + {t->kind = 7; break;} case 12: case_12: - {t->kind = 13; break;} + {t->kind = 9; break;} case 13: case_13: - {t->kind = 14; break;} + {t->kind = 10; break;} case 14: - {t->kind = 15; break;} + case_14: + {t->kind = 11; break;} case 15: case_15: - {t->kind = 16; break;} + {t->kind = 14; break;} case 16: - if (ch == L'=') {AddCh(); goto case_8;} - else if (ch == L'~') {AddCh(); goto case_10;} - else {t->kind = 7; break;} + case_16: + {t->kind = 15; break;} case 17: - if (ch == L'=') {AddCh(); goto case_9;} - else if (ch == L'~') {AddCh(); goto case_11;} - else if (ch == L'#') {AddCh(); goto case_15;} - else {t->kind = noSym; break;} + {t->kind = 16; break;} case 18: - if (ch == L'=') {AddCh(); goto case_12;} - else {t->kind = 11; break;} + case_18: + {t->kind = 17; break;} case 19: - if (ch == L'=') {AddCh(); goto case_13;} + if (ch == L'=') {AddCh(); goto case_11;} + else if (ch == L'~') {AddCh(); goto case_13;} + else {t->kind = 8; break;} + case 20: + if (ch == L'=') {AddCh(); goto case_12;} + else if (ch == L'~') {AddCh(); goto case_14;} + else if (ch == L'#') {AddCh(); goto case_18;} + else {t->kind = noSym; break;} + case 21: + if (ch == L'=') {AddCh(); goto case_15;} else {t->kind = 12; break;} + case 22: + if (ch == L'=') {AddCh(); goto case_16;} + else {t->kind = 13; break;} } AppendVal(t); diff --git a/filter/filter.atg b/filter/filter.atg index 26470b44..2e8da976 100644 --- a/filter/filter.atg +++ b/filter/filter.atg @@ -19,11 +19,12 @@ TOKENS ident = identchar { identchar }. stringliteral = '"' { nonquote } '"'. numliteral = ['-'] digit { digit }. + rangeliteral = digit { digit } ':' digit { digit }. PRODUCTIONS stringlit<char* &lit> - = ( stringliteral | numliteral ) (. lit = coco_string_create_char(t->val); .) + = ( stringliteral | numliteral | rangeliteral ) (. lit = coco_string_create_char(t->val); .) . matchattrib<char* &name> @@ -42,6 +43,7 @@ PRODUCTIONS | ">=" (. op = MATCHOP_GE; .) | "#" (. op = MATCHOP_CONTAINS; .) | "!#" (. op = MATCHOP_CONTAINSNOT; .) + | "between" (. op = MATCHOP_BETWEEN; .) . logop<int &lop> |