X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/362559e5c1b4d138305f9edf2c2b7ee1a24a08f6..4c0777b31ef7ddba6eb0fa4ca62cf5b9423fe1c9:/src/scan.l diff --git a/src/scan.l b/src/scan.l index 5c1a960..54cea88 100644 --- a/src/scan.l +++ b/src/scan.l @@ -17,10 +17,112 @@ * along with this program. If not, see . */ - #include "parse.h" +#include +#include "parse.h" } -%option noyywrap bison-locations +%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); +}