1 /* -*- indented-text -*- */ 2 /* Process source files and output type information. 3 Copyright (C) 2002-2018 Free Software Foundation, Inc. 4 5 This file is part of GCC. 6 7 GCC is free software; you can redistribute it and/or modify it under 8 the terms of the GNU General Public License as published by the Free 9 Software Foundation; either version 3, or (at your option) any later 10 version. 11 12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13 WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GCC; see the file COPYING3. If not see 19 <http://www.gnu.org/licenses/>. */ 20 21 %option noinput 22 23 %{ 24 #ifdef HOST_GENERATOR_FILE 25 #include "config.h" 26 #define GENERATOR_FILE 1 27 #else 28 #include "bconfig.h" 29 #endif 30 #include "system.h" 31 32 #define malloc xmalloc 33 #define realloc xrealloc 34 35 #include "gengtype.h" 36 37 #define YY_DECL int yylex (const char **yylval) 38 #define yyterminate() return EOF_TOKEN 39 40 struct fileloc lexer_line; 41 int lexer_toplevel_done; 42 43 static void 44 update_lineno (const char *l, size_t len) 45 { 46 while (len-- > 0) 47 if (*l++ == '\n') 48 lexer_line.line++; 49 } 50 51 %} 52 53 CID [[:alpha:]_][[:alnum:]_]* 54 WS [[:space:]]+ 55 HWS [ \t\r\v\f]* 56 IWORD short|long|(un)?signed|char|int|HOST_WIDE_INT|uint64_t|int64_t|bool|size_t|BOOL_BITFIELD|CPPCHAR_SIGNED_T|ino_t|dev_t|HARD_REG_SET 57 ITYPE {IWORD}({WS}{IWORD})* 58 /* Include '::' in identifiers to capture C++ scope qualifiers. */ 59 ID {CID}({HWS}::{HWS}{CID})* 60 EOID [^[:alnum:]_] 61 CXX_KEYWORD inline|public:|private:|protected:|template|operator|friend|static 62 63 %x in_struct in_struct_comment in_comment 64 %option warn noyywrap nounput nodefault perf-report 65 %option 8bit never-interactive 66 %% 67 /* Do this on entry to yylex(): */ 68 *yylval = 0; 69 if (lexer_toplevel_done) 70 { 71 BEGIN(INITIAL); 72 lexer_toplevel_done = 0; 73 } 74 75 /* Things we look for in skipping mode: */ 76 <INITIAL>{ 77 ^{HWS}typedef/{EOID} { 78 BEGIN(in_struct); 79 return TYPEDEF; 80 } 81 ^{HWS}struct/{EOID} { 82 BEGIN(in_struct); 83 return STRUCT; 84 } 85 ^{HWS}union/{EOID} { 86 BEGIN(in_struct); 87 return UNION; 88 } 89 ^{HWS}class/{EOID} { 90 BEGIN(in_struct); 91 return STRUCT; 92 } 93 ^{HWS}extern/{EOID} { 94 BEGIN(in_struct); 95 return EXTERN; 96 } 97 ^{HWS}static/{EOID} { 98 BEGIN(in_struct); 99 return STATIC; 100 } 101 } 102 103 /* Parsing inside a struct, union or class declaration. */ 104 <in_struct>{ 105 "/*" { BEGIN(in_struct_comment); } 106 "//".*\n { lexer_line.line++; } 107 108 {WS} { update_lineno (yytext, yyleng); } 109 \\\n { lexer_line.line++; } 110 111 "const"/{EOID} /* don't care */ 112 {CXX_KEYWORD}/{EOID} | 113 "~" | 114 "^" | 115 "&" { 116 *yylval = XDUPVAR (const char, yytext, yyleng, yyleng + 1); 117 return IGNORABLE_CXX_KEYWORD; 118 } 119 "GTY"/{EOID} { return GTY_TOKEN; } 120 "union"/{EOID} { return UNION; } 121 "struct"/{EOID} { return STRUCT; } 122 "class"/{EOID} { return STRUCT; } 123 "typedef"/{EOID} { return TYPEDEF; } 124 "enum"/{EOID} { return ENUM; } 125 "ptr_alias"/{EOID} { return PTR_ALIAS; } 126 "nested_ptr"/{EOID} { return NESTED_PTR; } 127 "user"/{EOID} { return USER_GTY; } 128 [0-9]+ { return NUM; } 129 130 {IWORD}({WS}{IWORD})*/{EOID} | 131 "ENUM_BITFIELD"{WS}?"("{WS}?{ID}{WS}?")" { 132 size_t len; 133 134 for (len = yyleng; ISSPACE (yytext[len-1]); len--) 135 ; 136 137 *yylval = XDUPVAR (const char, yytext, len, len+1); 138 update_lineno (yytext, yyleng); 139 return SCALAR; 140 } 141 142 {ID}/{EOID} { 143 *yylval = XDUPVAR (const char, yytext, yyleng, yyleng+1); 144 return ID; 145 } 146 147 \"([^"\\]|\\.)*\" { 148 *yylval = XDUPVAR (const char, yytext+1, yyleng-2, yyleng-1); 149 return STRING; 150 } 151 /* This "terminal" avoids having to parse integer constant expressions. */ 152 "["[^\[\]]*"]" { 153 *yylval = XDUPVAR (const char, yytext+1, yyleng-2, yyleng-1); 154 return ARRAY; 155 } 156 "'"("\\".|[^\\])"'" { 157 *yylval = XDUPVAR (const char, yytext+1, yyleng-2, yyleng); 158 return CHAR; 159 } 160 161 "..." { return ELLIPSIS; } 162 [(){},*:<>;=%/|+\!\?\.-] { return yytext[0]; } 163 164 /* ignore pp-directives */ 165 ^{HWS}"#"{HWS}[a-z_]+[^\n]*\n {lexer_line.line++;} 166 167 . { 168 error_at_line (&lexer_line, "unexpected character `%s'", yytext); 169 } 170 } 171 172 "/*" { BEGIN(in_comment); } 173 "//".*\n { lexer_line.line++; } 174 \n { lexer_line.line++; } 175 {ID} | 176 "'"("\\".|[^\\])"'" | 177 [^"/\n] /* do nothing */ 178 \"([^"\\]|\\.|\\\n)*\" { update_lineno (yytext, yyleng); } 179 "/"/[^*] /* do nothing */ 180 181 <in_comment,in_struct_comment>{ 182 \n { lexer_line.line++; } 183 [^*\n]{16} | 184 [^*\n] /* do nothing */ 185 "*"/[^/] /* do nothing */ 186 } 187 188 <in_comment>"*/" { BEGIN(INITIAL); } 189 <in_struct_comment>"*/" { BEGIN(in_struct); } 190 191 ["/] | 192 <in_struct_comment,in_comment>"*" { 193 error_at_line (&lexer_line, 194 "unterminated comment or string; unexpected EOF"); 195 } 196 197 ^{HWS}"#"{HWS}"define"{WS}"GTY(" /* do nothing */ 198 199 %% 200 201 void 202 yybegin (const char *fname) 203 { 204 yyin = fopen (fname, "r"); 205 if (yyin == NULL) 206 { 207 perror (fname); 208 exit (1); 209 } 210 lexer_line.file = input_file_by_name (fname); 211 lexer_line.line = 1; 212 } 213 214 void 215 yyend (void) 216 { 217 fclose (yyin); 218 } 219