]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
[script] Merge all Left-To-Right parsing into a single function
authorCharlie Brej <cbrej@cs.man.ac.uk>
Fri, 10 Jul 2009 14:23:54 +0000 (15:23 +0100)
committerRay Strode <rstrode@redhat.com>
Fri, 24 Jul 2009 13:30:28 +0000 (09:30 -0400)
src/plugins/splash/script/script-parse.c

index de20aa9eb8e50514acaed8002610865d71e4c30f..1e1036b8e69640bbfb29e0e705fcf167b434fc97 100644 (file)
 
 #define WITH_SEMIES
 
+
+typedef enum
+{
+  OP_ASSOC_INFIX_RTL,
+  OP_ASSOC_INFIX_LTR,
+  OP_ASSOC_PREFIX,
+  OP_ASSOC_POSTFIX,
+  OP_ASSOC_PREPOSTFIX,
+} script_parse_operator_associativity_t;
+
+
+typedef struct
+{
+ const char*                            symbol;
+ script_exp_type_t                      exp_type; 
+ int                                    presedence;
+}script_parse_operator_table_entry_t;
+
 static script_op_t *script_parse_op (ply_scan_t *scan);
 static script_exp_t *script_parse_exp (ply_scan_t *scan);
 static ply_list_t *script_parse_op_list (ply_scan_t *scan);
@@ -371,203 +389,62 @@ static script_exp_t *script_parse_exp_po (ply_scan_t *scan)
   return exp;
 }
 
-static script_exp_t *script_parse_exp_md (ply_scan_t *scan)
-{
-  script_exp_t *sub_a = script_parse_exp_po (scan);
-
-  if (!sub_a) return NULL;
-  ply_scan_token_t *curtoken = ply_scan_get_current_token (scan);
-  ply_scan_token_t *peektoken = ply_scan_peek_next_token (scan);
-  while (curtoken->type == PLY_SCAN_TOKEN_TYPE_SYMBOL
-         && (curtoken->data.symbol == '*'
-             || curtoken->data.symbol == '/'
-             || curtoken->data.symbol == '%')
-         && !(peektoken->type == PLY_SCAN_TOKEN_TYPE_SYMBOL
-              && peektoken->data.symbol == '='))
-    {
-      script_exp_t *exp = malloc (sizeof (script_exp_t));
-      if (curtoken->data.symbol == '*') exp->type = SCRIPT_EXP_TYPE_MUL;
-      else if (curtoken->data.symbol == '/') exp->type = SCRIPT_EXP_TYPE_DIV;
-      else exp->type = SCRIPT_EXP_TYPE_MOD;
-      exp->data.dual.sub_a = sub_a;
-      ply_scan_get_next_token (scan);
-      sub_a = exp;
-      exp->data.dual.sub_b = script_parse_exp_po (scan);
-      curtoken = ply_scan_get_current_token (scan);
-      peektoken = ply_scan_peek_next_token (scan);
-      if (!exp->data.dual.sub_b)
-        {
-          script_parse_error (curtoken, "An invalid RHS of an expression");
-          return NULL;
-        }
-    }
-
-  return sub_a;
-}
-
-static script_exp_t *script_parse_exp_pm (ply_scan_t *scan)
-{
-  script_exp_t *sub_a = script_parse_exp_md (scan);
-
-  if (!sub_a) return NULL;
-  ply_scan_token_t *curtoken = ply_scan_get_current_token (scan);
-  ply_scan_token_t *peektoken = ply_scan_peek_next_token (scan);
-  while (curtoken->type == PLY_SCAN_TOKEN_TYPE_SYMBOL
-         && (curtoken->data.symbol == '+'
-             || curtoken->data.symbol == '-')
-         && !(peektoken->type == PLY_SCAN_TOKEN_TYPE_SYMBOL
-              && peektoken->data.symbol == '='))
-    {
-      script_exp_t *exp = malloc (sizeof (script_exp_t));
-      if (curtoken->data.symbol == '+') exp->type = SCRIPT_EXP_TYPE_PLUS;
-      else exp->type = SCRIPT_EXP_TYPE_MINUS;
-      exp->data.dual.sub_a = sub_a;
-      ply_scan_get_next_token (scan);
-      exp->data.dual.sub_b = script_parse_exp_md (scan);
-      sub_a = exp;
-      curtoken = ply_scan_get_current_token (scan);
-      peektoken = ply_scan_peek_next_token (scan);
-      if (!exp->data.dual.sub_b)
-        {
-          script_parse_error (curtoken, "An invalid RHS of an expression");
-          return NULL;
-        }
-    }
-
-  return sub_a;
-}
-
-static script_exp_t *script_parse_exp_gt (ply_scan_t *scan)
-{
-  script_exp_t *sub_a = script_parse_exp_pm (scan);
-
-  if (!sub_a) return NULL;
-  ply_scan_token_t *curtoken = ply_scan_get_current_token (scan);
-  ply_scan_token_t *peektoken = ply_scan_peek_next_token (scan);
-  while (curtoken->type == PLY_SCAN_TOKEN_TYPE_SYMBOL
-         && (curtoken->data.symbol == '<'
-             || curtoken->data.symbol == '>'))                          /* FIXME make sure we dont consume <<= or >>= */
-    {
-      int gt = (curtoken->data.symbol == '>');
-      int eq = 0;
-      curtoken = ply_scan_get_next_token (scan);
-      if ((curtoken->type == PLY_SCAN_TOKEN_TYPE_SYMBOL)
-          && (curtoken->data.symbol == '=')
-          && !curtoken->whitespace)
-        {
-          eq = 1;
-          curtoken = ply_scan_get_next_token (scan);
-        }
-      script_exp_t *exp = malloc (sizeof (script_exp_t));
-      if      (gt &&  eq) exp->type = SCRIPT_EXP_TYPE_GE;
-      else if (gt && !eq) exp->type = SCRIPT_EXP_TYPE_GT;
-      else if (!gt &&  eq) exp->type = SCRIPT_EXP_TYPE_LE;
-      else exp->type = SCRIPT_EXP_TYPE_LT;
-      exp->data.dual.sub_a = sub_a;
-      exp->data.dual.sub_b = script_parse_exp_pm (scan);
-      sub_a = exp;
-      curtoken = ply_scan_get_current_token (scan);
-      peektoken = ply_scan_peek_next_token (scan);
-      if (!exp->data.dual.sub_b)
-        {
-          script_parse_error (curtoken, "An invalid RHS of an expression");
-          return NULL;
-        }
-    }
-
-  return sub_a;
-}
-
-static script_exp_t *script_parse_exp_eq (ply_scan_t *scan)
+static script_exp_t *script_parse_exp_ltr (ply_scan_t *scan, int presedence)
 {
-  script_exp_t *sub_a = script_parse_exp_gt (scan);
-
-  if (!sub_a) return NULL;
-  while (1)
+  static const script_parse_operator_table_entry_t operator_table[] =
     {
-      ply_scan_token_t *curtoken = ply_scan_get_current_token (scan);
-      ply_scan_token_t *peektoken = ply_scan_peek_next_token (scan);
-      if (curtoken->type != PLY_SCAN_TOKEN_TYPE_SYMBOL) break;
-      if (peektoken->type != PLY_SCAN_TOKEN_TYPE_SYMBOL) break;
-      if (peektoken->data.symbol != '=') break;
-      if (peektoken->whitespace) break;
-      if ((curtoken->data.symbol != '=')
-          && (curtoken->data.symbol != '!')) break;
-      int ne = (curtoken->data.symbol == '!');
-      ply_scan_get_next_token (scan);
-      ply_scan_get_next_token (scan);
-
-      script_exp_t *exp = malloc (sizeof (script_exp_t));
-      if (ne) exp->type = SCRIPT_EXP_TYPE_NE;
-      else exp->type = SCRIPT_EXP_TYPE_EQ;
-      exp->data.dual.sub_a = sub_a;
-      exp->data.dual.sub_b = script_parse_exp_gt (scan);
-      sub_a = exp;
-      if (!exp->data.dual.sub_b)
-        {
-          script_parse_error (ply_scan_get_current_token (scan),
-                              "An invalid RHS of an expression");
-          return NULL;
-        }
-    }
-
-  return sub_a;
-}
-
-static script_exp_t *script_parse_exp_an (ply_scan_t *scan)
-{
-  script_exp_t *sub_a = script_parse_exp_eq (scan);
-
+      {"||", SCRIPT_EXP_TYPE_OR,         0},    /* FIXME Does const imply static? */
+      {"&&", SCRIPT_EXP_TYPE_AND,        1},
+      {"==", SCRIPT_EXP_TYPE_EQ,         2},
+      {"!=", SCRIPT_EXP_TYPE_NE,         2},
+      {">=", SCRIPT_EXP_TYPE_GE,         3},
+      {"<=", SCRIPT_EXP_TYPE_LE,         3},
+      {"+=", SCRIPT_EXP_TYPE_TERM_NULL, -1},    /* A few things it shouldn't consume */
+      {"-=", SCRIPT_EXP_TYPE_TERM_NULL, -1},
+      {"*=", SCRIPT_EXP_TYPE_TERM_NULL, -1},
+      {"/=", SCRIPT_EXP_TYPE_TERM_NULL, -1},
+      {"%=", SCRIPT_EXP_TYPE_TERM_NULL, -1},
+      {">",  SCRIPT_EXP_TYPE_GT,         3},
+      {"<",  SCRIPT_EXP_TYPE_LT,         3},
+      {"+",  SCRIPT_EXP_TYPE_PLUS,       4},
+      {"-",  SCRIPT_EXP_TYPE_MINUS,      4},
+      {"*",  SCRIPT_EXP_TYPE_MUL,        5},
+      {"/",  SCRIPT_EXP_TYPE_DIV,        5},
+      {"%",  SCRIPT_EXP_TYPE_MOD,        5},
+      {NULL, SCRIPT_EXP_TYPE_TERM_NULL, -1},
+    };
+    
+  if (presedence > 5) return script_parse_exp_po (scan);
+  script_exp_t *sub_a = script_parse_exp_ltr (scan, presedence + 1);
   if (!sub_a) return NULL;
+  
   while (1)
     {
+      const char* symbol = "";
+      int entry_index;
       ply_scan_token_t *curtoken = ply_scan_get_current_token (scan);
       ply_scan_token_t *peektoken = ply_scan_peek_next_token (scan);
       if (curtoken->type != PLY_SCAN_TOKEN_TYPE_SYMBOL) break;
-      if (peektoken->type != PLY_SCAN_TOKEN_TYPE_SYMBOL) break;
-      if (curtoken->data.symbol != '&') break;
-      if (peektoken->data.symbol != '&') break;
-      if (peektoken->whitespace) break;
-      ply_scan_get_next_token (scan);
-      ply_scan_get_next_token (scan);
-
-      script_exp_t *exp = malloc (sizeof (script_exp_t));
-      exp->type = SCRIPT_EXP_TYPE_AND;
-      exp->data.dual.sub_a = sub_a;
-      exp->data.dual.sub_b = script_parse_exp_eq (scan);
-      sub_a = exp;
-      if (!exp->data.dual.sub_b)
+      for (entry_index = 0; operator_table[entry_index].symbol; entry_index++)
         {
-          script_parse_error (ply_scan_get_current_token (scan),
-                              "An invalid RHS of an expression");
-          return NULL;
+          symbol = operator_table[entry_index].symbol;
+          if (curtoken->data.symbol != symbol[0]) continue;
+          if (symbol[1])
+            {
+              if (peektoken->type != PLY_SCAN_TOKEN_TYPE_SYMBOL) continue;
+              if (peektoken->data.symbol != symbol[1]) continue;
+              if (peektoken->whitespace) continue;
+            }
+          break;
         }
-    }
-
-  return sub_a;
-}
-
-static script_exp_t *script_parse_exp_or (ply_scan_t *scan)
-{
-  script_exp_t *sub_a = script_parse_exp_an (scan);
-
-  if (!sub_a) return NULL;
-  while (1)
-    {
-      ply_scan_token_t *curtoken = ply_scan_get_current_token (scan);
-      ply_scan_token_t *peektoken = ply_scan_peek_next_token (scan);
-      if (curtoken->type != PLY_SCAN_TOKEN_TYPE_SYMBOL) break;
-      if (peektoken->type != PLY_SCAN_TOKEN_TYPE_SYMBOL) break;
-      if (peektoken->data.symbol != '|') break;
-      if (curtoken->data.symbol != '|') break;
-      if (peektoken->whitespace) break;
-      ply_scan_get_next_token (scan);
+      if (operator_table[entry_index].presedence != presedence) break;
       ply_scan_get_next_token (scan);
-
+      if (symbol[1]) ply_scan_get_next_token (scan);
+      
       script_exp_t *exp = malloc (sizeof (script_exp_t));
-      exp->type = SCRIPT_EXP_TYPE_OR;
+      exp->type = operator_table[entry_index].exp_type;
       exp->data.dual.sub_a = sub_a;
-      exp->data.dual.sub_b = script_parse_exp_an (scan);
+      exp->data.dual.sub_b = script_parse_exp_ltr (scan, presedence + 1);
       sub_a = exp;
       if (!exp->data.dual.sub_b)
         {
@@ -576,13 +453,12 @@ static script_exp_t *script_parse_exp_or (ply_scan_t *scan)
           return NULL;
         }
     }
-
   return sub_a;
 }
 
 static script_exp_t *script_parse_exp_as (ply_scan_t *scan)
 {
-  script_exp_t *lhs = script_parse_exp_or (scan);
+  script_exp_t *lhs = script_parse_exp_ltr (scan, 0);
 
   if (!lhs) return NULL;
   ply_scan_token_t *curtoken = ply_scan_get_current_token (scan);