3 * Scanner for C declarations.
4 * Copyright © 2011 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"
33 #define lex_error(...) do { \
34 cdecl__err(CDECL_ENOPARSE, __VA_ARGS__); \
38 #define dup_token() do { \
39 yylval->strval = malloc(yyleng+1); \
40 if (!yylval->strval) { \
41 cdecl__err(CDECL_ENOMEM); \
44 strcpy(yylval->strval, yytext); \
50 IDENT [_[:alpha:]][_[:alnum:]]*
51 INTEGER 0x[[:xdigit:]]+|0[0-7]+|[[:digit:]]+
63 "..." return T_ELLIPSIS;
64 ";" return T_SEMICOLON;
65 "*" return T_ASTERISK;
68 "[" return T_LBRACKET;
69 "]" return T_RBRACKET;
72 "typedef" return T_TYPEDEF;
73 "extern" return T_EXTERN;
74 "static" return T_STATIC;
76 "register" return T_REGISTER;
78 "restrict" return T_RESTRICT;
79 "volatile" return T_VOLATILE;
80 "const" return T_CONST;
82 "inline" return T_INLINE;
86 "short" return T_SHORT;
89 "float" return T_FLOAT;
90 "double" return T_DOUBLE;
91 "signed" return T_SIGNED;
92 "unsigned" return T_UNSIGNED;
93 "_Bool" return T_BOOL;
94 "_Complex" return T_COMPLEX;
95 "_Imaginary" return T_IMAGINARY;
97 "struct" return T_STRUCT;
98 "union" return T_UNION;
105 yylval->uintval = strtoumax(yytext, &end, 0);
107 lex_error(_("integer constant out of range"));
109 lex_error(_("invalid integer constant"));
115 "variable-length" return T_VLA;
116 "type" return T_TYPE;
117 "declare" return T_DECLARE;
118 "pointer" return T_POINTER;
119 "function" return T_FUNCTION;
120 "returning" return T_RETURNING;
121 "array" return T_ARRAY;
127 {IDENT} { dup_token(); return T_IDENT; }
131 char buf[5] = { yytext[0] };
132 unsigned char c = buf[0];
134 if (!isprint(c) || c == '\\' || c == '\'') {
135 /* Encode nonprinting characters with C-style escapes */
138 case '\a': buf[1] = 'a'; break;
139 case '\b': buf[1] = 'b'; break;
140 case '\f': buf[1] = 'f'; break;
141 case '\n': buf[1] = 'n'; break;
142 case '\r': buf[1] = 'r'; break;
143 case '\t': buf[1] = 't'; break;
144 case '\v': buf[1] = 'v'; break;
145 case '\\': buf[1] = '\\'; break;
146 case '\'': buf[1] = '\''; break;
148 buf[1] = '0' + ((c >> 6) & 3);
149 buf[2] = '0' + ((c >> 3) & 7);
150 buf[3] = '0' + ((c >> 0) & 7);
154 lex_error(_("syntax error, unexpected '%s'"), buf);