flush
authorMichael Wallner <mike@php.net>
Thu, 28 Jan 2016 13:46:18 +0000 (14:46 +0100)
committerMichael Wallner <mike@php.net>
Thu, 28 Jan 2016 13:46:18 +0000 (14:46 +0100)
src/parser.h
src/parser.re
src/parser_proc.h
src/parser_proc.y

index 6710996912d9cdea419f8b22ef65c97328466933..41741c0152abdd2e51c9672573f67e9ab195b4f7 100644 (file)
@@ -22,7 +22,7 @@ size_t psi_t_size(token_t);
 
 typedef struct PSI_Token {
        token_t type;
-       unsigned size, line;
+       unsigned size, line, col;
        char *text, *file;
        char buf[1];
 } PSI_Token;
@@ -61,6 +61,7 @@ typedef struct decl_type {
        struct decl_type *real;
        struct decl_struct *strct;
        struct decl_enum *enm;
+       struct decl *func;
 } decl_type;
 
 static inline decl_type *init_decl_type(token_t type, const char *name) {
@@ -1441,6 +1442,7 @@ static inline PSI_Token *PSI_TokenAlloc(PSI_Parser *P) {
        T->text = &T->buf[0];
        T->file = &T->buf[token_len + 1];
        T->line = P->line;
+       T->col = P->col;
 
        memcpy(T->text, P->tok, token_len);
        memcpy(T->file, P->psi.file.fn, fname_len);
@@ -1488,8 +1490,59 @@ static inline PSI_Token *PSI_TokenCat(unsigned argc, ...) {
        return T;
 }
 
-static inline const char *PSI_TokenLocation(PSI_Token *t) {
-       return t ? t->file : "<builtin>:0:0";
+static inline PSI_Token *PSI_TokenAppend(PSI_Token *T, unsigned argc, ...) {
+       va_list argv;
+       unsigned i;
+
+       va_start(argv, argc);
+       for (i = 0; i < argc; ++i) {
+               char *str = va_arg(argv, char *);
+               size_t str_len = strlen(str), token_len = T->size, fname_len = strlen(T->file);
+
+               T = realloc(T, PSI_TokenAllocSize(T->size += str_len + 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], str, str_len + 1);
+       }
+       va_end(argv);
+
+       return T;
+}
+
+static inline PSI_Token *PSI_TokenTranslit(PSI_Token *T, char *from, char *to) {
+       php_strtr(T->text, T->size, from, to, MIN(strlen(from), strlen(to)));
+       return T;
+}
+
+static inline uint64_t psi_hash(char *digest_buf, ...)
+{
+    uint64_t hash = 5381;
+    uint8_t c;
+    const uint8_t *ptr;
+    va_list argv;
+
+    va_start(argv, digest_buf);
+    while ((ptr = va_arg(argv, const uint8_t *))) {
+               while ((c = *ptr++)) {
+                       hash = ((hash << 5) + hash) + c;
+               }
+    }
+    va_end(argv);
+
+    if (digest_buf) {
+       sprintf(digest_buf, "%" PRIx64, hash);
+    }
+
+    return hash;
+}
+
+static inline uint64_t PSI_TokenHash(PSI_Token *t, char *digest_buf) {
+       char loc_buf[48];
+
+       sprintf(loc_buf, "%u%u", t->line, t->col);
+       return psi_hash(digest_buf, t->file, loc_buf, NULL);
 }
 
 #define PSI_PARSER_DEBUG 0x1
index 50d15aadd86d0b9ae7dfb35a1b445277afdbf554..5b7e80e83c24d81a36892167a51bbd6094704351 100644 (file)
@@ -209,10 +209,10 @@ void PSI_ParserFree(PSI_Parser **P)
 #define ADDCOLS \
        P->col += P->cur - P->tok
 
-#define NEWLINE \
+#define NEWLINE(label) \
        P->col = 1; \
        ++P->line; \
-       goto nextline
+       goto label
 
 token_t PSI_ParserScan(PSI_Parser *P)
 {
@@ -236,7 +236,8 @@ token_t PSI_ParserScan(PSI_Parser *P)
                QUOTED_STRING = "\"" ([^\"])+ "\"";
                NUMBER = [+-]? [0-9]* "."? [0-9]+ ([eE] [+-]? [0-9]+)?;
 
-               ("#"|"//") .* "\n" { NEWLINE; }
+               "/*" { goto comment; }
+               ("#"|"//") .* "\n" { NEWLINE(nextline); }
                "(" {RETURN(PSI_T_LPAREN);}
                ")" {RETURN(PSI_T_RPAREN);}
                ";" {RETURN(PSI_T_EOS);}
@@ -254,7 +255,7 @@ token_t PSI_ParserScan(PSI_Parser *P)
                "-" {RETURN(PSI_T_MINUS);}
                "/" {RETURN(PSI_T_SLASH);}
                "..." {RETURN(PSI_T_ELLIPSIS);}
-               [\r\n] { NEWLINE; }
+               [\r\n] { NEWLINE(nextline); }
                [\t ]+ { continue; }
                'TRUE' {RETURN(PSI_T_TRUE);}
                'FALSE' {RETURN(PSI_T_FALSE);}
@@ -284,6 +285,7 @@ token_t PSI_ParserScan(PSI_Parser *P)
                'FUNCTION' {RETURN(PSI_T_FUNCTION);}
                'TYPEDEF' {RETURN(PSI_T_TYPEDEF);}
                'STRUCT' {RETURN(PSI_T_STRUCT);}
+               'UNION' {RETURN(PSI_T_UNION);}
                'ENUM' {RETURN(PSI_T_ENUM);}
                'CONST' {RETURN(PSI_T_CONST);}
                'LIB' {RETURN(PSI_T_LIB);}
@@ -313,6 +315,14 @@ token_t PSI_ParserScan(PSI_Parser *P)
                QUOTED_STRING {RETURN(PSI_T_QUOTED_STRING);}
                [^] {break;}
                */
+
+       comment:
+               P->tok = P->cur;
+               /*!re2c
+               "\n" { NEWLINE(comment); }
+               "*" "/" { continue; }
+               [^] { goto comment; }
+               */
        }
        return -1;
 }
index c6fe15a6c4484c3773d013ccdefb3e1f0af8a933..4749e82197132c41bdcef8e55f6e785b265d3051 100644 (file)
 #define PSI_T_RETURN                          10
 #define PSI_T_LIB                             11
 #define PSI_T_STRING                          12
-#define PSI_T_EOF                             13
-#define PSI_T_EOS                             14
-#define PSI_T_QUOTED_STRING                   15
-#define PSI_T_ENUM                            16
-#define PSI_T_LBRACE                          17
-#define PSI_T_RBRACE                          18
-#define PSI_T_COMMA                           19
-#define PSI_T_EQUALS                          20
-#define PSI_T_STRUCT                          21
-#define PSI_T_COLON                           22
-#define PSI_T_LPAREN                          23
-#define PSI_T_NUMBER                          24
-#define PSI_T_RPAREN                          25
-#define PSI_T_BOOL                            26
-#define PSI_T_INT                             27
-#define PSI_T_FLOAT                           28
-#define PSI_T_CONST                           29
-#define PSI_T_NSNAME                          30
-#define PSI_T_TYPEDEF                         31
-#define PSI_T_VOID                            32
-#define PSI_T_LBRACKET                        33
-#define PSI_T_RBRACKET                        34
-#define PSI_T_ELLIPSIS                        35
-#define PSI_T_CHAR                            36
-#define PSI_T_SHORT                           37
-#define PSI_T_LONG                            38
-#define PSI_T_DOUBLE                          39
-#define PSI_T_UNSIGNED                        40
-#define PSI_T_SIGNED                          41
-#define PSI_T_INT8                            42
-#define PSI_T_UINT8                           43
-#define PSI_T_INT16                           44
-#define PSI_T_UINT16                          45
-#define PSI_T_INT32                           46
-#define PSI_T_UINT32                          47
-#define PSI_T_INT64                           48
-#define PSI_T_UINT64                          49
-#define PSI_T_FUNCTION                        50
-#define PSI_T_NULL                            51
-#define PSI_T_TRUE                            52
-#define PSI_T_FALSE                           53
-#define PSI_T_DOLLAR                          54
-#define PSI_T_CALLOC                          55
-#define PSI_T_OBJVAL                          56
-#define PSI_T_ARRVAL                          57
-#define PSI_T_PATHVAL                         58
-#define PSI_T_STRLEN                          59
-#define PSI_T_STRVAL                          60
-#define PSI_T_FLOATVAL                        61
-#define PSI_T_INTVAL                          62
-#define PSI_T_BOOLVAL                         63
-#define PSI_T_TO_OBJECT                       64
-#define PSI_T_TO_ARRAY                        65
-#define PSI_T_TO_STRING                       66
-#define PSI_T_TO_INT                          67
-#define PSI_T_TO_FLOAT                        68
-#define PSI_T_TO_BOOL                         69
-#define PSI_T_MIXED                           70
-#define PSI_T_ARRAY                           71
-#define PSI_T_OBJECT                          72
-#define PSI_T_AMPERSAND                       73
+#define PSI_T_STRUCT                          13
+#define PSI_T_UNION                           14
+#define PSI_T_EOF                             15
+#define PSI_T_EOS                             16
+#define PSI_T_QUOTED_STRING                   17
+#define PSI_T_ENUM                            18
+#define PSI_T_LBRACE                          19
+#define PSI_T_RBRACE                          20
+#define PSI_T_COMMA                           21
+#define PSI_T_EQUALS                          22
+#define PSI_T_COLON                           23
+#define PSI_T_LPAREN                          24
+#define PSI_T_NUMBER                          25
+#define PSI_T_RPAREN                          26
+#define PSI_T_BOOL                            27
+#define PSI_T_INT                             28
+#define PSI_T_FLOAT                           29
+#define PSI_T_CONST                           30
+#define PSI_T_NSNAME                          31
+#define PSI_T_TYPEDEF                         32
+#define PSI_T_VOID                            33
+#define PSI_T_LBRACKET                        34
+#define PSI_T_RBRACKET                        35
+#define PSI_T_ELLIPSIS                        36
+#define PSI_T_CHAR                            37
+#define PSI_T_SHORT                           38
+#define PSI_T_LONG                            39
+#define PSI_T_DOUBLE                          40
+#define PSI_T_UNSIGNED                        41
+#define PSI_T_SIGNED                          42
+#define PSI_T_INT8                            43
+#define PSI_T_UINT8                           44
+#define PSI_T_INT16                           45
+#define PSI_T_UINT16                          46
+#define PSI_T_INT32                           47
+#define PSI_T_UINT32                          48
+#define PSI_T_INT64                           49
+#define PSI_T_UINT64                          50
+#define PSI_T_FUNCTION                        51
+#define PSI_T_NULL                            52
+#define PSI_T_TRUE                            53
+#define PSI_T_FALSE                           54
+#define PSI_T_DOLLAR                          55
+#define PSI_T_CALLOC                          56
+#define PSI_T_OBJVAL                          57
+#define PSI_T_ARRVAL                          58
+#define PSI_T_PATHVAL                         59
+#define PSI_T_STRLEN                          60
+#define PSI_T_STRVAL                          61
+#define PSI_T_FLOATVAL                        62
+#define PSI_T_INTVAL                          63
+#define PSI_T_BOOLVAL                         64
+#define PSI_T_TO_OBJECT                       65
+#define PSI_T_TO_ARRAY                        66
+#define PSI_T_TO_STRING                       67
+#define PSI_T_TO_INT                          68
+#define PSI_T_TO_FLOAT                        69
+#define PSI_T_TO_BOOL                         70
+#define PSI_T_MIXED                           71
+#define PSI_T_ARRAY                           72
+#define PSI_T_OBJECT                          73
+#define PSI_T_AMPERSAND                       74
index 2068105e7886a4a3ef4bae9057c3e49abca4de9d..ac856ede483a5ac3e2d01c7ae1a8256ccb43ced1 100644 (file)
@@ -30,6 +30,7 @@ void psi_error(int, const char *, int, const char *, ...);
 %left PLUS MINUS.
 %left SLASH ASTERISK.
 %fallback NAME TEMP FREE SET LET RETURN LIB STRING.
+%fallback STRUCT UNION.
 
 file ::= blocks.
 
@@ -71,9 +72,24 @@ block ::= decl_enum(e). {
        P->enums = add_decl_enum(P->enums, e);
 }
 
-enum_name(n) ::= ENUM NAME(N). {
+optional_name(n) ::= .{
+       n = NULL;
+}
+optional_name(n) ::= NAME(N). {
        n = N;
 }
+enum_name(n) ::= ENUM(E) optional_name(N). {
+       if (N) {
+               n = N;
+               free(E);
+       } else {
+               char digest[17];
+
+               PSI_TokenHash(E, digest);
+               n = PSI_TokenTranslit(PSI_TokenAppend(E, 1, digest), " ", "@");
+       }
+}
+
 
 %type decl_enum {decl_enum *}
 %destructor decl_enum {free_decl_enum($$);}
@@ -102,8 +118,16 @@ decl_enum_item(i) ::= NAME(N). {
        i->token = N;
 }
 
-struct_name(n) ::= STRUCT NAME(N). {
-       n = N;
+struct_name(n) ::= STRUCT(S) optional_name(N). {
+       if (N) {
+               n = N;
+               free(S);
+       } else {
+               char digest[17];
+
+               PSI_TokenHash(S, digest);
+               n = PSI_TokenTranslit(PSI_TokenAppend(S, 1, digest), " ", "@");
+       }
 }
 
 %type decl_struct_args_block {decl_args*}
@@ -157,15 +181,27 @@ constant(constant) ::= CONST const_type(type) NSNAME(T) EQUALS impl_def_val(val)
 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) ::= struct_name(N) struct_size(size_) decl_struct_args_block(args) NAME(ALIAS). {
+%type decl_typedef_body_ex {decl_typedef*}
+%destructor decl_typedef_body_ex {free_decl_typedef($$);}
+decl_typedef_body_ex(def) ::= struct_name(N) struct_size(size_) decl_struct_args_block(args) NAME(ALIAS). {
        def = init_decl_typedef(ALIAS->text, init_decl_type(PSI_T_STRUCT, N->text));
        def->token = ALIAS;
+       def->type->token = PSI_TokenCopy(N);
        def->type->strct = init_decl_struct(N->text, args);
        def->type->strct->token = N;
        def->type->strct->size = size_;
 }
+decl_typedef_body_ex(def) ::= decl_enum(e) NAME(ALIAS). {
+       def = init_decl_typedef(ALIAS->text, init_decl_type(PSI_T_ENUM, e->name));
+       def->type->token = PSI_TokenCopy(e->token);
+       def->token = ALIAS;
+       def->type->enm = e;
+}
+%type decl_typedef_body {decl_typedef*}
+%destructor decl_typedef_body {free_decl_typedef($$);}
+decl_typedef_body(def) ::= decl_typedef_body_ex(def_). {
+       def = def_;
+}
 decl_typedef_body(def) ::= decl_type(type) NAME(ALIAS). {
        def = init_decl_typedef(ALIAS->text, type);
        def->token = ALIAS;
@@ -176,6 +212,12 @@ decl_typedef_body(def) ::= VOID(V) indirection(i) NAME(ALIAS). {
        def->token = ALIAS;
        def->type->token = V;
 }
+decl_typedef_body(def) ::= decl_func(func) LPAREN decl_args(args) RPAREN. {
+       def = init_decl_typedef(func->var->name, init_decl_type(PSI_T_FUNCTION, func->var->name));
+       def->type->token = PSI_TokenCopy(func->token);
+       def->type->func = init_decl(init_decl_abi("default"), func, args);
+       def->token = PSI_TokenCopy(func->token);
+}
 
 %type decl {decl*}
 %destructor decl {free_decl($$);}
@@ -276,6 +318,14 @@ struct_args(args) ::= struct_args(args_) struct_arg(arg). {
 }
 %type struct_arg {decl_arg*}
 %destructor struct_arg {free_decl_arg($$);}
+struct_arg(arg_) ::= decl_typedef_body_ex(def) EOS. {
+       arg_ = init_decl_arg(def->type, init_decl_var(def->alias, 0, 0));
+       arg_->var->arg = arg_;
+       arg_->token = PSI_TokenCopy(def->type->token);
+       arg_->var->token = def->token;
+       free(def->alias);
+       free(def);
+}
 struct_arg(arg) ::= decl_arg(arg_) struct_layout(layout_) EOS. {
        arg_->layout = layout_;
        arg = arg_;