summaryrefslogtreecommitdiffstats
path: root/filter
diff options
context:
space:
mode:
authorAndreas Krennmair <ak@synflood.at>2009-01-31 10:57:44 +0100
committerAndreas Krennmair <ak@synflood.at>2009-01-31 10:57:44 +0100
commit9e33f9e6fd15c399190b68b46e80a5748aa113da (patch)
tree9f9524c63ff1a71f5977fab525a4ffafc6b71879 /filter
parent970a242aab3fd35bc718901eb48aeb566339a1b8 (diff)
implemented and documented "between" operator to match integer values for ranges.
Diffstat (limited to 'filter')
-rw-r--r--filter/FilterParser.h2
-rw-r--r--filter/Parser.cpp92
-rw-r--r--filter/Parser.h1
-rw-r--r--filter/Scanner.cpp80
-rw-r--r--filter/filter.atg4
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>