]> git.draconx.ca Git - cdecl99.git/blob - src/scan.l
54cea88717622f138a74f11841b73e9170f9f328
[cdecl99.git] / src / scan.l
1 %top{
2 /*
3  *  Scanner for C declarations.
4  *  Copyright © 2011 Nick Bowler
5  *
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.
10  *
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.
15  *
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/>.
18  */
19
20 #include <config.h>
21 #include "parse.h"
22 }
23
24 %option nodefault noyywrap bison-locations reentrant never-interactive
25 %option extra-type="_Bool"
26 %option prefix="cdecl__yy"
27
28 %{
29 #define lex_error(msg) do { \
30         cdecl__yyerror(yylloc, NULL, NULL, (msg)); \
31         return T_LEX_ERROR; \
32 } while(0)
33
34 #define dup_token() do { \
35         yylval->strval = malloc(yyleng+1); \
36         if (!yylval->strval) \
37                 lex_error("failed to allocate memory"); \
38         strcpy(yylval->strval, yytext); \
39 } while(0)
40 %}
41
42 %s ENGLISH
43
44 IDENT [_[:alpha:]][_[:alnum:]]*
45 INTEGER 0x[[:xdigit:]]+|0[0-7]+|[[:digit:]]+
46
47 %%
48
49 %{
50         if (yyextra) {
51                 yyextra = 0;
52                 BEGIN(ENGLISH);
53                 return T_ENGLISH;
54         }
55 %}
56
57 "..." return T_ELLIPSIS;
58 ";"   return T_SEMICOLON;
59 "*"   return T_ASTERISK;
60 "("   return T_LPAREN;
61 ")"   return T_RPAREN;
62 "["   return T_LBRACKET;
63 "]"   return T_RBRACKET;
64 ","   return T_COMMA;
65
66 "typedef"    return T_TYPEDEF;
67 "extern"     return T_EXTERN;
68 "static"     return T_STATIC;
69 "auto"       return T_AUTO;
70 "register"   return T_REGISTER;
71
72 "restrict"   return T_RESTRICT;
73 "volatile"   return T_VOLATILE;
74 "const"      return T_CONST;
75
76 "inline"     return T_INLINE;
77
78 "void"       return T_VOID;
79 "char"       return T_CHAR;
80 "short"      return T_SHORT;
81 "int"        return T_INT;
82 "long"       return T_LONG;
83 "float"      return T_FLOAT;
84 "double"     return T_DOUBLE;
85 "signed"     return T_SIGNED;
86 "unsigned"   return T_UNSIGNED;
87 "_Bool"      return T_BOOL;
88 "_Complex"   return T_COMPLEX;
89 "_Imaginary" return T_IMAGINARY;
90
91 "struct"     return T_STRUCT;
92 "union"      return T_UNION;
93 "enum"       return T_ENUM;
94
95 {INTEGER} {
96         char *end;
97
98         errno = 0;
99         yylval->uintval = strtoumax(yytext, &end, 0);
100         if (errno == ERANGE)
101                 lex_error("integer constant out of range");
102         if (*end)
103                 lex_error("invalid integer constant");
104
105         return T_UINT;
106 }
107
108 <ENGLISH>{
109         "variable-length" return T_VLA;
110         "type"            return T_TYPE;
111         "declare"         return T_DECLARE;
112         "pointer"         return T_POINTER;
113         "function"        return T_FUNCTION;
114         "returning"       return T_RETURNING;
115         "array"           return T_ARRAY;
116         "to"              return T_TO;
117         "of"              return T_OF;
118         "as"              return T_AS;
119 }
120
121 {IDENT} { dup_token(); return T_IDENT; }
122
123 [[:space:]]+
124 . {
125         char buf[] = "syntax error, unexpected #";
126         *strchr(buf, '#') = *yytext;
127         lex_error(buf);
128 }