Browse Source

[4088] Replaced example grammar with client classification expressions

Tomek Mrugalski 9 years ago
parent
commit
38ea55139b
2 changed files with 57 additions and 55 deletions
  1. 34 26
      src/lib/eval/lexer.ll
  2. 23 29
      src/lib/eval/parser.yy

+ 34 - 26
src/lib/eval/lexer.ll

@@ -17,7 +17,6 @@
 static isc::eval::location loc;
 %}
 %option noyywrap nounput batch debug noinput
-id    [a-zA-Z][a-zA-Z_0-9]*
 int   [0-9]+
 blank [ \t]
 
@@ -33,26 +32,36 @@ blank [ \t]
     loc.step();
 %}
 
-{blank}+   loc.step ();
-[\n]+      loc.lines (yyleng); loc.step ();
-"-"      return isc::eval::EvalParser::make_MINUS(loc);
-"+"      return isc::eval::EvalParser::make_PLUS(loc);
-"*"      return isc::eval::EvalParser::make_STAR(loc);
-"/"      return isc::eval::EvalParser::make_SLASH(loc);
-"("      return isc::eval::EvalParser::make_LPAREN(loc);
-")"      return isc::eval::EvalParser::make_RPAREN(loc);
-":="     return isc::eval::EvalParser::make_ASSIGN(loc);
+{blank}+   loc.step();
+[\n]+      loc.lines(yyleng); loc.step();
+
+\"[a-zA-Z_0-9]*\" {
+    // This is a string, no need to do any conversions here.
+    return isc::eval::EvalParser::make_STRING(yytext, loc);
+}
+
+option\[{int}\] {
+    long n = strtol(yytext, NULL, 10);
+    /// @todo: Sanity check n
+    if (n<0 || n>65535) {
+        driver.error(loc, "Option code has invalid values. Allowed range: 0..65535");
+    }
+
+    return isc::eval::EvalParser::make_OPTION(n, loc);
+}
 
+"==" {
+    return isc::eval::EvalParser::make_EQUAL(loc);
+}
 
-{int}      {
-  errno = 0;
-  long n = strtol (yytext, NULL, 10);
-  if (! (INT_MIN <= n && n <= INT_MAX && errno != ERANGE))
-    driver.error (loc, "integer is out of range");
-  return isc::eval::EvalParser::make_NUMBER(n, loc);
+"substring" {
+    return isc::eval::EvalParser::make_SUBSTRING(loc);
 }
 
-{id}       return isc::eval::EvalParser::make_IDENTIFIER(yytext, loc);
+"("      return isc::eval::EvalParser::make_LPAREN(loc);
+")"      return isc::eval::EvalParser::make_RPAREN(loc);
+","      return isc::eval::EvalParser::make_COMA(loc);
+
 .          driver.error (loc, "invalid character");
 <<EOF>>    return isc::eval::EvalParser::make_END(loc);
 %%
@@ -60,19 +69,18 @@ blank [ \t]
 void
 EvalContext::scan_begin()
 {
-  yy_flex_debug = trace_scanning;
-  if (file.empty () || file == "-")
-    yyin = stdin;
-  else if (!(yyin = fopen(file.c_str (), "r")))
-    {
-      error ("cannot open " + file + ": " + strerror(errno));
-      exit (EXIT_FAILURE);
+    yy_flex_debug = trace_scanning;
+    if (file.empty () || file == "-") {
+        yyin = stdin;
+    }
+    else if (!(yyin = fopen(file.c_str (), "r"))) {
+        error ("cannot open " + file + ": " + strerror(errno));
+        exit (EXIT_FAILURE);
     }
 }
 
 void
 EvalContext::scan_end()
 {
-  fclose (yyin);
+    fclose (yyin);
 }
-

+ 23 - 29
src/lib/eval/parser.yy

@@ -8,16 +8,17 @@
 %define parse.assert
 %code requires
 {
-# include <string>
+#include <string>
+#include <eval/token.h>
 class EvalContext;
 }
 // The parsing context.
-%param { EvalContext& driver }
+%param { EvalContext& ctx }
 %locations
 %initial-action
 {
   // Initialize the initial location.
-  @$.begin.filename = @$.end.filename = &driver.file;
+  @$.begin.filename = @$.end.filename = &ctx.file;
 };
 %define parse.trace
 %define parse.error verbose
@@ -28,43 +29,36 @@ class EvalContext;
 %define api.token.prefix {TOKEN_}
 %token
   END  0  "end of file"
-  ASSIGN  ":="
-  MINUS   "-"
-  PLUS    "+"
-  STAR    "*"
-  SLASH   "/"
+  EQUAL "=="
+  SUBSTRING "substring"
+  COMA ","
   LPAREN  "("
   RPAREN  ")"
 ;
-%token <std::string> IDENTIFIER "identifier"
-%token <int> NUMBER "number"
-%type  <int> exp
+%token <std::string> STRING "constant string"
+%token <int> OPTION "option code"
 %printer { yyoutput << $$; } <*>;
 %%
-%start unit;
-unit: assignments exp  { driver.result = $2; };
 
-assignments:
-  %empty                 {}
-| assignments assignment {};
+// The whole grammar starts with an expression.
+%start expression;
 
-assignment:
-  "identifier" ":=" exp { driver.variables[$1] = $3; };
+// Expression can either be a single token or a (something == something) expression
+expression:
+token EQUAL token
+| token;
+
+token:
+STRING { /* push back TokenString */ }
+| OPTION { /* push back TokenOption */ }
+| SUBSTRING "(" token "," token "," token ")" {
+    /* push back TokenSubstring */
+  }
 
-%left "+" "-";
-%left "*" "/";
-exp:
-  exp "+" exp   { $$ = $1 + $3; }
-| exp "-" exp   { $$ = $1 - $3; }
-| exp "*" exp   { $$ = $1 * $3; }
-| exp "/" exp   { $$ = $1 / $3; }
-| "(" exp ")"   { std::swap ($$, $2); }
-| "identifier"  { $$ = driver.variables[$1]; }
-| "number"      { std::swap ($$, $1); };
 %%
 void
 isc::eval::EvalParser::error(const location_type& l,
                              const std::string& m)
 {
-  driver.error (l, m);
+    ctx.error(l, m);
 }