%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);
}