CPP builtins
authorMichael Wallner <mike@php.net>
Mon, 10 Dec 2018 08:09:45 +0000 (09:09 +0100)
committerMichael Wallner <mike@php.net>
Mon, 10 Dec 2018 08:09:45 +0000 (09:09 +0100)
* __BASE_FILE__
* __INCLUDE_LEVEL__
* __TIMESTAMP__

13 files changed:
TODO
src/builtin.c
src/cpp.c
src/cpp.h
src/parser.c
src/parser.h
src/parser_scan.c
src/parser_scan.re
tests/parser/cpp004.phpt
tests/parser/cpp004/base_file.h [new file with mode: 0644]
tests/parser/cpp004/builtins.psi
tests/parser/cpp004/include_level.h [new file with mode: 0644]
tests/parser/cpp004/timestamp.h [new file with mode: 0644]

diff --git a/TODO b/TODO
index 7dc89a4..8823a08 100644 (file)
--- a/TODO
+++ b/TODO
 
 * variadic macros
 * predefined macros
-   * __COUNTER__               counter starting from 0, incremented each time expanded
-   * __BASE_FILE__             current PSI file
-   * __INCLUDE_LEVEL__ include level
-   * __TIMESTAMP__             lmod of current source file
+  ...
 * builtins
+  ...
 * int128
 * very small real numbers
 * cache tokens of files and copy tokens if used for further processing
index 6c767b9..057e6f2 100644 (file)
@@ -43,7 +43,10 @@ static bool has_include(struct psi_cpp *cpp, struct psi_token *target, struct ps
 static bool has_include_next(struct psi_cpp *cpp, struct psi_token *target, struct psi_plist **args, struct psi_plist **res);
 static bool has_feature(struct psi_cpp *cpp, struct psi_token *target, struct psi_plist **args, struct psi_plist **res);
 static bool builtin_constant_p(struct psi_cpp *cpp, struct psi_token *target, struct psi_plist **args, struct psi_plist **res);
+static bool BASE_FILE__(struct psi_cpp *cpp, struct psi_token *target, struct psi_plist **args, struct psi_plist **res);
 static bool COUNTER__(struct psi_cpp *cpp, struct psi_token *target, struct psi_plist **args, struct psi_plist **res);
+static bool INCLUDE_LEVEL__(struct psi_cpp *cpp, struct psi_token *target, struct psi_plist **args, struct psi_plist **res);
+static bool TIMESTAMP__(struct psi_cpp *cpp, struct psi_token *target, struct psi_plist **args, struct psi_plist **res);
 
 static inline struct psi_plist *builtin_sig(token_t typ, ...)
 {
@@ -102,7 +105,10 @@ PHP_MINIT_FUNCTION(psi_builtin)
        PSI_BUILTIN(has_feature, PSI_T_NAME);
        PSI_BUILTIN(builtin_constant_p, PSI_T_NAME);
 
+       PSI_BUILTIN(BASE_FILE__, -1);
        PSI_BUILTIN(COUNTER__, -1);
+       PSI_BUILTIN(INCLUDE_LEVEL__, -1);
+       PSI_BUILTIN(TIMESTAMP__, -1);
 
        return SUCCESS;
 }
@@ -181,20 +187,73 @@ static bool builtin_constant_p(struct psi_cpp *cpp, struct psi_token *target,
        return false;
 }
 
+#define NEW_TOKEN(typ, str, len) \
+       psi_token_init((typ), (str), (len), (target)->col, (target)->line, (target)->file)
+
+#define ADD_TOKEN(tok) do { \
+       struct psi_token *tok__ = tok; \
+       if (!*res) { \
+               *res = psi_plist_init((psi_plist_dtor) psi_token_free); \
+       } \
+       *res = psi_plist_add(*res, &tok__); \
+} while (0)
+
+#define ADD_QUOTED_STRING(buf, len) do { \
+       ADD_TOKEN(NEW_TOKEN(PSI_T_QUOTED_STRING, buf, len)); \
+} while(0)
+
+#define ADD_QUOTED_ZSTRING(zs) do { \
+       zend_string *zs_ = zs; \
+       ADD_QUOTED_STRING(zs_->val, zs_->len); \
+} while (0)
+
+#define ADD_UNSIGNED_NUMBER(u) do { \
+       char buf[0x20]; \
+       unsigned u_ = u; \
+       size_t len = sprintf(buf, "%u", u_); \
+       struct psi_token *tok_ = NEW_TOKEN(PSI_T_NUMBER, buf, len); \
+       tok_->flags |= PSI_NUMBER_INT | PSI_NUMBER_U; \
+       ADD_TOKEN(tok_); \
+} while (0)
+
+static bool BASE_FILE__(struct psi_cpp *cpp, struct psi_token *target,
+               struct psi_plist **args, struct psi_plist **res)
+{
+       ADD_QUOTED_ZSTRING(cpp->parser->input->file);
+       return true;
+}
+
 static bool COUNTER__(struct psi_cpp *cpp, struct psi_token *target,
                struct psi_plist **args, struct psi_plist **res)
 {
-       struct psi_token *tok;
-       char buf[0x20];
-       size_t len = sprintf(buf, "%u", cpp->counter++);
+       ADD_UNSIGNED_NUMBER(cpp->counter++);
+       return true;
+}
 
-       tok = psi_token_init(PSI_T_NUMBER, buf, len, target->col, target->line, target->file);
-       *res = psi_plist_init((psi_plist_dtor) psi_token_free);
-       *res = psi_plist_add(*res, &tok);
+static bool INCLUDE_LEVEL__(struct psi_cpp *cpp, struct psi_token *target,
+               struct psi_plist **args, struct psi_plist **res)
+{
+       ADD_UNSIGNED_NUMBER(cpp->include_level);
+       return true;
+}
 
+static bool TIMESTAMP__(struct psi_cpp *cpp, struct psi_token *target,
+               struct psi_plist **args, struct psi_plist **res)
+{
+       char *str;
+#ifdef HAVE_CTIME_R
+       char buf[26];
+       str = ctime_r(&cpp->parser->input->lmod, buf);
+#else
+       str = ctime(&cpp->parser->input->lmod);
+#endif
+
+       /* kill EOL */
+       ADD_QUOTED_STRING(str, 24);
        return true;
 }
 
+
 #ifdef __APPLE__
 #include <libkern/OSByteOrder.h>
 # define bswap_16(u) _OSSwapInt16(u)
index 034f8a2..c436ef3 100644 (file)
--- a/src/cpp.c
+++ b/src/cpp.c
@@ -504,7 +504,10 @@ bool psi_cpp_include(struct psi_cpp *cpp, const struct psi_token *file, unsigned
                return false;
        }
 
+       ++cpp->include_level;
        parsed = psi_cpp_process(cpp, &tokens, NULL);
+       --cpp->include_level;
+
        if (!parsed) {
                psi_plist_free(tokens);
                return false;
index 66a14fb..57e9eb5 100644 (file)
--- a/src/cpp.h
+++ b/src/cpp.h
@@ -49,6 +49,7 @@ struct psi_cpp {
        unsigned seen;
        unsigned expanded;
        unsigned counter;
+       unsigned include_level;
        bool do_cpp;
 };
 
index 2a89068..aa9b539 100644 (file)
@@ -32,6 +32,7 @@
 #include <assert.h>
 #include <errno.h>
 #include <stdarg.h>
+#include <time.h>
 
 #include <Zend/zend_smart_str.h>
 
@@ -101,6 +102,7 @@ struct psi_parser_input *psi_parser_open_file(struct psi_parser *P,
 
        memset(fb->buffer + sb.st_size, 0, psi_parser_maxfill());
 
+       fb->lmod = sb.st_mtim.tv_sec;
        fb->length = sb.st_size;
        fb->file = psi_string_init_interned(filename, strlen(filename), 1);
 
@@ -122,6 +124,7 @@ struct psi_parser_input *psi_parser_open_string(struct psi_parser *P,
        memcpy(sb->buffer, string, length);
        memset(sb->buffer + length, 0, psi_parser_maxfill());
 
+       sb->lmod = time(NULL);
        sb->length = length;
        sb->file = psi_string_init_interned("<stdin>", strlen("<stdin>"), 1);
 
@@ -270,16 +273,21 @@ bool psi_parser_parse(struct psi_parser *P, struct psi_parser_input *I)
        struct psi_plist *scanned, *preproc;
        size_t processed = 0;
 
+       P->input = I;
+
        if (!(scanned = psi_parser_scan(P, I))) {
+               P->input = NULL;
                return false;
        }
 
        if (!(preproc = psi_parser_preprocess(P, &scanned))) {
+               P->input = NULL;
                psi_plist_free(scanned);
                return false;
        }
 
        if (!psi_parser_process(P, preproc, &processed)) {
+               P->input = NULL;
                psi_plist_free(preproc);
                return false;
        }
@@ -287,6 +295,7 @@ bool psi_parser_parse(struct psi_parser *P, struct psi_parser_input *I)
        psi_parser_postprocess(P);
 
        psi_plist_free(preproc);
+       P->input = NULL;
        return true;
 }
 
index 31bd5b5..68bebb5 100644 (file)
@@ -38,19 +38,20 @@ struct psi_parser;
 
 struct psi_cpp;
 
-struct psi_parser {
-       PSI_DATA_MEMBERS;
-
-       struct psi_cpp *preproc;
-};
-
 struct psi_parser_input {
        size_t length;
        zend_string *file;
-       unsigned lines;
+       time_t lmod;
        char buffer[1];
 };
 
+struct psi_parser {
+       PSI_DATA_MEMBERS;
+
+       struct psi_cpp *preproc;
+       struct psi_parser_input *input;
+};
+
 static inline void psi_parser_input_free(struct psi_parser_input **I) {
        if (*I) {
                struct psi_parser_input *i = *I;
index 8ff3b11..262496b 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 1.1.1 on Fri Dec  7 11:06:28 2018 */
+/* Generated by re2c 1.1.1 on Mon Dec 10 08:53:39 2018 */
 #line 1 "src/parser_scan.re"
 /*******************************************************************************
  Copyright (c) 2016, Michael Wallner <mike@php.net>.
@@ -47,13 +47,13 @@ size_t psi_parser_maxfill(void) {
 
 #define NEWLINE() \
        eol = cur; \
-       ++I->lines
+       ++lines
 
 #define NEWTOKEN(t) do { \
        if (t == PSI_T_COMMENT || t == PSI_T_WHITESPACE) { \
-               token = psi_token_init(t, "", 0, tok - eol + 1, I->lines, I->file); \
+               token = psi_token_init(t, "", 0, tok - eol + 1, lines, I->file); \
        } else { \
-               token = psi_token_init(t, tok, cur - tok, tok - eol + 1, I->lines, I->file); \
+               token = psi_token_init(t, tok, cur - tok, tok - eol + 1, lines, I->file); \
        } \
        tokens = psi_plist_add(tokens, &token); \
        PSI_DEBUG_LOCK(P, \
@@ -69,7 +69,7 @@ struct psi_plist *psi_parser_scan(struct psi_parser *P, struct psi_parser_input
        struct psi_plist *tokens;
        struct psi_token *token;
        const char *tok, *cur, *lim, *mrk, *eol, *ctxmrk;
-       unsigned parens;
+       unsigned parens, lines = 1;
        bool escaped;
        token_t char_width;
 
@@ -77,7 +77,6 @@ struct psi_plist *psi_parser_scan(struct psi_parser *P, struct psi_parser_input
 
        tok = mrk = eol = cur = I->buffer;
        lim = I->buffer + I->length + YYMAXFILL;
-       I->lines = 1;
        tokens = psi_plist_init((psi_plist_dtor) psi_token_free);
 
        start: ;
@@ -88,7 +87,7 @@ struct psi_plist *psi_parser_scan(struct psi_parser *P, struct psi_parser_input
                (void) ctxmrk;
 
                
-#line 92 "src/parser_scan.c"
+#line 91 "src/parser_scan.c"
                {
                        unsigned char yych;
                        unsigned int yyaccept = 0;
@@ -213,9 +212,9 @@ struct psi_plist *psi_parser_scan(struct psi_parser *P, struct psi_parser_input
 yy2:
                        ++cur;
 yy3:
-#line 257 "src/parser_scan.re"
+#line 256 "src/parser_scan.re"
                        { CHECKEOF(); NEWTOKEN(-2); goto error; }
-#line 219 "src/parser_scan.c"
+#line 218 "src/parser_scan.c"
 yy4:
                        ++cur;
                        if (lim <= cur) CHECKEOF();;
@@ -227,14 +226,14 @@ yy4:
                        default:        goto yy6;
                        }
 yy6:
-#line 256 "src/parser_scan.re"
+#line 255 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_WHITESPACE); goto start; }
-#line 233 "src/parser_scan.c"
+#line 232 "src/parser_scan.c"
 yy7:
                        ++cur;
-#line 255 "src/parser_scan.re"
+#line 254 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_EOL); NEWLINE(); goto start; }
-#line 238 "src/parser_scan.c"
+#line 237 "src/parser_scan.c"
 yy9:
                        yych = *++cur;
                        switch (yych) {
@@ -242,14 +241,14 @@ yy9:
                        default:        goto yy10;
                        }
 yy10:
-#line 158 "src/parser_scan.re"
+#line 157 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_NOT); goto start; }
-#line 248 "src/parser_scan.c"
+#line 247 "src/parser_scan.c"
 yy11:
                        ++cur;
-#line 131 "src/parser_scan.re"
+#line 130 "src/parser_scan.re"
                        { escaped = false; tok += 1; goto string; }
-#line 253 "src/parser_scan.c"
+#line 252 "src/parser_scan.c"
 yy13:
                        yych = *++cur;
                        switch (yych) {
@@ -257,9 +256,9 @@ yy13:
                        default:        goto yy14;
                        }
 yy14:
-#line 141 "src/parser_scan.re"
+#line 140 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_HASH); goto start; }
-#line 263 "src/parser_scan.c"
+#line 262 "src/parser_scan.c"
 yy15:
                        yych = *++cur;
                        switch (yych) {
@@ -332,9 +331,9 @@ yy15:
                        }
 yy16:
                        ++cur;
-#line 159 "src/parser_scan.re"
+#line 158 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_MODULO); goto start; }
-#line 338 "src/parser_scan.c"
+#line 337 "src/parser_scan.c"
 yy18:
                        yych = *++cur;
                        switch (yych) {
@@ -342,44 +341,44 @@ yy18:
                        default:        goto yy19;
                        }
 yy19:
-#line 160 "src/parser_scan.re"
+#line 159 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_AMPERSAND); goto start; }
-#line 348 "src/parser_scan.c"
+#line 347 "src/parser_scan.c"
 yy20:
                        ++cur;
-#line 130 "src/parser_scan.re"
+#line 129 "src/parser_scan.re"
                        { escaped = false; tok += 1; goto character; }
-#line 353 "src/parser_scan.c"
+#line 352 "src/parser_scan.c"
 yy22:
                        ++cur;
-#line 142 "src/parser_scan.re"
+#line 141 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_LPAREN); goto start; }
-#line 358 "src/parser_scan.c"
+#line 357 "src/parser_scan.c"
 yy24:
                        ++cur;
-#line 143 "src/parser_scan.re"
+#line 142 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_RPAREN); goto start; }
-#line 363 "src/parser_scan.c"
+#line 362 "src/parser_scan.c"
 yy26:
                        ++cur;
-#line 156 "src/parser_scan.re"
+#line 155 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_ASTERISK); goto start; }
-#line 368 "src/parser_scan.c"
+#line 367 "src/parser_scan.c"
 yy28:
                        ++cur;
-#line 161 "src/parser_scan.re"
+#line 160 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_PLUS); goto start; }
-#line 373 "src/parser_scan.c"
+#line 372 "src/parser_scan.c"
 yy30:
                        ++cur;
-#line 145 "src/parser_scan.re"
+#line 144 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_COMMA); goto start; }
-#line 378 "src/parser_scan.c"
+#line 377 "src/parser_scan.c"
 yy32:
                        ++cur;
-#line 162 "src/parser_scan.re"
+#line 161 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_MINUS); goto start; }
-#line 383 "src/parser_scan.c"
+#line 382 "src/parser_scan.c"
 yy34:
                        yyaccept = 0;
                        yych = *(mrk = ++cur);
@@ -398,9 +397,9 @@ yy34:
                        default:        goto yy35;
                        }
 yy35:
-#line 173 "src/parser_scan.re"
+#line 172 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_PERIOD); goto start; }
-#line 404 "src/parser_scan.c"
+#line 403 "src/parser_scan.c"
 yy36:
                        yych = *++cur;
                        switch (yych) {
@@ -409,9 +408,9 @@ yy36:
                        default:        goto yy37;
                        }
 yy37:
-#line 163 "src/parser_scan.re"
+#line 162 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_SLASH); goto start; }
-#line 415 "src/parser_scan.c"
+#line 414 "src/parser_scan.c"
 yy38:
                        yyaccept = 1;
                        yych = *(mrk = ++cur);
@@ -424,9 +423,9 @@ yy38:
                        default:        goto yy125;
                        }
 yy39:
-#line 117 "src/parser_scan.re"
+#line 116 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_NUMBER); token->flags = PSI_NUMBER_INT; goto start; }
-#line 430 "src/parser_scan.c"
+#line 429 "src/parser_scan.c"
 yy40:
                        yyaccept = 1;
                        mrk = ++cur;
@@ -454,14 +453,14 @@ yy40:
                        }
 yy42:
                        ++cur;
-#line 146 "src/parser_scan.re"
+#line 145 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_COLON); goto start; }
-#line 460 "src/parser_scan.c"
+#line 459 "src/parser_scan.c"
 yy44:
                        ++cur;
-#line 144 "src/parser_scan.re"
+#line 143 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_EOS); goto start; }
-#line 465 "src/parser_scan.c"
+#line 464 "src/parser_scan.c"
 yy46:
                        yyaccept = 2;
                        yych = *(mrk = ++cur);
@@ -537,9 +536,9 @@ yy46:
                        default:        goto yy47;
                        }
 yy47:
-#line 171 "src/parser_scan.re"
+#line 170 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_LCHEVR); goto start; }
-#line 543 "src/parser_scan.c"
+#line 542 "src/parser_scan.c"
 yy48:
                        yych = *++cur;
                        switch (yych) {
@@ -547,9 +546,9 @@ yy48:
                        default:        goto yy49;
                        }
 yy49:
-#line 155 "src/parser_scan.re"
+#line 154 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_EQUALS); goto start; }
-#line 553 "src/parser_scan.c"
+#line 552 "src/parser_scan.c"
 yy50:
                        yych = *++cur;
                        switch (yych) {
@@ -558,14 +557,14 @@ yy50:
                        default:        goto yy51;
                        }
 yy51:
-#line 172 "src/parser_scan.re"
+#line 171 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_RCHEVR); goto start; }
-#line 564 "src/parser_scan.c"
+#line 563 "src/parser_scan.c"
 yy52:
                        ++cur;
-#line 175 "src/parser_scan.re"
+#line 174 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_IIF); goto start; }
-#line 569 "src/parser_scan.c"
+#line 568 "src/parser_scan.c"
 yy54:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -577,9 +576,9 @@ yy54:
                        default:        goto yy62;
                        }
 yy55:
-#line 250 "src/parser_scan.re"
+#line 249 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_NAME); goto start; }
-#line 583 "src/parser_scan.c"
+#line 582 "src/parser_scan.c"
 yy56:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -822,9 +821,9 @@ yy74:
                        }
 yy75:
                        ++cur;
-#line 149 "src/parser_scan.re"
+#line 148 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_LBRACKET); goto start; }
-#line 828 "src/parser_scan.c"
+#line 827 "src/parser_scan.c"
 yy77:
                        yych = *++cur;
                        switch (yych) {
@@ -906,19 +905,19 @@ yy77:
                        default:        goto yy183;
                        }
 yy78:
-#line 164 "src/parser_scan.re"
+#line 163 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_BSLASH); goto start; }
-#line 912 "src/parser_scan.c"
+#line 911 "src/parser_scan.c"
 yy79:
                        ++cur;
-#line 150 "src/parser_scan.re"
+#line 149 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_RBRACKET); goto start; }
-#line 917 "src/parser_scan.c"
+#line 916 "src/parser_scan.c"
 yy81:
                        ++cur;
-#line 166 "src/parser_scan.re"
+#line 165 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_CARET); goto start; }
-#line 922 "src/parser_scan.c"
+#line 921 "src/parser_scan.c"
 yy83:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -1058,9 +1057,9 @@ yy95:
                        }
 yy96:
                        ++cur;
-#line 147 "src/parser_scan.re"
+#line 146 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_LBRACE); goto start; }
-#line 1064 "src/parser_scan.c"
+#line 1063 "src/parser_scan.c"
 yy98:
                        yych = *++cur;
                        switch (yych) {
@@ -1068,29 +1067,29 @@ yy98:
                        default:        goto yy99;
                        }
 yy99:
-#line 165 "src/parser_scan.re"
+#line 164 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_PIPE); goto start; }
-#line 1074 "src/parser_scan.c"
+#line 1073 "src/parser_scan.c"
 yy100:
                        ++cur;
-#line 148 "src/parser_scan.re"
+#line 147 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_RBRACE); goto start; }
-#line 1079 "src/parser_scan.c"
+#line 1078 "src/parser_scan.c"
 yy102:
                        ++cur;
-#line 157 "src/parser_scan.re"
+#line 156 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_TILDE); goto start; }
-#line 1084 "src/parser_scan.c"
+#line 1083 "src/parser_scan.c"
 yy104:
                        ++cur;
-#line 151 "src/parser_scan.re"
+#line 150 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_CMP_NE); goto start; }
-#line 1089 "src/parser_scan.c"
+#line 1088 "src/parser_scan.c"
 yy106:
                        ++cur;
-#line 140 "src/parser_scan.re"
+#line 139 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_CPP_PASTE); goto start; }
-#line 1094 "src/parser_scan.c"
+#line 1093 "src/parser_scan.c"
 yy108:
                        ++cur;
                        if (lim <= cur) CHECKEOF();;
@@ -1164,14 +1163,14 @@ yy108:
                        default:        goto yy108;
                        }
 yy110:
-#line 252 "src/parser_scan.re"
+#line 251 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_DOLLAR_NAME); goto start; }
-#line 1170 "src/parser_scan.c"
+#line 1169 "src/parser_scan.c"
 yy111:
                        ++cur;
-#line 153 "src/parser_scan.re"
+#line 152 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_AND); goto start; }
-#line 1175 "src/parser_scan.c"
+#line 1174 "src/parser_scan.c"
 yy113:
                        yych = *++cur;
                        switch (yych) {
@@ -1288,19 +1287,19 @@ yy115:
                        default:        goto yy117;
                        }
 yy117:
-#line 123 "src/parser_scan.re"
+#line 122 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_NUMBER); token->flags = PSI_NUMBER_FLT; goto start; }
-#line 1294 "src/parser_scan.c"
+#line 1293 "src/parser_scan.c"
 yy118:
                        ++cur;
-#line 137 "src/parser_scan.re"
+#line 136 "src/parser_scan.re"
                        { goto comment; }
-#line 1299 "src/parser_scan.c"
+#line 1298 "src/parser_scan.c"
 yy120:
                        ++cur;
-#line 138 "src/parser_scan.re"
+#line 137 "src/parser_scan.re"
                        { goto comment_sl; }
-#line 1304 "src/parser_scan.c"
+#line 1303 "src/parser_scan.c"
 yy122:
                        yyaccept = 4;
                        mrk = ++cur;
@@ -1376,9 +1375,9 @@ yy127:
                        }
 yy128:
                        cur -= 1;
-#line 119 "src/parser_scan.re"
+#line 118 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_NUMBER); token->flags = PSI_NUMBER_INT | PSI_NUMBER_L; cur += 1; goto start; }
-#line 1382 "src/parser_scan.c"
+#line 1381 "src/parser_scan.c"
 yy129:
                        yych = *++cur;
                        switch (yych) {
@@ -1388,9 +1387,9 @@ yy129:
                        }
 yy130:
                        cur -= 1;
-#line 118 "src/parser_scan.re"
+#line 117 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_NUMBER); token->flags = PSI_NUMBER_INT | PSI_NUMBER_U; cur += 1; goto start; }
-#line 1394 "src/parser_scan.c"
+#line 1393 "src/parser_scan.c"
 yy131:
                        yych = *++cur;
                        switch (yych) {
@@ -1494,29 +1493,29 @@ yy132:
                        }
 yy134:
                        ++cur;
-#line 167 "src/parser_scan.re"
+#line 166 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_LSHIFT); goto start; }
-#line 1500 "src/parser_scan.c"
+#line 1499 "src/parser_scan.c"
 yy136:
                        ++cur;
-#line 169 "src/parser_scan.re"
+#line 168 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_CMP_LE); goto start; }
-#line 1505 "src/parser_scan.c"
+#line 1504 "src/parser_scan.c"
 yy138:
                        ++cur;
-#line 152 "src/parser_scan.re"
+#line 151 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_CMP_EQ); goto start; }
-#line 1510 "src/parser_scan.c"
+#line 1509 "src/parser_scan.c"
 yy140:
                        ++cur;
-#line 170 "src/parser_scan.re"
+#line 169 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_CMP_GE); goto start; }
-#line 1515 "src/parser_scan.c"
+#line 1514 "src/parser_scan.c"
 yy142:
                        ++cur;
-#line 168 "src/parser_scan.re"
+#line 167 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_RSHIFT); goto start; }
-#line 1520 "src/parser_scan.c"
+#line 1519 "src/parser_scan.c"
 yy144:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -1597,9 +1596,9 @@ yy145:
                        default:        goto yy61;
                        }
 yy146:
-#line 230 "src/parser_scan.re"
+#line 229 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_AS); goto start; }
-#line 1603 "src/parser_scan.c"
+#line 1602 "src/parser_scan.c"
 yy147:
                        ++cur;
                        if (lim <= cur) CHECKEOF();;
@@ -1848,9 +1847,9 @@ yy159:
                        default:        goto yy61;
                        }
 yy160:
-#line 200 "src/parser_scan.re"
+#line 199 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_IF); goto start; }
-#line 1854 "src/parser_scan.c"
+#line 1853 "src/parser_scan.c"
 yy161:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -1864,9 +1863,9 @@ yy161:
 yy162:
                        ++cur;
                        cur -= 1;
-#line 135 "src/parser_scan.re"
-                       { char_width = sizeof(wchar_t)/8; }
-#line 1870 "src/parser_scan.c"
+#line 134 "src/parser_scan.re"
+                       { char_width = sizeof(wchar_t); }
+#line 1869 "src/parser_scan.c"
 yy164:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -1983,9 +1982,9 @@ yy177:
 yy178:
                        ++cur;
                        cur -= 1;
-#line 134 "src/parser_scan.re"
+#line 133 "src/parser_scan.re"
                        { char_width = 4; }
-#line 1989 "src/parser_scan.c"
+#line 1988 "src/parser_scan.c"
 yy180:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -2084,9 +2083,9 @@ yy183:
                        default:        goto yy183;
                        }
 yy185:
-#line 251 "src/parser_scan.re"
+#line 250 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_NSNAME); goto start; }
-#line 2090 "src/parser_scan.c"
+#line 2089 "src/parser_scan.c"
 yy186:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -2216,9 +2215,9 @@ yy200:
 yy201:
                        ++cur;
                        cur -= 1;
-#line 133 "src/parser_scan.re"
+#line 132 "src/parser_scan.re"
                        { char_width = 2; }
-#line 2222 "src/parser_scan.c"
+#line 2221 "src/parser_scan.c"
 yy203:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -2246,14 +2245,14 @@ yy205:
                        }
 yy206:
                        ++cur;
-#line 154 "src/parser_scan.re"
+#line 153 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_OR); goto start; }
-#line 2252 "src/parser_scan.c"
+#line 2251 "src/parser_scan.c"
 yy208:
                        ++cur;
-#line 174 "src/parser_scan.re"
+#line 173 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_ELLIPSIS); goto start; }
-#line 2257 "src/parser_scan.c"
+#line 2256 "src/parser_scan.c"
 yy210:
                        yych = *++cur;
                        switch (yych) {
@@ -2268,15 +2267,15 @@ yy210:
 yy211:
                        ++cur;
                        cur -= 1;
-#line 124 "src/parser_scan.re"
+#line 123 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_NUMBER); token->flags = PSI_NUMBER_FLT | PSI_NUMBER_F; cur += 1; goto start; }
-#line 2274 "src/parser_scan.c"
+#line 2273 "src/parser_scan.c"
 yy213:
                        ++cur;
                        cur -= 1;
-#line 125 "src/parser_scan.re"
+#line 124 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_NUMBER); token->flags = PSI_NUMBER_FLT | PSI_NUMBER_L; cur += 1; goto start; }
-#line 2280 "src/parser_scan.c"
+#line 2279 "src/parser_scan.c"
 yy215:
                        yych = *++cur;
                        switch (yych) {
@@ -2303,9 +2302,9 @@ yy217:
                        ++cur;
 yy218:
                        cur -= 2;
-#line 120 "src/parser_scan.re"
+#line 119 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_NUMBER); token->flags = PSI_NUMBER_INT | PSI_NUMBER_UL; cur += 2; goto start; }
-#line 2309 "src/parser_scan.c"
+#line 2308 "src/parser_scan.c"
 yy219:
                        yych = *++cur;
                        switch (yych) {
@@ -2352,9 +2351,9 @@ yy220:
                        }
 yy222:
                        ++cur;
-#line 253 "src/parser_scan.re"
+#line 252 "src/parser_scan.re"
                        { tok += 1; cur -= 1; NEWTOKEN(PSI_T_CPP_HEADER); cur += 1; goto start; }
-#line 2358 "src/parser_scan.c"
+#line 2357 "src/parser_scan.c"
 yy224:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -2565,9 +2564,9 @@ yy241:
                        default:        goto yy61;
                        }
 yy242:
-#line 225 "src/parser_scan.re"
+#line 224 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_LET); goto start; }
-#line 2571 "src/parser_scan.c"
+#line 2570 "src/parser_scan.c"
 yy243:
                        yyaccept = 10;
                        yych = *(mrk = ++cur);
@@ -2640,9 +2639,9 @@ yy243:
                        default:        goto yy61;
                        }
 yy244:
-#line 224 "src/parser_scan.re"
+#line 223 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_LIB); goto start; }
-#line 2646 "src/parser_scan.c"
+#line 2645 "src/parser_scan.c"
 yy245:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -2772,9 +2771,9 @@ yy252:
                        default:        goto yy61;
                        }
 yy253:
-#line 226 "src/parser_scan.re"
+#line 225 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_SET); goto start; }
-#line 2778 "src/parser_scan.c"
+#line 2777 "src/parser_scan.c"
 yy254:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -3007,9 +3006,9 @@ yy273:
                        default:        goto yy61;
                        }
 yy274:
-#line 194 "src/parser_scan.re"
+#line 193 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_INT); goto start; }
-#line 3013 "src/parser_scan.c"
+#line 3012 "src/parser_scan.c"
 yy275:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -3075,9 +3074,9 @@ yy282:
 yy283:
                        ++cur;
                        cur -= 1;
-#line 132 "src/parser_scan.re"
+#line 131 "src/parser_scan.re"
                        { char_width = 1; }
-#line 3081 "src/parser_scan.c"
+#line 3080 "src/parser_scan.c"
 yy285:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -3109,27 +3108,27 @@ yy288:
 yy289:
                        ++cur;
                        cur -= 2;
-#line 127 "src/parser_scan.re"
+#line 126 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_NUMBER); token->flags = PSI_NUMBER_FLT | PSI_NUMBER_DD; cur += 2; goto start; }
-#line 3115 "src/parser_scan.c"
+#line 3114 "src/parser_scan.c"
 yy291:
                        ++cur;
                        cur -= 2;
-#line 126 "src/parser_scan.re"
+#line 125 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_NUMBER); token->flags = PSI_NUMBER_FLT | PSI_NUMBER_DF; cur += 2; goto start; }
-#line 3121 "src/parser_scan.c"
+#line 3120 "src/parser_scan.c"
 yy293:
                        ++cur;
                        cur -= 2;
-#line 128 "src/parser_scan.re"
+#line 127 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_NUMBER); token->flags = PSI_NUMBER_FLT | PSI_NUMBER_DL; cur += 2; goto start; }
-#line 3127 "src/parser_scan.c"
+#line 3126 "src/parser_scan.c"
 yy295:
                        ++cur;
                        cur -= 3;
-#line 121 "src/parser_scan.re"
+#line 120 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_NUMBER); token->flags = PSI_NUMBER_INT | PSI_NUMBER_ULL; cur += 3; goto start; }
-#line 3133 "src/parser_scan.c"
+#line 3132 "src/parser_scan.c"
 yy297:
                        ++cur;
                        if ((lim - cur) < 3) CHECKEOF();;
@@ -3285,9 +3284,9 @@ yy305:
                        default:        goto yy61;
                        }
 yy306:
-#line 204 "src/parser_scan.re"
+#line 203 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_ELIF); goto start; }
-#line 3291 "src/parser_scan.c"
+#line 3290 "src/parser_scan.c"
 yy307:
                        yyaccept = 14;
                        yych = *(mrk = ++cur);
@@ -3360,9 +3359,9 @@ yy307:
                        default:        goto yy61;
                        }
 yy308:
-#line 203 "src/parser_scan.re"
+#line 202 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_ELSE); goto start; }
-#line 3366 "src/parser_scan.c"
+#line 3365 "src/parser_scan.c"
 yy309:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -3467,9 +3466,9 @@ yy313:
                        default:        goto yy61;
                        }
 yy314:
-#line 231 "src/parser_scan.re"
+#line 230 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_FREE); goto start; }
-#line 3473 "src/parser_scan.c"
+#line 3472 "src/parser_scan.c"
 yy315:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -3590,9 +3589,9 @@ yy321:
                        default:        goto yy61;
                        }
 yy322:
-#line 215 "src/parser_scan.re"
+#line 214 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_NULL); goto start; }
-#line 3596 "src/parser_scan.c"
+#line 3595 "src/parser_scan.c"
 yy323:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -3744,9 +3743,9 @@ yy333:
                        default:        goto yy61;
                        }
 yy334:
-#line 232 "src/parser_scan.re"
+#line 231 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_TEMP); goto start; }
-#line 3750 "src/parser_scan.c"
+#line 3749 "src/parser_scan.c"
 yy335:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -3867,9 +3866,9 @@ yy341:
                        default:        goto yy61;
                        }
 yy342:
-#line 213 "src/parser_scan.re"
+#line 212 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_TRUE); goto start; }
-#line 3873 "src/parser_scan.c"
+#line 3872 "src/parser_scan.c"
 yy343:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -3958,9 +3957,9 @@ yy345:
                        default:        goto yy61;
                        }
 yy346:
-#line 241 "src/parser_scan.re"
+#line 240 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_ZVAL); goto start; }
-#line 3964 "src/parser_scan.c"
+#line 3963 "src/parser_scan.c"
 yy347:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -4070,9 +4069,9 @@ yy352:
                        default:        goto yy61;
                        }
 yy353:
-#line 191 "src/parser_scan.re"
+#line 190 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_BOOL); goto start; }
-#line 4076 "src/parser_scan.c"
+#line 4075 "src/parser_scan.c"
 yy354:
                        yyaccept = 21;
                        yych = *(mrk = ++cur);
@@ -4145,9 +4144,9 @@ yy354:
                        default:        goto yy61;
                        }
 yy355:
-#line 192 "src/parser_scan.re"
+#line 191 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_CHAR); goto start; }
-#line 4151 "src/parser_scan.c"
+#line 4150 "src/parser_scan.c"
 yy356:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -4234,9 +4233,9 @@ yy358:
                        default:        goto yy61;
                        }
 yy359:
-#line 188 "src/parser_scan.re"
+#line 187 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_ENUM); goto start; }
-#line 4240 "src/parser_scan.c"
+#line 4239 "src/parser_scan.c"
 yy360:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -4324,9 +4323,9 @@ yy362:
                        default:        goto yy61;
                        }
 yy363:
-#line 184 "src/parser_scan.re"
+#line 183 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_LINE); goto start; }
-#line 4330 "src/parser_scan.c"
+#line 4329 "src/parser_scan.c"
 yy364:
                        yyaccept = 24;
                        yych = *(mrk = ++cur);
@@ -4399,9 +4398,9 @@ yy364:
                        default:        goto yy61;
                        }
 yy365:
-#line 195 "src/parser_scan.re"
+#line 194 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_LONG); goto start; }
-#line 4405 "src/parser_scan.c"
+#line 4404 "src/parser_scan.c"
 yy366:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -4530,9 +4529,9 @@ yy374:
                        default:        goto yy61;
                        }
 yy375:
-#line 190 "src/parser_scan.re"
+#line 189 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_VOID); goto start; }
-#line 4536 "src/parser_scan.c"
+#line 4535 "src/parser_scan.c"
 yy376:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -4612,9 +4611,9 @@ yy377:
                        default:        goto yy61;
                        }
 yy378:
-#line 219 "src/parser_scan.re"
+#line 218 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_ARRAY); goto start; }
-#line 4618 "src/parser_scan.c"
+#line 4617 "src/parser_scan.c"
 yy379:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -4727,9 +4726,9 @@ yy384:
                        default:        goto yy61;
                        }
 yy385:
-#line 242 "src/parser_scan.re"
+#line 241 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_COUNT); goto start; }
-#line 4733 "src/parser_scan.c"
+#line 4732 "src/parser_scan.c"
 yy386:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -4810,9 +4809,9 @@ yy387:
                        default:        goto yy61;
                        }
 yy388:
-#line 205 "src/parser_scan.re"
+#line 204 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_ENDIF); goto start; }
-#line 4816 "src/parser_scan.c"
+#line 4815 "src/parser_scan.c"
 yy389:
                        yyaccept = 29;
                        yych = *(mrk = ++cur);
@@ -4885,9 +4884,9 @@ yy389:
                        default:        goto yy61;
                        }
 yy390:
-#line 210 "src/parser_scan.re"
+#line 209 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_ERROR); goto start; }
-#line 4891 "src/parser_scan.c"
+#line 4890 "src/parser_scan.c"
 yy391:
                        yyaccept = 30;
                        yych = *(mrk = ++cur);
@@ -4960,9 +4959,9 @@ yy391:
                        default:        goto yy61;
                        }
 yy392:
-#line 214 "src/parser_scan.re"
+#line 213 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_FALSE); goto start; }
-#line 4966 "src/parser_scan.c"
+#line 4965 "src/parser_scan.c"
 yy393:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -5051,9 +5050,9 @@ yy395:
                        default:        goto yy61;
                        }
 yy396:
-#line 201 "src/parser_scan.re"
+#line 200 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_IFDEF); goto start; }
-#line 5057 "src/parser_scan.c"
+#line 5056 "src/parser_scan.c"
 yy397:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -5150,9 +5149,9 @@ yy400:
                        default:        goto yy61;
                        }
 yy401:
-#line 216 "src/parser_scan.re"
+#line 215 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_MIXED); goto start; }
-#line 5156 "src/parser_scan.c"
+#line 5155 "src/parser_scan.c"
 yy402:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -5353,9 +5352,9 @@ yy418:
                        default:        goto yy61;
                        }
 yy419:
-#line 208 "src/parser_scan.re"
+#line 207 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_UNDEF); goto start; }
-#line 5359 "src/parser_scan.c"
+#line 5358 "src/parser_scan.c"
 yy420:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -5437,9 +5436,9 @@ yy421:
                        default:        goto yy61;
                        }
 yy422:
-#line 181 "src/parser_scan.re"
+#line 180 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_CPP_ASM); goto start; }
-#line 5443 "src/parser_scan.c"
+#line 5442 "src/parser_scan.c"
 yy423:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -5533,9 +5532,9 @@ yy426:
                        default:        goto yy61;
                        }
 yy427:
-#line 189 "src/parser_scan.re"
+#line 188 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_CONST); goto start; }
-#line 5539 "src/parser_scan.c"
+#line 5538 "src/parser_scan.c"
 yy428:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -5617,9 +5616,9 @@ yy429:
                        default:        goto yy61;
                        }
 yy430:
-#line 196 "src/parser_scan.re"
+#line 195 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_FLOAT); goto start; }
-#line 5623 "src/parser_scan.c"
+#line 5622 "src/parser_scan.c"
 yy431:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -5706,9 +5705,9 @@ yy433:
                        default:        goto yy61;
                        }
 yy434:
-#line 193 "src/parser_scan.re"
+#line 192 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_SHORT); goto start; }
-#line 5712 "src/parser_scan.c"
+#line 5711 "src/parser_scan.c"
 yy435:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -5809,9 +5808,9 @@ yy439:
                        default:        goto yy61;
                        }
 yy440:
-#line 187 "src/parser_scan.re"
+#line 186 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_UNION); goto start; }
-#line 5815 "src/parser_scan.c"
+#line 5814 "src/parser_scan.c"
 yy441:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -5898,9 +5897,9 @@ yy443:
                        default:        goto yy61;
                        }
 yy444:
-#line 239 "src/parser_scan.re"
+#line 238 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_ARRVAL); goto start; }
-#line 5904 "src/parser_scan.c"
+#line 5903 "src/parser_scan.c"
 yy445:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -5997,9 +5996,9 @@ yy448:
                        default:        goto yy61;
                        }
 yy449:
-#line 243 "src/parser_scan.re"
+#line 242 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_CALLOC); goto start; }
-#line 6003 "src/parser_scan.c"
+#line 6002 "src/parser_scan.c"
 yy450:
                        yyaccept = 41;
                        yych = *(mrk = ++cur);
@@ -6074,9 +6073,9 @@ yy450:
                        default:        goto yy61;
                        }
 yy451:
-#line 206 "src/parser_scan.re"
+#line 205 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_DEFINE); goto start; }
-#line 6080 "src/parser_scan.c"
+#line 6079 "src/parser_scan.c"
 yy452:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -6165,9 +6164,9 @@ yy454:
                        default:        goto yy61;
                        }
 yy455:
-#line 202 "src/parser_scan.re"
+#line 201 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_IFNDEF); goto start; }
-#line 6171 "src/parser_scan.c"
+#line 6170 "src/parser_scan.c"
 yy456:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -6248,9 +6247,9 @@ yy457:
                        default:        goto yy61;
                        }
 yy458:
-#line 236 "src/parser_scan.re"
+#line 235 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_INTVAL); goto start; }
-#line 6254 "src/parser_scan.c"
+#line 6253 "src/parser_scan.c"
 yy459:
                        yyaccept = 44;
                        yych = *(mrk = ++cur);
@@ -6323,9 +6322,9 @@ yy459:
                        default:        goto yy61;
                        }
 yy460:
-#line 220 "src/parser_scan.re"
+#line 219 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_OBJECT); goto start; }
-#line 6329 "src/parser_scan.c"
+#line 6328 "src/parser_scan.c"
 yy461:
                        yyaccept = 45;
                        yych = *(mrk = ++cur);
@@ -6398,9 +6397,9 @@ yy461:
                        default:        goto yy61;
                        }
 yy462:
-#line 240 "src/parser_scan.re"
+#line 239 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_OBJVAL); goto start; }
-#line 6404 "src/parser_scan.c"
+#line 6403 "src/parser_scan.c"
 yy463:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -6497,9 +6496,9 @@ yy466:
                        default:        goto yy61;
                        }
 yy467:
-#line 229 "src/parser_scan.re"
+#line 228 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_RETURN); goto start; }
-#line 6503 "src/parser_scan.c"
+#line 6502 "src/parser_scan.c"
 yy468:
                        yyaccept = 47;
                        yych = *(mrk = ++cur);
@@ -6572,9 +6571,9 @@ yy468:
                        default:        goto yy61;
                        }
 yy469:
-#line 222 "src/parser_scan.re"
+#line 221 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_STATIC); goto start; }
-#line 6578 "src/parser_scan.c"
+#line 6577 "src/parser_scan.c"
 yy470:
                        yyaccept = 48;
                        yych = *(mrk = ++cur);
@@ -6647,9 +6646,9 @@ yy470:
                        default:        goto yy61;
                        }
 yy471:
-#line 218 "src/parser_scan.re"
+#line 217 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_STRING); goto start; }
-#line 6653 "src/parser_scan.c"
+#line 6652 "src/parser_scan.c"
 yy472:
                        yyaccept = 49;
                        yych = *(mrk = ++cur);
@@ -6722,9 +6721,9 @@ yy472:
                        default:        goto yy61;
                        }
 yy473:
-#line 233 "src/parser_scan.re"
+#line 232 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_STRLEN); goto start; }
-#line 6728 "src/parser_scan.c"
+#line 6727 "src/parser_scan.c"
 yy474:
                        yyaccept = 50;
                        yych = *(mrk = ++cur);
@@ -6797,9 +6796,9 @@ yy474:
                        default:        goto yy61;
                        }
 yy475:
-#line 234 "src/parser_scan.re"
+#line 233 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_STRVAL); goto start; }
-#line 6803 "src/parser_scan.c"
+#line 6802 "src/parser_scan.c"
 yy476:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -6896,9 +6895,9 @@ yy479:
                        default:        goto yy61;
                        }
 yy480:
-#line 247 "src/parser_scan.re"
+#line 246 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_TO_INT); goto start; }
-#line 6902 "src/parser_scan.c"
+#line 6901 "src/parser_scan.c"
 yy481:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -7023,9 +7022,9 @@ yy488:
                        default:        goto yy61;
                        }
 yy489:
-#line 197 "src/parser_scan.re"
+#line 196 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_DOUBLE); goto start; }
-#line 7029 "src/parser_scan.c"
+#line 7028 "src/parser_scan.c"
 yy490:
                        yyaccept = 53;
                        yych = *(mrk = ++cur);
@@ -7098,9 +7097,9 @@ yy490:
                        default:        goto yy61;
                        }
 yy491:
-#line 178 "src/parser_scan.re"
+#line 177 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_CPP_INLINE); goto start; }
-#line 7104 "src/parser_scan.c"
+#line 7103 "src/parser_scan.c"
 yy492:
                        yyaccept = 54;
                        yych = *(mrk = ++cur);
@@ -7173,9 +7172,9 @@ yy492:
                        default:        goto yy529;
                        }
 yy493:
-#line 176 "src/parser_scan.re"
+#line 175 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_PRAGMA); goto start; }
-#line 7179 "src/parser_scan.c"
+#line 7178 "src/parser_scan.c"
 yy494:
                        yyaccept = 55;
                        yych = *(mrk = ++cur);
@@ -7248,9 +7247,9 @@ yy494:
                        default:        goto yy61;
                        }
 yy495:
-#line 199 "src/parser_scan.re"
+#line 198 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_SIGNED); goto start; }
-#line 7254 "src/parser_scan.c"
+#line 7253 "src/parser_scan.c"
 yy496:
                        yyaccept = 56;
                        yych = *(mrk = ++cur);
@@ -7323,9 +7322,9 @@ yy496:
                        default:        goto yy61;
                        }
 yy497:
-#line 183 "src/parser_scan.re"
+#line 182 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_SIZEOF); goto start; }
-#line 7329 "src/parser_scan.c"
+#line 7328 "src/parser_scan.c"
 yy498:
                        yyaccept = 57;
                        yych = *(mrk = ++cur);
@@ -7398,9 +7397,9 @@ yy498:
                        default:        goto yy61;
                        }
 yy499:
-#line 186 "src/parser_scan.re"
+#line 185 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_STRUCT); goto start; }
-#line 7404 "src/parser_scan.c"
+#line 7403 "src/parser_scan.c"
 yy500:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -7494,9 +7493,9 @@ yy503:
                        default:        goto yy61;
                        }
 yy504:
-#line 238 "src/parser_scan.re"
+#line 237 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_BOOLVAL); goto start; }
-#line 7500 "src/parser_scan.c"
+#line 7499 "src/parser_scan.c"
 yy505:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -7585,9 +7584,9 @@ yy507:
                        default:        goto yy61;
                        }
 yy508:
-#line 207 "src/parser_scan.re"
+#line 206 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_DEFINED); goto start; }
-#line 7591 "src/parser_scan.c"
+#line 7590 "src/parser_scan.c"
 yy509:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -7677,9 +7676,9 @@ yy511:
                        default:        goto yy61;
                        }
 yy512:
-#line 211 "src/parser_scan.re"
+#line 210 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_INCLUDE); goto start; }
-#line 7683 "src/parser_scan.c"
+#line 7682 "src/parser_scan.c"
 yy513:
                        yyaccept = 61;
                        yych = *(mrk = ++cur);
@@ -7752,9 +7751,9 @@ yy513:
                        default:        goto yy61;
                        }
 yy514:
-#line 235 "src/parser_scan.re"
+#line 234 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_PATHVAL); goto start; }
-#line 7758 "src/parser_scan.c"
+#line 7757 "src/parser_scan.c"
 yy515:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -7851,9 +7850,9 @@ yy518:
                        default:        goto yy61;
                        }
 yy519:
-#line 249 "src/parser_scan.re"
+#line 248 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_TO_BOOL); goto start; }
-#line 7857 "src/parser_scan.c"
+#line 7856 "src/parser_scan.c"
 yy520:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -7950,9 +7949,9 @@ yy523:
                        default:        goto yy61;
                        }
 yy524:
-#line 209 "src/parser_scan.re"
+#line 208 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_WARNING); goto start; }
-#line 7956 "src/parser_scan.c"
+#line 7955 "src/parser_scan.c"
 yy525:
                        yyaccept = 34;
                        yych = *(mrk = ++cur);
@@ -8191,9 +8190,9 @@ yy531:
                        default:        goto yy61;
                        }
 yy532:
-#line 185 "src/parser_scan.re"
+#line 184 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_TYPEDEF); goto start; }
-#line 8197 "src/parser_scan.c"
+#line 8196 "src/parser_scan.c"
 yy533:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -8280,9 +8279,9 @@ yy535:
                        default:        goto yy61;
                        }
 yy536:
-#line 217 "src/parser_scan.re"
+#line 216 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_CALLABLE); goto start; }
-#line 8286 "src/parser_scan.c"
+#line 8285 "src/parser_scan.c"
 yy537:
                        yyaccept = 66;
                        yych = *(mrk = ++cur);
@@ -8355,9 +8354,9 @@ yy537:
                        default:        goto yy61;
                        }
 yy538:
-#line 221 "src/parser_scan.re"
+#line 220 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_CALLBACK); goto start; }
-#line 8361 "src/parser_scan.c"
+#line 8360 "src/parser_scan.c"
 yy539:
                        yyaccept = 67;
                        yych = *(mrk = ++cur);
@@ -8430,9 +8429,9 @@ yy539:
                        default:        goto yy61;
                        }
 yy540:
-#line 237 "src/parser_scan.re"
+#line 236 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_FLOATVAL); goto start; }
-#line 8436 "src/parser_scan.c"
+#line 8435 "src/parser_scan.c"
 yy541:
                        yyaccept = 68;
                        yych = *(mrk = ++cur);
@@ -8505,9 +8504,9 @@ yy541:
                        default:        goto yy61;
                        }
 yy542:
-#line 223 "src/parser_scan.re"
+#line 222 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_FUNCTION); goto start; }
-#line 8511 "src/parser_scan.c"
+#line 8510 "src/parser_scan.c"
 yy543:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -8604,9 +8603,9 @@ yy546:
                        default:        goto yy61;
                        }
 yy547:
-#line 245 "src/parser_scan.re"
+#line 244 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_TO_ARRAY); goto start; }
-#line 8610 "src/parser_scan.c"
+#line 8609 "src/parser_scan.c"
 yy548:
                        yyaccept = 70;
                        yych = *(mrk = ++cur);
@@ -8679,9 +8678,9 @@ yy548:
                        default:        goto yy61;
                        }
 yy549:
-#line 248 "src/parser_scan.re"
+#line 247 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_TO_FLOAT); goto start; }
-#line 8685 "src/parser_scan.c"
+#line 8684 "src/parser_scan.c"
 yy550:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -8866,9 +8865,9 @@ yy557:
                        default:        goto yy61;
                        }
 yy558:
-#line 198 "src/parser_scan.re"
+#line 197 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_UNSIGNED); goto start; }
-#line 8872 "src/parser_scan.c"
+#line 8871 "src/parser_scan.c"
 yy559:
                        yyaccept = 72;
                        yych = *(mrk = ++cur);
@@ -8941,9 +8940,9 @@ yy559:
                        default:        goto yy61;
                        }
 yy560:
-#line 182 "src/parser_scan.re"
+#line 181 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_VOLATILE); goto start; }
-#line 8947 "src/parser_scan.c"
+#line 8946 "src/parser_scan.c"
 yy561:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -9040,9 +9039,9 @@ yy564:
                        default:        goto yy61;
                        }
 yy565:
-#line 244 "src/parser_scan.re"
+#line 243 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_TO_OBJECT); goto start; }
-#line 9046 "src/parser_scan.c"
+#line 9045 "src/parser_scan.c"
 yy566:
                        yyaccept = 74;
                        yych = *(mrk = ++cur);
@@ -9115,9 +9114,9 @@ yy566:
                        default:        goto yy61;
                        }
 yy567:
-#line 246 "src/parser_scan.re"
+#line 245 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_TO_STRING); goto start; }
-#line 9121 "src/parser_scan.c"
+#line 9120 "src/parser_scan.c"
 yy568:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -9302,9 +9301,9 @@ yy574:
                        default:        goto yy61;
                        }
 yy575:
-#line 227 "src/parser_scan.re"
+#line 226 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_PRE_ASSERT); goto start; }
-#line 9308 "src/parser_scan.c"
+#line 9307 "src/parser_scan.c"
 yy576:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -9391,9 +9390,9 @@ yy578:
                        default:        goto yy61;
                        }
 yy579:
-#line 179 "src/parser_scan.re"
+#line 178 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_CPP_RESTRICT); goto start; }
-#line 9397 "src/parser_scan.c"
+#line 9396 "src/parser_scan.c"
 yy580:
                        yyaccept = 3;
                        mrk = ++cur;
@@ -9549,9 +9548,9 @@ yy582:
                        default:        goto yy61;
                        }
 yy583:
-#line 228 "src/parser_scan.re"
+#line 227 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_POST_ASSERT); goto start; }
-#line 9555 "src/parser_scan.c"
+#line 9554 "src/parser_scan.c"
 yy584:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -9641,9 +9640,9 @@ yy586:
                        default:        goto yy529;
                        }
 yy587:
-#line 177 "src/parser_scan.re"
+#line 176 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_PRAGMA_ONCE); goto start; }
-#line 9647 "src/parser_scan.c"
+#line 9646 "src/parser_scan.c"
 yy588:
                        yyaccept = 79;
                        yych = *(mrk = ++cur);
@@ -9716,9 +9715,9 @@ yy588:
                        default:        goto yy61;
                        }
 yy589:
-#line 212 "src/parser_scan.re"
+#line 211 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_INCLUDE_NEXT); goto start; }
-#line 9722 "src/parser_scan.c"
+#line 9721 "src/parser_scan.c"
 yy590:
                        yyaccept = 3;
                        yych = *(mrk = ++cur);
@@ -9815,9 +9814,9 @@ yy593:
                        default:        goto yy61;
                        }
 yy594:
-#line 180 "src/parser_scan.re"
+#line 179 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_CPP_EXTENSION); goto start; }
-#line 9821 "src/parser_scan.c"
+#line 9820 "src/parser_scan.c"
 yy595:
                        ++cur;
                        if ((lim - cur) < 2) CHECKEOF();;
@@ -9837,16 +9836,16 @@ yy597:
                        }
 yy598:
                        ++cur;
-#line 254 "src/parser_scan.re"
+#line 253 "src/parser_scan.re"
                        { parens = 2; goto cpp_attribute; }
-#line 9843 "src/parser_scan.c"
+#line 9842 "src/parser_scan.c"
                }
-#line 260 "src/parser_scan.re"
+#line 259 "src/parser_scan.re"
 
 
        character: ;
                
-#line 9850 "src/parser_scan.c"
+#line 9849 "src/parser_scan.c"
                {
                        unsigned char yych;
                        if (lim <= cur) CHECKEOF();;
@@ -9860,17 +9859,17 @@ yy598:
                        }
 yy602:
                        ++cur;
-#line 278 "src/parser_scan.re"
+#line 277 "src/parser_scan.re"
                        { escaped = false; goto character; }
-#line 9866 "src/parser_scan.c"
+#line 9865 "src/parser_scan.c"
 yy604:
                        ++cur;
-#line 265 "src/parser_scan.re"
+#line 264 "src/parser_scan.re"
                        { NEWLINE(); goto character; }
-#line 9871 "src/parser_scan.c"
+#line 9870 "src/parser_scan.c"
 yy606:
                        ++cur;
-#line 267 "src/parser_scan.re"
+#line 266 "src/parser_scan.re"
                        {
                        if (escaped) {
                                escaped = false;
@@ -9882,19 +9881,19 @@ yy606:
                        token->flags = char_width;
                        goto start;
                }
-#line 9886 "src/parser_scan.c"
+#line 9885 "src/parser_scan.c"
 yy608:
                        ++cur;
-#line 266 "src/parser_scan.re"
+#line 265 "src/parser_scan.re"
                        { escaped = !escaped;  goto character; }
-#line 9891 "src/parser_scan.c"
+#line 9890 "src/parser_scan.c"
                }
-#line 280 "src/parser_scan.re"
+#line 279 "src/parser_scan.re"
 
 
        string: ;
                
-#line 9898 "src/parser_scan.c"
+#line 9897 "src/parser_scan.c"
                {
                        unsigned char yych;
                        if (lim <= cur) CHECKEOF();;
@@ -9908,17 +9907,17 @@ yy608:
                        }
 yy612:
                        ++cur;
-#line 298 "src/parser_scan.re"
+#line 297 "src/parser_scan.re"
                        { escaped = false; goto string; }
-#line 9914 "src/parser_scan.c"
+#line 9913 "src/parser_scan.c"
 yy614:
                        ++cur;
-#line 285 "src/parser_scan.re"
+#line 284 "src/parser_scan.re"
                        { NEWLINE(); goto string; }
-#line 9919 "src/parser_scan.c"
+#line 9918 "src/parser_scan.c"
 yy616:
                        ++cur;
-#line 287 "src/parser_scan.re"
+#line 286 "src/parser_scan.re"
                        {
                        if (escaped) {
                                escaped = false;
@@ -9930,19 +9929,19 @@ yy616:
                        token->flags = char_width;
                        goto start;
                }
-#line 9934 "src/parser_scan.c"
+#line 9933 "src/parser_scan.c"
 yy618:
                        ++cur;
-#line 286 "src/parser_scan.re"
+#line 285 "src/parser_scan.re"
                        { escaped = !escaped; goto string; }
-#line 9939 "src/parser_scan.c"
+#line 9938 "src/parser_scan.c"
                }
-#line 300 "src/parser_scan.re"
+#line 299 "src/parser_scan.re"
 
 
        comment: ;
                
-#line 9946 "src/parser_scan.c"
+#line 9945 "src/parser_scan.c"
                {
                        unsigned char yych;
                        if ((lim - cur) < 2) CHECKEOF();;
@@ -9956,14 +9955,14 @@ yy618:
 yy622:
                        ++cur;
 yy623:
-#line 307 "src/parser_scan.re"
+#line 306 "src/parser_scan.re"
                        { goto comment; }
-#line 9962 "src/parser_scan.c"
+#line 9961 "src/parser_scan.c"
 yy624:
                        ++cur;
-#line 305 "src/parser_scan.re"
+#line 304 "src/parser_scan.re"
                        { NEWLINE(); goto comment; }
-#line 9967 "src/parser_scan.c"
+#line 9966 "src/parser_scan.c"
 yy626:
                        yych = *++cur;
                        switch (yych) {
@@ -9972,16 +9971,16 @@ yy626:
                        }
 yy627:
                        ++cur;
-#line 306 "src/parser_scan.re"
+#line 305 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_COMMENT); goto start; }
-#line 9978 "src/parser_scan.c"
+#line 9977 "src/parser_scan.c"
                }
-#line 309 "src/parser_scan.re"
+#line 308 "src/parser_scan.re"
 
 
        comment_sl: ;
                
-#line 9985 "src/parser_scan.c"
+#line 9984 "src/parser_scan.c"
                {
                        unsigned char yych;
                        if (lim <= cur) CHECKEOF();;
@@ -9993,22 +9992,22 @@ yy627:
                        }
 yy631:
                        ++cur;
-#line 315 "src/parser_scan.re"
+#line 314 "src/parser_scan.re"
                        { goto comment_sl; }
-#line 9999 "src/parser_scan.c"
+#line 9998 "src/parser_scan.c"
 yy633:
                        ++cur;
-#line 314 "src/parser_scan.re"
+#line 313 "src/parser_scan.re"
                        { NEWTOKEN(PSI_T_COMMENT); tok = cur - 1; NEWTOKEN(PSI_T_EOL); NEWLINE(); goto start; }
-#line 10004 "src/parser_scan.c"
+#line 10003 "src/parser_scan.c"
                }
-#line 317 "src/parser_scan.re"
+#line 316 "src/parser_scan.re"
 
 
        cpp_attribute: ;
 
                
-#line 10012 "src/parser_scan.c"
+#line 10011 "src/parser_scan.c"
                {
                        unsigned char yych;
                        if (lim <= cur) CHECKEOF();;
@@ -10022,26 +10021,26 @@ yy633:
                        }
 yy637:
                        ++cur;
-#line 326 "src/parser_scan.re"
+#line 325 "src/parser_scan.re"
                        { goto cpp_attribute; }
-#line 10028 "src/parser_scan.c"
+#line 10027 "src/parser_scan.c"
 yy639:
                        ++cur;
-#line 325 "src/parser_scan.re"
+#line 324 "src/parser_scan.re"
                        { NEWLINE(); goto cpp_attribute; }
-#line 10033 "src/parser_scan.c"
+#line 10032 "src/parser_scan.c"
 yy641:
                        ++cur;
-#line 323 "src/parser_scan.re"
+#line 322 "src/parser_scan.re"
                        { ++parens; goto cpp_attribute; }
-#line 10038 "src/parser_scan.c"
+#line 10037 "src/parser_scan.c"
 yy643:
                        ++cur;
-#line 324 "src/parser_scan.re"
+#line 323 "src/parser_scan.re"
                        { if (parens == 1) { NEWTOKEN(PSI_T_CPP_ATTRIBUTE); goto start; } else { --parens; goto cpp_attribute; } }
-#line 10043 "src/parser_scan.c"
+#line 10042 "src/parser_scan.c"
                }
-#line 328 "src/parser_scan.re"
+#line 327 "src/parser_scan.re"
 
 error: ;
 
index f280b86..437b33f 100644 (file)
@@ -44,13 +44,13 @@ size_t psi_parser_maxfill(void) {
 
 #define NEWLINE() \
        eol = cur; \
-       ++I->lines
+       ++lines
 
 #define NEWTOKEN(t) do { \
        if (t == PSI_T_COMMENT || t == PSI_T_WHITESPACE) { \
-               token = psi_token_init(t, "", 0, tok - eol + 1, I->lines, I->file); \
+               token = psi_token_init(t, "", 0, tok - eol + 1, lines, I->file); \
        } else { \
-               token = psi_token_init(t, tok, cur - tok, tok - eol + 1, I->lines, I->file); \
+               token = psi_token_init(t, tok, cur - tok, tok - eol + 1, lines, I->file); \
        } \
        tokens = psi_plist_add(tokens, &token); \
        PSI_DEBUG_LOCK(P, \
@@ -66,7 +66,7 @@ struct psi_plist *psi_parser_scan(struct psi_parser *P, struct psi_parser_input
        struct psi_plist *tokens;
        struct psi_token *token;
        const char *tok, *cur, *lim, *mrk, *eol, *ctxmrk;
-       unsigned parens;
+       unsigned parens, lines = 1;
        bool escaped;
        token_t char_width;
 
@@ -74,7 +74,6 @@ struct psi_plist *psi_parser_scan(struct psi_parser *P, struct psi_parser_input
 
        tok = mrk = eol = cur = I->buffer;
        lim = I->buffer + I->length + YYMAXFILL;
-       I->lines = 1;
        tokens = psi_plist_init((psi_plist_dtor) psi_token_free);
 
        start: ;
@@ -121,8 +120,8 @@ struct psi_plist *psi_parser_scan(struct psi_parser *P, struct psi_parser_input
                INT_CONST / ('llu' | 'ull')     { NEWTOKEN(PSI_T_NUMBER); token->flags = PSI_NUMBER_INT | PSI_NUMBER_ULL; cur += 3; goto start; }
 
                FLT_CONST                                       { NEWTOKEN(PSI_T_NUMBER); token->flags = PSI_NUMBER_FLT; goto start; }
-               FLT_CONST / 'f'                         { NEWTOKEN(PSI_T_NUMBER); token->flags = PSI_NUMBER_FLT | PSI_NUMBER_F; cur += 1; goto start; }
-               FLT_CONST / 'l'                         { NEWTOKEN(PSI_T_NUMBER); token->flags = PSI_NUMBER_FLT | PSI_NUMBER_L; cur += 1; goto start; }
+               FLT_CONST       / 'f'                   { NEWTOKEN(PSI_T_NUMBER); token->flags = PSI_NUMBER_FLT | PSI_NUMBER_F; cur += 1; goto start; }
+               FLT_CONST       / 'l'                   { NEWTOKEN(PSI_T_NUMBER); token->flags = PSI_NUMBER_FLT | PSI_NUMBER_L; cur += 1; goto start; }
                FLT_CONST       / 'df'                  { NEWTOKEN(PSI_T_NUMBER); token->flags = PSI_NUMBER_FLT | PSI_NUMBER_DF; cur += 2; goto start; }
                FLT_CONST       / 'dd'                  { NEWTOKEN(PSI_T_NUMBER); token->flags = PSI_NUMBER_FLT | PSI_NUMBER_DD; cur += 2; goto start; }
                FLT_CONST       / 'dl'                  { NEWTOKEN(PSI_T_NUMBER); token->flags = PSI_NUMBER_FLT | PSI_NUMBER_DL; cur += 2; goto start; }
@@ -132,7 +131,7 @@ struct psi_plist *psi_parser_scan(struct psi_parser *P, struct psi_parser_input
                "u8" / "\""             { char_width = 1; }
                "u" / ['"]              { char_width = 2; }
                "U" / ['"]              { char_width = 4; }
-               "L" / ['"]              { char_width = sizeof(wchar_t)/8; }
+               "L" / ['"]              { char_width = sizeof(wchar_t); }
 
                "/*"                    { goto comment; }
                "//"                    { goto comment_sl; }
index 2278e23..8f24f1c 100644 (file)
@@ -1,18 +1,21 @@
 --TEST--
-CPP argument prescan
+CPP builtins
 --SKIPIF--
 <?php 
 extension_loaded("psi") or die("skip - need ext/psi");
 ?>
 --INI--
 psi.directory={PWD}/cpp004
+--ENV--
+LC_TIME=C
 --FILE--
 ===TEST===
 <?php 
 var_dump(CPP_TEST0, CPP_TEST1, CPP_TEST2, CPP_TEST3, CPP_TEST4, CPP_TEST5);
+var_dump(base_file, include_level, timestamp);
 ?>
 ===DONE===
---EXPECT--
+--EXPECTF--
 ===TEST===
 int(0)
 int(1)
@@ -20,4 +23,7 @@ int(2)
 int(3003)
 int(4004)
 int(5005)
+string(%d) "%s/tests/parser/cpp004/builtins.psi"
+int(2)
+string(24) "%s %s %w%d %d:%d:%d %d"
 ===DONE===
diff --git a/tests/parser/cpp004/base_file.h b/tests/parser/cpp004/base_file.h
new file mode 100644 (file)
index 0000000..40abf6e
--- /dev/null
@@ -0,0 +1,2 @@
+const \base_file = __BASE_FILE__;
+#include "include_level.h"
index d6cbf38..24f79d4 100644 (file)
@@ -8,3 +8,6 @@ const \CPP_TEST2 = __COUNTER__;
 const \CPP_TEST3 = c(300);
 const \CPP_TEST4 = c(400);
 const \CPP_TEST5 = c(500);
+
+#include "base_file.h" // includes include_level.h
+#include "timestamp.h"
diff --git a/tests/parser/cpp004/include_level.h b/tests/parser/cpp004/include_level.h
new file mode 100644 (file)
index 0000000..e5ab1e3
--- /dev/null
@@ -0,0 +1 @@
+const \include_level = __INCLUDE_LEVEL__;
diff --git a/tests/parser/cpp004/timestamp.h b/tests/parser/cpp004/timestamp.h
new file mode 100644 (file)
index 0000000..f2f9a39
--- /dev/null
@@ -0,0 +1 @@
+const \timestamp = __TIMESTAMP__;