parser: fix parsing escaped characters
[m6w6/ext-psi] / src / parser_proc_grammar.y
index 442f93d84f070bf037e73d216e831ac48a694c77..feff14a23cdaaec27bc183191da012652a59dc38 100644 (file)
@@ -309,10 +309,10 @@ struct psi_parser;
 
 %type          <struct psi_decl_type *>                        decl_type const_decl_type decl_type_complex
 %destructor    {psi_decl_type_free(&$$);}                      decl_type const_decl_type decl_type_complex
-%type          <struct psi_decl *>                                     decl_stmt decl
-%destructor    {psi_decl_free(&$$);}                           decl_stmt decl
-%type          <struct psi_decl_arg *>                         decl_typedef decl_fn decl_func decl_functor decl_arg struct_arg typedef
-%destructor    {psi_decl_arg_free(&$$);}                       decl_typedef decl_fn decl_func decl_functor decl_arg struct_arg typedef
+%type          <struct psi_decl *>                                     decl_stmt decl decl_body decl_func_body decl_functor_body
+%destructor    {psi_decl_free(&$$);}                           decl_stmt decl decl_body decl_func_body decl_functor_body
+%type          <struct psi_decl_arg *>                         decl_typedef decl_func decl_functor decl_arg typedef
+%destructor    {psi_decl_arg_free(&$$);}                       decl_typedef decl_func decl_functor decl_arg typedef
 %type          <struct psi_decl_var *>                         decl_var
 %destructor    {psi_decl_var_free(&$$);}                       decl_var
 %type          <struct psi_decl_struct *>                      decl_struct
@@ -323,8 +323,8 @@ struct psi_parser;
 %destructor    {psi_decl_enum_free(&$$);}                      decl_enum
 %type          <struct psi_decl_enum_item *>           decl_enum_item
 %destructor    {psi_decl_enum_item_free(&$$);}         decl_enum_item
-%type          <struct psi_plist *>                            decl_args decl_struct_args struct_args_block struct_args decl_enum_items decl_vars
-%destructor    {psi_plist_free($$);}                           decl_args decl_struct_args struct_args_block struct_args decl_enum_items decl_vars
+%type          <struct psi_plist *>                            decl_args decl_struct_args struct_args_block struct_args struct_arg_var_list decl_enum_items decl_vars decl_vars_with_layout
+%destructor    {psi_plist_free($$);}                           decl_args decl_struct_args struct_args_block struct_args struct_arg_var_list decl_enum_items decl_vars decl_vars_with_layout
 
 %type          <struct psi_layout>                                     align_and_size
 %destructor    {}                                                                      align_and_size
@@ -737,7 +737,7 @@ decl_typedef[def]:
 
 typedef[def]:
        decl_arg
-|      decl {
+|      decl_func_body[decl] {
        $def = psi_decl_arg_init(
                psi_decl_type_init(PSI_T_FUNCTION, $decl->func->var->name),
                psi_decl_var_copy($decl->func->var)
@@ -981,31 +981,56 @@ decl_ext_var_list:
 }
 ;
 
+decl_vars[vars]:
+       decl_var[var] {
+       $vars = psi_plist_add(psi_plist_init((psi_plist_dtor) psi_decl_var_free), &$var);
+}
+|      decl_vars[vars_] COMMA decl_var[var] {
+       $vars = psi_plist_add($vars_, &$var);
+}
+;
+
 decl:
-       decl_fn[func] LPAREN decl_args[args] RPAREN array_size[as] {
-       $decl = psi_decl_init(psi_decl_abi_init("default"), $func, $args);
+       decl_body
+|      NAME[abi] decl_body {
+       $decl = $decl_body;
+       $decl->abi = psi_decl_abi_init($abi->text);
+}
+;
+
+decl_body:
+       decl_func_body
+|      decl_functor_body
+;
+
+decl_func_body[decl]:
+       decl_func[func] LPAREN decl_args[args] RPAREN array_size[as] {
+       $decl = psi_decl_init($func, $args);
        if ($as) {
                $decl->func->var->pointer_level += 1;
                $decl->func->var->array_size = $as;
        }
 }
-|      decl_fn[func] LPAREN decl_args[args] COMMA ELLIPSIS RPAREN array_size[as] {
-       $decl = psi_decl_init(psi_decl_abi_init("default"), $func, $args);
+|      decl_func[func] LPAREN decl_args[args] COMMA ELLIPSIS RPAREN array_size[as] {
+       $decl = psi_decl_init($func, $args);
        $decl->varargs = 1;
        if ($as) {
                $decl->func->var->pointer_level += 1;
                $decl->func->var->array_size = $as;
        }
 }
-|      NAME[abi] decl_fn[func] LPAREN decl_args[args] RPAREN array_size[as] {
-       $decl = psi_decl_init(psi_decl_abi_init($abi->text), $func, $args);
+;
+
+decl_functor_body[decl]:
+       decl_functor[func] LPAREN decl_args[args] RPAREN array_size[as] {
+       $decl = psi_decl_init($func, $args);
        if ($as) {
                $decl->func->var->pointer_level += 1;
                $decl->func->var->array_size = $as;
        }
 }
-|      NAME[abi] decl_fn[func] LPAREN decl_args[args] COMMA ELLIPSIS RPAREN array_size[as] {
-       $decl = psi_decl_init(psi_decl_abi_init($abi->text), $func, $args);
+|      decl_functor[func] LPAREN decl_args[args] COMMA ELLIPSIS RPAREN array_size[as] {
+       $decl = psi_decl_init($func, $args);
        $decl->varargs = 1;
        if ($as) {
                $decl->func->var->pointer_level += 1;
@@ -1014,11 +1039,6 @@ decl:
 }
 ;
 
-decl_fn:
-       decl_func
-|      decl_functor
-;
-
 decl_functor[arg]:
        const_decl_type[type] indirection[i] LPAREN indirection[unused1] name_token[NAME] RPAREN {
        (void) $unused1;
@@ -1091,7 +1111,15 @@ decl_args[args]:
 ;
 
 decl_arg[arg]:
-       const_decl_type[type] decl_var[var] {
+       decl_functor_body[decl] {
+       $arg = psi_decl_arg_init(
+               psi_decl_type_init(PSI_T_FUNCTION, $decl->func->var->name),
+               psi_decl_var_copy($decl->func->var)
+       );
+       $arg->type->token = psi_token_copy($decl->func->token);
+       $arg->type->real.func = $decl;
+}
+|      const_decl_type[type] decl_var[var] {
        $arg = psi_decl_arg_init($type, $var);
 }
 |      CONST VOID pointers name_token[NAME] {
@@ -1163,19 +1191,59 @@ struct_args_block[args]:
 ;
 
 struct_args[args]:
-       struct_arg[arg] {
+       typedef[arg] decl_layout[layout] struct_arg_var_list[vars] EOS {
+       $arg->layout = $layout;
        $args = psi_plist_add(psi_plist_init((psi_plist_dtor) psi_decl_arg_free), &$arg);
+       if ($vars) {
+               size_t i = 0;
+               struct psi_decl_arg *arg;
+               
+               while (psi_plist_get($vars, i++, &arg)) {
+                       arg->type = psi_decl_type_copy($arg->type);
+                       $args = psi_plist_add($args, &arg);
+               }
+               free($vars);
+       }
 }
-|      struct_args[args_] struct_arg[arg] {
+|      struct_args[args_] typedef[arg] decl_layout[layout] struct_arg_var_list[vars] EOS {
+       $arg->layout = $layout;
        $args = psi_plist_add($args_, &$arg);
+       if ($vars) {
+               size_t i = 0;
+               struct psi_decl_arg *arg;
+               
+               while (psi_plist_get($vars, i++, &arg)) {
+                       arg->type = psi_decl_type_copy($arg->type);
+                       $args = psi_plist_add($args, &arg);
+               }
+               free($vars);
+       }
 }
 ;
 
-struct_arg[arg]:
-       typedef[arg_] decl_layout[layout] EOS {
-       $arg = $arg_;
-       $arg->layout = $layout;
-       psi_parser_proc_add_from_typedef(P, $arg);
+struct_arg_var_list[vars]:
+       %empty {
+       $vars = NULL;
+}
+|      COMMA decl_vars_with_layout[vars_] {
+       $vars = $vars_;
+}
+;
+
+decl_vars_with_layout[vars]:
+       decl_var[var] decl_layout[layout] {
+       {
+               struct psi_decl_arg *arg = psi_decl_arg_init(NULL, $var);
+               arg->layout = $layout;
+               $vars = psi_plist_add(psi_plist_init((psi_plist_dtor) psi_decl_arg_free), &arg);
+       }
+}
+|      decl_vars_with_layout[vars_] COMMA decl_var[var] decl_layout[layout] {
+       {
+               struct psi_decl_arg *arg = psi_decl_arg_init(NULL, $var);
+               arg->layout = $layout;
+               $vars = psi_plist_add($vars_, &arg);
+       }
 }
 ;
 
@@ -1307,8 +1375,14 @@ decl_layout[l]:
        %empty {
        $l = NULL;
 }
+|      COLON NUMBER[width] {
+       $l = psi_layout_init(0, 0, psi_layout_init(0, atol($width->text), NULL));
+}
 |      COLON COLON LPAREN NUMBER[align] COMMA NUMBER[size] RPAREN {
-       $l = psi_layout_init(atol($align->text), atol($size->text));
+       $l = psi_layout_init(atol($align->text), atol($size->text), NULL);
+}
+|      COLON NUMBER[width] COLON COLON LPAREN NUMBER[align] COMMA NUMBER[size] RPAREN {
+       $l = psi_layout_init(atol($align->text), atol($size->text), psi_layout_init(0, atol($width->text), NULL));
 }
 ;
 
@@ -1700,15 +1774,6 @@ free_exp[exp]:
 }
 ;
 
-decl_vars[vars]:
-       decl_var[var] {
-       $vars = psi_plist_add(psi_plist_init((psi_plist_dtor) psi_decl_var_free), &$var);
-}
-|      decl_vars[vars_] COMMA decl_var[var] {
-       $vars = psi_plist_add($vars_, &$var);
-}
-;
-
 reference:
        %empty {
        $reference = false;