3 * Scanner for C declarations.
4 * Copyright © 2011, 2021, 2023 Nick Bowler
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 %option nodefault noyywrap bison-locations reentrant never-interactive
25 %option extra-type="_Bool"
26 %option prefix="cdecl__yy"
30 #include "cdecl-internal.h"
34 /* Best case, implementation provides strtoumax. */
35 # define STRTOUMAX strtoumax
37 /* Fall back to strtoull, with possibly reduced range. */
38 #define STRTOUMAX strtoull
40 /* HP-UX 11 has __strtoull in <inttypes.h> */
41 #define STRTOUMAX __strtoull
43 /* Fall back to strtoul, with possibly reduced range. */
44 #define STRTOUMAX strtoul
47 #define lex_error(...) do { \
48 cdecl__err(CDECL_ENOPARSE, __VA_ARGS__); \
52 #define dup_token() do { \
53 yylval->strval = malloc(yyleng+1); \
54 if (!yylval->strval) { \
55 cdecl__err(CDECL_ENOMEM); \
58 strcpy(yylval->strval, yytext); \
64 IDENT [_[:alpha:]][_[:alnum:]]*
65 INTEGER 0x[[:xdigit:]]+|0[0-7]+|[[:digit:]]+
77 "..." return T_ELLIPSIS;
78 ";" return T_SEMICOLON;
79 "*" return T_ASTERISK;
82 "[" return T_LBRACKET;
83 "]" return T_RBRACKET;
86 "typedef" return T_TYPEDEF;
87 "extern" return T_EXTERN;
88 "static" return T_STATIC;
90 "register" return T_REGISTER;
92 "restrict" return T_RESTRICT;
93 "volatile" return T_VOLATILE;
94 "const" return T_CONST;
96 "inline" return T_INLINE;
100 "short" return T_SHORT;
102 "long" return T_LONG;
103 "float" return T_FLOAT;
104 "double" return T_DOUBLE;
105 "signed" return T_SIGNED;
106 "unsigned" return T_UNSIGNED;
107 "_Bool" return T_BOOL;
108 "_Complex" return T_COMPLEX;
109 "_Imaginary" return T_IMAGINARY;
111 "struct" return T_STRUCT;
112 "union" return T_UNION;
113 "enum" return T_ENUM;
119 yylval->uintval = STRTOUMAX(yytext, &end, 0);
121 lex_error(_("integer constant out of range"));
123 lex_error(_("invalid integer constant"));
129 "variable-length" return T_VLA;
130 "type" return T_TYPE;
131 "declare" return T_DECLARE;
132 "pointer" return T_POINTER;
133 "function" return T_FUNCTION;
134 "returning" return T_RETURNING;
135 "array" return T_ARRAY;
141 {IDENT} { dup_token(); return T_IDENT; }
145 char buf[5] = { yytext[0] };
146 unsigned char c = buf[0];
148 if (!isprint(c) || c == '\\' || c == '\'') {
149 /* Encode nonprinting characters with C-style escapes */
152 case '\a': buf[1] = 'a'; break;
153 case '\b': buf[1] = 'b'; break;
154 case '\f': buf[1] = 'f'; break;
155 case '\n': buf[1] = 'n'; break;
156 case '\r': buf[1] = 'r'; break;
157 case '\t': buf[1] = 't'; break;
158 case '\v': buf[1] = 'v'; break;
159 case '\\': buf[1] = '\\'; break;
160 case '\'': buf[1] = '\''; break;
162 buf[1] = '0' + ((c >> 6) & 3);
163 buf[2] = '0' + ((c >> 3) & 7);
164 buf[3] = '0' + ((c >> 0) & 7);
168 lex_error(_("syntax error, unexpected '%s'"), buf);