eolian: lex_until and lex_balanced
authorDaniel Kolesa <d.kolesa@samsung.com>
Thu, 19 Jun 2014 14:05:24 +0000 (15:05 +0100)
committerDaniel Kolesa <d.kolesa@samsung.com>
Thu, 19 Jun 2014 15:04:08 +0000 (16:04 +0100)
src/lib/eolian/eo_lexer.c
src/lib/eolian/eo_lexer.h
src/lib/eolian/eo_parser.c

index 70ae758..b6539a0 100644 (file)
@@ -203,6 +203,51 @@ lex(Eo_Lexer *ls, const char **value, int *kwid, const char *chars)
      }
 }
 
+static int
+lex_balanced(Eo_Lexer *ls, const char **value, int *kwid, char beg, char end)
+{
+   int depth = 0;
+   const char *str;
+   eina_strbuf_reset(ls->buff);
+   while (ls->current)
+     {
+        if (ls->current == beg)
+          ++depth;
+        else if (ls->current == end)
+          --depth;
+
+        if (depth == -1)
+          break;
+
+        eina_strbuf_append_char(ls->buff, ls->current);
+        next_char(ls);
+     }
+   eina_strbuf_trim(ls->buff);
+   str    = eina_strbuf_string_get(ls->buff);
+   *kwid  = (long)eina_hash_find(keyword_map, str);
+   *value = str;
+   return TOK_VALUE;
+}
+
+static int
+lex_until(Eo_Lexer *ls, const char **value, int *kwid, char end)
+{
+   const char *str;
+   eina_strbuf_reset(ls->buff);
+   while (ls->current)
+     {
+        if (ls->current == end)
+          break;
+        eina_strbuf_append_char(ls->buff, ls->current);
+        next_char(ls);
+     }
+   eina_strbuf_trim(ls->buff);
+   str    = eina_strbuf_string_get(ls->buff);
+   *kwid  = (long)eina_hash_find(keyword_map, str);
+   *value = str;
+   return TOK_VALUE;
+}
+
 static void
 eo_lexer_set_input(Eo_Lexer *ls, const char *source)
 {
@@ -254,6 +299,20 @@ eo_lexer_new(const char *source)
 }
 
 int
+eo_lexer_get_balanced(Eo_Lexer *ls, char beg, char end)
+{
+   assert(ls->lookahead.token == TOK_EOF);
+   return (ls->t.token == lex_balanced(ls, &ls->t.value, &ls->t.kw, beg, end));
+}
+
+int
+eo_lexer_get_until(Eo_Lexer *ls, char end)
+{
+   assert(ls->lookahead.token == TOK_EOF);
+   return (ls->t.token == lex_until(ls, &ls->t.value, &ls->t.kw, end));
+}
+
+int
 eo_lexer_get(Eo_Lexer *ls)
 {
    return eo_lexer_get_ident(ls, "@_.+-/\\='\"?!%");
index feb6604..eabf3b0 100644 (file)
@@ -62,6 +62,8 @@ int       eo_lexer_init           (void);
 int       eo_lexer_shutdown       (void);
 Eo_Lexer *eo_lexer_new            (const char *source);
 void      eo_lexer_free           (Eo_Lexer *ls);
+int       eo_lexer_get_balanced   (Eo_Lexer *ls, char beg, char end);
+int       eo_lexer_get_until      (Eo_Lexer *ls, char end);
 int       eo_lexer_get            (Eo_Lexer *ls);
 int       eo_lexer_get_ident      (Eo_Lexer *ls, const char *chars);
 int       eo_lexer_lookahead      (Eo_Lexer *ls);
index a33bd7a..ee82e79 100644 (file)
@@ -225,8 +225,7 @@ parse_return(Eo_Lexer *ls)
    if (ls->t.token == '(')
      {
         int line = ls->line_number;
-        eo_lexer_get(ls);
-        check(ls, TOK_VALUE);
+        eo_lexer_get_balanced(ls, '(', ')');
         ret->dflt_ret_val = eina_stringshare_add(ls->t.value);
         eo_lexer_get(ls);
         check_match(ls, ')', '(', line);
@@ -721,13 +720,10 @@ parse_event(Eo_Lexer *ls)
    eo_lexer_get(ls);
    if (ls->t.token == '(')
      {
-        Eina_Strbuf *buf;
         int line = ls->line_number;
+        eo_lexer_get_balanced(ls, '(', ')');
+        ev->type = eina_stringshare_add(ls->t.value);
         eo_lexer_get(ls);
-        buf = push_strbuf(ls);
-        parse_type(ls, NULL, buf);
-        ev->type = eina_stringshare_add(eina_strbuf_string_get(buf));
-        pop_strbuf(ls);
         check_match(ls, ')', '(', line);
      }
    check(ls, ';');
@@ -872,8 +868,8 @@ parse_class_body(Eo_Lexer *ls, Eina_Bool allow_ctors)
                    eo_lexer_syntax_error(ls, "double data definition");
                 has_data = EINA_TRUE;
                 eo_lexer_get(ls);
-                check_next(ls, ':');
-                check(ls, TOK_VALUE);
+                check(ls, ':');
+                eo_lexer_get_until(ls, ';');
                 ls->tmp.kls->data_type = eina_stringshare_add(ls->t.value);
                 eo_lexer_get(ls);
                 check_next(ls, ';');