%top{ /* * Scanner for C declarations. * Copyright © 2011 Nick Bowler * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include "parse.h" } %option nodefault noyywrap bison-locations reentrant never-interactive %option extra-type="_Bool" %option prefix="cdecl__yy" %{ #define lex_error(msg) do { \ cdecl__yyerror(yylloc, NULL, NULL, (msg)); \ return T_LEX_ERROR; \ } while(0) #define dup_token() do { \ yylval->strval = malloc(yyleng+1); \ if (!yylval->strval) \ lex_error("failed to allocate memory"); \ strcpy(yylval->strval, yytext); \ } while(0) %} %s ENGLISH IDENT [_[:alpha:]][_[:alnum:]]* INTEGER 0x[[:xdigit:]]+|0[0-7]+|[[:digit:]]+ %% %{ if (yyextra) { yyextra = 0; BEGIN(ENGLISH); return T_ENGLISH; } %} "..." return T_ELLIPSIS; ";" return T_SEMICOLON; "*" return T_ASTERISK; "(" return T_LPAREN; ")" return T_RPAREN; "[" return T_LBRACKET; "]" return T_RBRACKET; "," return T_COMMA; "typedef" return T_TYPEDEF; "extern" return T_EXTERN; "static" return T_STATIC; "auto" return T_AUTO; "register" return T_REGISTER; "restrict" return T_RESTRICT; "volatile" return T_VOLATILE; "const" return T_CONST; "inline" return T_INLINE; "void" return T_VOID; "char" return T_CHAR; "short" return T_SHORT; "int" return T_INT; "long" return T_LONG; "float" return T_FLOAT; "double" return T_DOUBLE; "signed" return T_SIGNED; "unsigned" return T_UNSIGNED; "_Bool" return T_BOOL; "_Complex" return T_COMPLEX; "_Imaginary" return T_IMAGINARY; "struct" return T_STRUCT; "union" return T_UNION; "enum" return T_ENUM; {INTEGER} { char *end; errno = 0; yylval->uintval = strtoumax(yytext, &end, 0); if (errno == ERANGE) lex_error("integer constant out of range"); if (*end) lex_error("invalid integer constant"); return T_UINT; } { "variable-length" return T_VLA; "type" return T_TYPE; "declare" return T_DECLARE; "pointer" return T_POINTER; "function" return T_FUNCTION; "returning" return T_RETURNING; "array" return T_ARRAY; "to" return T_TO; "of" return T_OF; "as" return T_AS; } {IDENT} { dup_token(); return T_IDENT; } [[:space:]]+ . { char buf[] = "syntax error, unexpected #"; *strchr(buf, '#') = *yytext; lex_error(buf); }