type parser fixes
authorMichael Wallner <mike@php.net>
Tue, 26 Jan 2016 19:32:37 +0000 (20:32 +0100)
committerMichael Wallner <mike@php.net>
Tue, 26 Jan 2016 19:32:37 +0000 (20:32 +0100)
.gitignore
TODO
m4/psi.m4
m4/psi_type.m4
src/context.c
src/module.c
src/parser.h
src/parser.re
src/parser_proc.h
src/parser_proc.y
tests/parser/dump/dump001.phpt [new file with mode: 0644]

index 4eafc8b906da29489039a2e779a9816988c25d1a..4979790b117d110612041804b0311aa6194b4c30 100644 (file)
@@ -58,6 +58,7 @@ php_psi_decls.h
 php_psi_macros.h
 php_psi_redirs.h
 php_psi_stdinc.h
+php_psi_stdtypes.h
 php_psi_structs.h
 php_psi_types.h
 php_psi_va_decls.h
diff --git a/TODO b/TODO
index ee63abe58cf690118489fa11ee906b9ec94ee5c8..9ed0e5e54469f70f980c827c2c52e37dfa6e9923 100644 (file)
--- a/TODO
+++ b/TODO
@@ -6,3 +6,4 @@
 * pemalloc
 * unions
 * callbacks and function pointers
+* full struct typedefs
\ No newline at end of file
index 1f6af02f1930e960ba3661730d29d5a6023a3ebe..c9f4e080df6c0381680e18e623e896d22501daea 100644 (file)
--- a/m4/psi.m4
+++ b/m4/psi.m4
@@ -1,5 +1,6 @@
 dnl Generated headers with pre-defined types, structs, consts and decls.
 PSI_STDINC=$PHP_PSI_SRCDIR/php_psi_stdinc.h
+PSI_STDTYPES=$PHP_PSI_SRCDIR/php_psi_stdtypes.h
 PSI_TYPES=$PHP_PSI_SRCDIR/php_psi_types.h
 PSI_STRUCTS=$PHP_PSI_SRCDIR/php_psi_structs.h
 PSI_CONSTS=$PHP_PSI_SRCDIR/php_psi_consts.h
@@ -13,13 +14,25 @@ dnl Creates stubs of the headers with pre-defined types etc.
 dnl These headers are included by src/context.c.
 dnl This macro must be called prior any checks for a type, struct, decl etc.
 AC_DEFUN(PSI_CONFIG_INIT, [
-       cat >$PSI_TYPES <<EOF
+       cat >$PSI_STDTYPES <<EOF
 /* generated by configure */
 static struct psi_predef_type {
        token_t type_tag;
        const char *type_name;
        const char *alias;
-} psi_predef_types@<:@@:>@ = {
+} psi_std_types@<:@@:>@ = {
+       {PSI_T_INT8, "int8_t", NULL},
+       {PSI_T_INT16, "int16_t", NULL},
+       {PSI_T_INT32, "int32_t", NULL},
+       {PSI_T_INT64, "int64_t", NULL},
+       {PSI_T_UINT8, "uint8_t", NULL},
+       {PSI_T_UINT16, "uint16_t", NULL},
+       {PSI_T_UINT32, "uint32_t", NULL},
+       {PSI_T_UINT64, "uint64_t", NULL},
+EOF
+       cat >$PSI_TYPES <<EOF
+/* generated by configure */
+static struct psi_predef_type psi_predef_types@<:@@:>@ = {
 EOF
        cat >$PSI_STRUCTS <<EOF
 /* generated by configure */
@@ -74,7 +87,7 @@ AC_DEFUN(PSI_CONFIG_DONE, [
 /* generated by configure */
 PSI_INCLUDES
 EOF
-       for i in $PSI_TYPES $PSI_STRUCTS $PSI_CONSTS $PSI_REDIRS $PSI_DECLS $PSI_VA_DECLS; do
+       for i in $PSI_STDTYPES $PSI_TYPES $PSI_STRUCTS $PSI_CONSTS $PSI_REDIRS $PSI_DECLS $PSI_VA_DECLS; do
                cat >>$i <<EOF
        {0}
 };
index 7e4badbbbacb4bf3ab26e24d5c6aa4214d04e969..21484adb60c1622edaf92a32bf0638e16bed2644 100644 (file)
@@ -4,6 +4,10 @@ psi_add_type() {
        cat >>$PSI_TYPES <<<"   $1, "
 }
 
+psi_add_stdtype() {
+       cat >>$PSI_STDTYPES <<<"        $1, "
+}
+
 # psi_type_pair(type, size)
 # Output a PSI_T_<TYPE>, \"<TYPENAME>\" tuple.
 # Uses stdint types when possible.
@@ -48,7 +52,23 @@ AC_DEFUN(PSI_TYPE, [
        esac
        if test "$2" && PSI_SH_TEST_SIZEOF($1); then
                AS_TR_SH(psi_basic_type_$1)=$psi_basic_type
-               psi_add_type "{`psi_type_pair $psi_basic_type $AS_TR_SH([ac_cv_sizeof_]$1)`, \"$1\"}"
+               psi_add_type "{`psi_type_pair $psi_basic_type PSI_SH_SIZEOF($1)`, \"$1\"}"
+       fi
+])
+
+AC_DEFUN(PSI_STDTYPE, [
+       ifdef(AS_TR_CPP(AC_TYPE_$1), AS_TR_CPP(AC_TYPE_$1))
+       PSI_CHECK_SIZEOF($1)
+       if PSI_SH_TEST_SIZEOF($1); then
+               m4_case([$1],
+               [float],[psi_add_stdtype "{PSI_T_FLOAT, \"float\", NULL}"],
+               [double],[psi_add_stdtype "{PSI_T_DOUBLE, \"double\", NULL}"],
+               [long double],[psi_add_stdtype "{PSI_T_LONG_DOUBLE, \"long double\", NULL}"],
+               [
+                       AX_CHECK_SIGN($1, psi_basic_type=int, psi_basic_type=uint, PSI_INCLUDES)
+                       AS_TR_SH(psi_basic_type_$1)=$psi_basic_type
+                       psi_add_stdtype "{`psi_type_pair $psi_basic_type PSI_SH_SIZEOF($1)`, \"$1\"}"
+               ])
        fi
 ])
 
@@ -85,7 +105,7 @@ AC_DEFUN(PSI_OPAQUE_TYPE, [
                case "$AS_TR_SH([psi_cv_type_class_]$1)" in
                scalar)
                        AX_CHECK_SIGN($1, [psi_basic_type=int], [psi_basic_type=uint], PSI_INCLUDES)
-                       psi_add_type "{`psi_type_pair $psi_basic_type $AS_TR_SH([ac_cv_sizeof_]$1)`, \"$1\"}"
+                       psi_add_type "{`psi_type_pair $psi_basic_type PSI_SH_SIZEOF($1)`, \"$1\"}"
                        ;;
                struct)
                        PSI_STRUCT($1)
@@ -173,40 +193,41 @@ AC_DEFUN(PSI_CHECK_STD_TYPES, [
        AC_TYPE_UINT64_T
        PSI_CHECK_SIZEOF(uint64_t)
        AC_CHECK_ALIGNOF(uint64_t)
+       
+       PSI_CHECK_SIZEOF(void *)
+       AC_CHECK_ALIGNOF(void *)
 
-       PSI_TYPE(float)
+       PSI_STDTYPE(float)
        AC_CHECK_ALIGNOF(float)
-       PSI_TYPE(double)
+       PSI_STDTYPE(double)
        AC_CHECK_ALIGNOF(double)
-       PSI_TYPE(long double)
+       PSI_STDTYPE(long double)
        AC_CHECK_ALIGNOF(long double)
-       PSI_TYPE(void *)
-       AC_CHECK_ALIGNOF(void *)
 
-       PSI_TYPE(char, int)
-       PSI_TYPE(signed char, int)
-       PSI_TYPE(unsigned char, uint)
-       PSI_TYPE(short, int)
-       PSI_TYPE(short int, int)
-       PSI_TYPE(signed short, int)
-       PSI_TYPE(signed short int, int)
-       PSI_TYPE(unsigned short, uint)
-       PSI_TYPE(unsigned short int, uint)
-       PSI_TYPE(int, int)
-       PSI_TYPE(signed int, int)
-       PSI_TYPE(signed, int)
-       PSI_TYPE(unsigned int, uint)
-       PSI_TYPE(unsigned, uint)
-       PSI_TYPE(long, int)
-       PSI_TYPE(long int, int)
-       PSI_TYPE(signed long int, int)
-       PSI_TYPE(unsigned long, uint)
-       PSI_TYPE(unsigned long int, uint)
-       PSI_TYPE(long long, int)
-       PSI_TYPE(signed long long, int)
-       PSI_TYPE(signed long long int, int)
-       PSI_TYPE(unsigned long long, uint)
-       PSI_TYPE(unsigned long long int, uint)
+       PSI_STDTYPE(char, int)
+       PSI_STDTYPE(signed char, int)
+       PSI_STDTYPE(unsigned char, uint)
+       PSI_STDTYPE(short, int)
+       PSI_STDTYPE(short int, int)
+       PSI_STDTYPE(signed short, int)
+       PSI_STDTYPE(signed short int, int)
+       PSI_STDTYPE(unsigned short, uint)
+       PSI_STDTYPE(unsigned short int, uint)
+       PSI_STDTYPE(int, int)
+       PSI_STDTYPE(signed int, int)
+       PSI_STDTYPE(signed, int)
+       PSI_STDTYPE(unsigned int, uint)
+       PSI_STDTYPE(unsigned, uint)
+       PSI_STDTYPE(long, int)
+       PSI_STDTYPE(long int, int)
+       PSI_STDTYPE(signed long int, int)
+       PSI_STDTYPE(unsigned long, uint)
+       PSI_STDTYPE(unsigned long int, uint)
+       PSI_STDTYPE(long long, int)
+       PSI_STDTYPE(signed long long, int)
+       PSI_STDTYPE(signed long long int, int)
+       PSI_STDTYPE(unsigned long long, uint)
+       PSI_STDTYPE(unsigned long long int, uint)
        dnl this must come after the check fo "unsigned long long int"; autoconf, wth?
-       PSI_TYPE(long long int, int)
+       PSI_STDTYPE(long long int, int)
 ])
index 0242b77ae3c5bd2844c12862f762ef3d01a6faf0..f0f2a6a3033bed29115b5f6281946250e1ac15ec 100644 (file)
 #include "libjit.h"
 #include "libffi.h"
 
-static struct psi_std_type {
-       token_t type_tag;
-       const char *type_name;
-} psi_std_types[] = {
-       {PSI_T_FLOAT, "float"},
-       {PSI_T_DOUBLE, "double"},
-#ifdef HAVE_LONG_DOUBLE
-       {PSI_T_LONG_DOUBLE, "long double"},
-#endif
-       {PSI_T_INT8, "int8_t"},
-       {PSI_T_INT16, "int16_t"},
-       {PSI_T_INT32, "int32_t"},
-       {PSI_T_INT64, "int64_t"},
-       {PSI_T_UINT8, "uint8_t"},
-       {PSI_T_UINT16, "uint16_t"},
-       {PSI_T_UINT32, "uint32_t"},
-       {PSI_T_UINT64, "uint64_t"},
-       {0}
-};
-
+#include "php_psi_stdtypes.h"
 #include "php_psi_types.h"
 #include "php_psi_consts.h"
 #include "php_psi_macros.h"
@@ -88,7 +69,7 @@ static int validate_lib(PSI_Data *data, void **dlopened) {
 
 static inline int locate_decl_type_alias(decl_typedefs *defs, decl_type *type) {
        size_t i;
-       struct psi_std_type *stdtyp;
+       struct psi_predef_type *stdtyp;
 
        if (type->real) {
                return 1;
@@ -102,7 +83,7 @@ static inline int locate_decl_type_alias(decl_typedefs *defs, decl_type *type) {
                }
        }
        for (stdtyp = &psi_std_types[0]; stdtyp->type_tag; ++stdtyp) {
-               if (!strcmp(type->name, stdtyp->type_name)) {
+               if (!strcmp(type->name, stdtyp->alias ?: stdtyp->type_name)) {
                        type->type = stdtyp->type_tag;
                        return 1;
                }
@@ -1270,7 +1251,7 @@ static inline void dump_num_exp(int fd, num_exp *exp) {
        }
 }
 
-static inline void dump_impl_set_value(int fd, set_value *set, unsigned level) {
+static inline void dump_impl_set_value(int fd, set_value *set, unsigned level, int last) {
        size_t i;
 
        if (level > 1) {
@@ -1302,13 +1283,13 @@ static inline void dump_impl_set_value(int fd, set_value *set, unsigned level) {
        if (set->inner && set->func->type != PSI_T_ELLIPSIS) {
                dprintf(fd, ",\n");
                for (i = 0; i < set->count; ++i) {
-                       dump_impl_set_value(fd, set->inner[i], level+1);
+                       dump_impl_set_value(fd, set->inner[i], level+1, i == (set->count - 1));
                }
                /* only if inner stmts, i.e. with new lines, were dumped */
                dump_level(fd, level);
        }
        if (level > 1) {
-               dprintf(fd, "),\n");
+               dprintf(fd, ")%s\n", last ? "" : ",");
        } else {
                dprintf(fd, ");\n");
        }
@@ -1345,15 +1326,22 @@ void PSI_ContextDump(PSI_Context *C, int fd)
                for (i = 0; i < C->structs->count; ++i) {
                        decl_struct *strct = C->structs->list[i];
 
-                       dprintf(fd, "struct %s::(%zu) {\n", strct->name, strct->size);
-                       if (strct->args) for (j = 0; j < strct->args->count; ++j) {
-                               decl_arg *sarg = strct->args->args[j];
+                       dprintf(fd, "struct %s::(%zu)", strct->name, strct->size);
+                       if (strct->args && strct->args->count) {
+                               dprintf(fd, " {\n");
+                               for (j = 0; j < strct->args->count; ++j) {
+                                       decl_arg *sarg = strct->args->args[j];
 
-                               dprintf(fd, "\t");
-                               dump_decl_arg(fd, sarg);
-                               dprintf(fd, "::(%zu, %zu);\n", sarg->layout->pos, sarg->layout->len);
+                                       dprintf(fd, "\t");
+                                       dump_decl_arg(fd, sarg);
+                                       dprintf(fd, "::(%zu, %zu);\n", sarg->layout->pos, sarg->layout->len);
+                               }
+                               dprintf(fd, "}");
+                       } else {
+                               dprintf(fd, ";");
                        }
-                       dprintf(fd, "}\n");
+                       dprintf(fd, "\n");
+
                }
                dprintf(fd, "\n");
        }
@@ -1460,13 +1448,13 @@ void PSI_ContextDump(PSI_Context *C, int fd)
                                        return_stmt *ret = impl->stmts->ret.list[j];
 
                                        dprintf(fd, "\treturn ");
-                                       dump_impl_set_value(fd, ret->set, 1);
+                                       dump_impl_set_value(fd, ret->set, 1, 0);
                                }
                                for (j = 0; j < impl->stmts->set.count; ++j) {
                                        set_stmt *set = impl->stmts->set.list[j];
 
                                        dprintf(fd, "\tset $%s = ", set->var->name);
-                                       dump_impl_set_value(fd, set->val, 1);
+                                       dump_impl_set_value(fd, set->val, 1, 0);
                                }
                                for (j = 0; j < impl->stmts->fre.count; ++j) {
                                        free_stmt *fre = impl->stmts->fre.list[j];
index 184cf0c558ee0a88a6be03ab0d5b5899639888fa..84d3e95d034de9f12e61e18c45fd23d1d2dd56fd 100644 (file)
@@ -40,7 +40,7 @@ void psi_error_wrapper(PSI_Token *t, int type, const char *msg, ...)
        va_list argv;
 
        va_start(argv, msg);
-       psi_verror(type, t?t->file:"Unknown", t?*t->line:0, msg, argv);
+       psi_verror(type, t?t->file:"Unknown", t?t->line:0, msg, argv);
        va_end(argv);
 }
 void psi_error(int type, const char *fn, unsigned ln, const char *msg, ...)
index de5ba10fbdebede9a99037a54a0e393b121e834c..5582922453923a3a4ce8a0a1dc2e8e61577d1799 100644 (file)
@@ -23,7 +23,7 @@ size_t psi_t_size(token_t);
 
 typedef struct PSI_Token {
        token_t type;
-       unsigned size, *line;
+       unsigned size, line;
        char *text, *file;
        char buf[1];
 } PSI_Token;
@@ -1299,7 +1299,7 @@ typedef struct PSI_Parser {
 } PSI_Parser;
 
 static inline size_t PSI_TokenAllocSize(size_t token_len, size_t fname_len) {
-       return sizeof(PSI_Token) + token_len + fname_len + sizeof(unsigned) + 2;
+       return sizeof(PSI_Token) + token_len + fname_len + 2;
 }
 
 static inline PSI_Token *PSI_TokenAlloc(PSI_Parser *P) {
@@ -1320,11 +1320,10 @@ static inline PSI_Token *PSI_TokenAlloc(PSI_Parser *P) {
        T->size = token_len;
        T->text = &T->buf[0];
        T->file = &T->buf[token_len + 1];
-       T->line = (void *) &T->buf[fname_len + token_len + 2];
+       T->line = P->line;
 
        memcpy(T->text, P->tok, token_len);
        memcpy(T->file, P->psi.file.fn, fname_len);
-       memcpy(T->line, &P->line, sizeof(unsigned));
 
        return T;
 }
@@ -1351,12 +1350,14 @@ static inline PSI_Token *PSI_TokenCat(unsigned argc, ...) {
                PSI_Token *arg = va_arg(argv, PSI_Token *);
 
                if (T) {
-                       size_t fname_len = strlen(T->file);
+                       size_t token_len = T->size, fname_len = strlen(T->file);
 
-                       T = realloc(T, PSI_TokenAllocSize(T->size + arg->size, fname_len));
-                       memmove(&T->buf[T->size + 1], T->file, fname_len + 1);
-                       memcpy(T->file - 1, arg->text, arg->size + 1);
+                       T = realloc(T, PSI_TokenAllocSize(T->size += arg->size + 1, fname_len));
+                       T->text = &T->buf[0];
                        T->file = &T->buf[T->size + 1];
+                       T->buf[token_len] = ' ';
+                       memmove(&T->buf[T->size + 1], &T->buf[token_len + 1], fname_len + 1);
+                       memcpy(&T->buf[token_len + 1], arg->text, arg->size + 1);
                } else {
                        T = PSI_TokenCopy(arg);
                        T->type = PSI_T_NAME;
index 70ab698ab88bf1b69f0a209c4eb333f4033181d2..0922ba1b0f23f6ceb3debb4b9ffbe8c058aa77ae 100644 (file)
@@ -1,3 +1,4 @@
+#include <stddef.h>
 #include <stdio.h>
 #include <assert.h>
 
index 7fe90fd3c6acddfa4c16302bbad790c7e2201200..7e8a7fe9e2a8dd29b21cdd732b7350541bf736e9 100644 (file)
@@ -9,35 +9,35 @@
 #define PSI_T_LET                              9
 #define PSI_T_RETURN                          10
 #define PSI_T_LIB                             11
-#define PSI_T_CHAR                            12
-#define PSI_T_SHORT                           13
-#define PSI_T_INT                             14
-#define PSI_T_LONG                            15
-#define PSI_T_SIGNED                          16
-#define PSI_T_UNSIGNED                        17
-#define PSI_T_EOF                             18
-#define PSI_T_QUOTED_STRING                   19
-#define PSI_T_EOS                             20
-#define PSI_T_STRUCT                          21
-#define PSI_T_LBRACE                          22
-#define PSI_T_RBRACE                          23
-#define PSI_T_COLON                           24
-#define PSI_T_LPAREN                          25
-#define PSI_T_NUMBER                          26
-#define PSI_T_RPAREN                          27
-#define PSI_T_BOOL                            28
-#define PSI_T_FLOAT                           29
-#define PSI_T_STRING                          30
-#define PSI_T_CONST                           31
-#define PSI_T_NSNAME                          32
-#define PSI_T_EQUALS                          33
-#define PSI_T_TYPEDEF                         34
-#define PSI_T_VOID                            35
-#define PSI_T_LBRACKET                        36
-#define PSI_T_RBRACKET                        37
-#define PSI_T_COMMA                           38
-#define PSI_T_ELLIPSIS                        39
-#define PSI_T_DOUBLE                          40
+#define PSI_T_STRING                          12
+#define PSI_T_EOF                             13
+#define PSI_T_EOS                             14
+#define PSI_T_QUOTED_STRING                   15
+#define PSI_T_STRUCT                          16
+#define PSI_T_LBRACE                          17
+#define PSI_T_RBRACE                          18
+#define PSI_T_COLON                           19
+#define PSI_T_LPAREN                          20
+#define PSI_T_NUMBER                          21
+#define PSI_T_RPAREN                          22
+#define PSI_T_BOOL                            23
+#define PSI_T_INT                             24
+#define PSI_T_FLOAT                           25
+#define PSI_T_CONST                           26
+#define PSI_T_NSNAME                          27
+#define PSI_T_EQUALS                          28
+#define PSI_T_TYPEDEF                         29
+#define PSI_T_VOID                            30
+#define PSI_T_LBRACKET                        31
+#define PSI_T_RBRACKET                        32
+#define PSI_T_COMMA                           33
+#define PSI_T_ELLIPSIS                        34
+#define PSI_T_CHAR                            35
+#define PSI_T_SHORT                           36
+#define PSI_T_LONG                            37
+#define PSI_T_DOUBLE                          38
+#define PSI_T_UNSIGNED                        39
+#define PSI_T_SIGNED                          40
 #define PSI_T_INT8                            41
 #define PSI_T_UINT8                           42
 #define PSI_T_INT16                           43
index b4150ae6b5ee82b4331a3729aed13a4f235bc88c..1cc466f16cb969b97c665479bae33d970f299516 100644 (file)
@@ -1,4 +1,5 @@
 %include {
+#include <stddef.h>
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
@@ -19,7 +20,7 @@ void psi_error(int, const char *, int, const char *, ...);
 %syntax_error {
        ++P->errors;
        if (TOKEN && TOKEN->type != PSI_T_EOF) {
-               psi_error(PSI_WARNING, TOKEN->file, *TOKEN->line, "PSI syntax error: Unexpected token '%s'", TOKEN->text);
+               psi_error(PSI_WARNING, TOKEN->file, TOKEN->line, "PSI syntax error: Unexpected token '%s'", TOKEN->text);
        } else {
                psi_error(PSI_WARNING, P->psi.file.fn, P->line, "PSI syntax error: Unexpected end of input");
        }
@@ -28,7 +29,7 @@ void psi_error(int, const char *, int, const char *, ...);
 %nonassoc NAME.
 %left PLUS MINUS.
 %left SLASH ASTERISK.
-%fallback NAME TEMP FREE SET LET RETURN LIB CHAR SHORT INT LONG SIGNED UNSIGNED.
+%fallback NAME TEMP FREE SET LET RETURN LIB STRING.
 
 file ::= blocks.
 
@@ -36,6 +37,7 @@ blocks ::= block.
 blocks ::= blocks block.
 
 block ::= EOF.
+block ::= EOS.
 
 block ::= LIB(T) QUOTED_STRING(libname) EOS. {
        if (P->psi.file.ln) {
@@ -66,9 +68,23 @@ block ::= decl_struct(strct). {
        P->structs = add_decl_struct(P->structs, strct);
 }
 
+struct_name(n) ::= STRUCT NAME(N). {
+       n = N;
+}
+
+%type decl_struct_args {decl_args*}
+%destructor decl_struct_args {free_decl_args($$);}
+decl_struct_args(args_) ::= LBRACE struct_args(args) RBRACE. {
+       args_ = args;
+}
+decl_struct_args(args_) ::= EOS. {
+       args_ = init_decl_args(NULL);
+}
+
+
 %type decl_struct {decl_struct*}
 %destructor decl_struct {free_decl_struct($$);}
-decl_struct(strct) ::= STRUCT NAME(N) struct_size(size_) LBRACE struct_args(args) RBRACE. {
+decl_struct(strct) ::= struct_name(N) struct_size(size_) decl_struct_args(args). {
        strct = init_decl_struct(N->text, args);
        strct->size = size_;
        strct->token = N;
@@ -99,28 +115,22 @@ constant(constant) ::= CONST const_type(type) NSNAME(T) EQUALS impl_def_val(val)
 
 %type decl_typedef {decl_typedef*}
 %destructor decl_typedef {free_decl_typedef($$);}
-decl_typedef(def) ::= TYPEDEF decl_type(type) NAME(ALIAS) EOS. {
+decl_typedef(def) ::= TYPEDEF decl_typedef_body(def_) EOS. {
+       def = def_;
+}
+%type decl_typedef_body {decl_typedef*}
+%destructor decl_typedef_body {free_decl_typedef($$);}
+decl_typedef_body(def) ::= decl_type(type) NAME(ALIAS). {
        def = init_decl_typedef(ALIAS->text, type);
        def->token = ALIAS;
 }
+
 /* support opaque types */
-decl_typedef(def) ::= TYPEDEF VOID(V) indirection(i) NAME(ALIAS) EOS. {
+decl_typedef_body(def) ::= VOID(V) indirection(i) NAME(ALIAS). {
        def = init_decl_typedef(ALIAS->text, init_decl_type(i?PSI_T_POINTER:V->type, V->text));
        def->token = ALIAS;
        def->type->token = V;
 }
-decl_typedef(def) ::= TYPEDEF STRUCT(S) NAME(N) NAME(ALIAS) EOS. {
-       def = init_decl_typedef(ALIAS->text, init_decl_type(S->type, N->text));
-       def->token = ALIAS;
-       def->type->token = N;
-       free(S);
-}
-decl_typedef(def) ::= TYPEDEF decl_struct(s) NAME(ALIAS) EOS. {
-       def = init_decl_typedef(ALIAS->text, init_decl_type(PSI_T_STRUCT, s->name));
-       def->token = ALIAS;
-       def->type->token = PSI_TokenCopy(s->token);
-       def->type->strct = s;
-}
 
 %type decl {decl*}
 %destructor decl {free_decl($$);}
@@ -241,29 +251,54 @@ struct_layout(layout) ::= COLON COLON LPAREN NUMBER(POS) COMMA NUMBER(SIZ) RPARE
 decl_scalar_type(type_) ::= CHAR(C). {
        type_ = C;
 }
-decl_scalar_type(type_) ::= SHORT(S) INT(I). {
-       type_ = PSI_TokenCat(2, S, I);
-       free(S);
-       free(I);
+decl_scalar_type(type_) ::= SHORT(S) decl_scalar_type_short(s). {
+       if (s) {
+               type_ = PSI_TokenCat(2, S, s);
+               free(S);
+               free(s);
+       } else {
+               type_ = S;
+       }
 }
-decl_scalar_type(type_) ::= SHORT(S). {
-       type_ = S;
+decl_scalar_type_short(s) ::= . {
+       s = NULL;
 }
-decl_scalar_type(type_) ::= LONG(L) INT(I). {
-       type_ = PSI_TokenCat(2, L, I);
-       free(L);
-       free(I);
+
+decl_scalar_type_short(s) ::= INT(I). {
+       s = I;
 }
-decl_scalar_type(type_) ::= LONG(L1) LONG(L2) INT(I). {
-       type_ = PSI_TokenCat(3, L1, L2, I);
-       free(L1);
-       free(L2);
-       free(I);
+decl_scalar_type(type_) ::= INT(I). {
+       type_ = I;
 }
-decl_scalar_type(type_) ::= LONG(L1) LONG(L2). {
-       type_ = PSI_TokenCat(2, L1, L2);
-       free(L1);
-       free(L2);
+decl_scalar_type(type_) ::= LONG(L) decl_scalar_type_long(l). {
+       if (l) {
+               type_ = PSI_TokenCat(2, L, l);
+               free(L);
+               free(l);
+       } else {
+               type_ = L;
+       }
+}
+decl_scalar_type_long(l) ::= . {
+       l = NULL;
+}
+decl_scalar_type_long(l) ::= DOUBLE(D). {
+       l = D;
+}
+decl_scalar_type_long(l) ::= LONG(L) decl_scalar_type_long_long(ll). {
+       if (ll) {
+               l = PSI_TokenCat(2, L, ll);
+               free(L);
+               free(ll);
+       } else {
+               l = L;
+       }
+}
+decl_scalar_type_long_long(ll) ::= . {
+       ll = NULL;
+}
+decl_scalar_type_long_long(ll) ::= INT(I). {
+       ll = I;
 }
 decl_type(type_) ::= UNSIGNED(U) decl_scalar_type(N). {
        PSI_Token *T = PSI_TokenCat(2, U, N);
@@ -279,19 +314,24 @@ decl_type(type_) ::= SIGNED(S) decl_scalar_type(N). {
        free(S);
        free(N);
 }
+decl_type(type_) ::= UNSIGNED(U). {
+       type_ = init_decl_type(PSI_T_NAME, U->text);
+       type_->token = U;
+}
+decl_type(type_) ::= SIGNED(S). {
+       type_ = init_decl_type(PSI_T_NAME, S->text);
+       type_->token = S;
+}
+decl_type(type_) ::= decl_scalar_type(N). {
+       type_ = init_decl_type(N->type, N->text);
+       type_->token = N;
+}
 /* structs ! */
 decl_type(type_) ::= STRUCT(S) NAME(T). {
        type_ = init_decl_type(S->type, T->text);
        type_->token = T;
        free(S);
 }
-decl_type(type_) ::= LONG(L) DOUBLE(D). {
-       PSI_Token *T = PSI_TokenCat(2, L, D);
-       type_ = init_decl_type(T->type, T->text);
-       type_->token = T;
-       free(L);
-       free(D);
-}
 %token_class decl_type_token FLOAT DOUBLE INT8 UINT8 INT16 UINT16 INT32 UINT32 INT64 UINT64 NAME.
 %type decl_type {decl_type*}
 %destructor decl_type {free_decl_type($$);}
diff --git a/tests/parser/dump/dump001.phpt b/tests/parser/dump/dump001.phpt
new file mode 100644 (file)
index 0000000..68f23c2
--- /dev/null
@@ -0,0 +1,22 @@
+--TEST--
+parse dump
+--SKIPIF--
+<?php 
+extension_loaded("psi") or die("skip - need ext/psi");
+?>
+--FILE--
+===TEST===
+<?php 
+echo shell_exec("PSI_DUMP=1 ".PHP_BINARY." -r '' > ".__DIR__."/dump.psi");
+var_dump(file_exists(__DIR__."/dump.psi"));
+echo shell_exec(PHP_BINARY." -d psi.directory=".__DIR__." -r ''");
+?>
+===DONE===
+--EXPECT--
+===TEST===
+bool(true)
+===DONE===
+--CLEAN--
+<?php 
+@unlink(__DIR__."/dump.psi");
+?>
\ No newline at end of file