152419Sjulian/* -*- indented-text -*- */ 252419Sjulian/* Process source files and output type information. 352419Sjulian Copyright (C) 2002-2015 Free Software Foundation, Inc. 452419Sjulian 552419SjulianThis file is part of GCC. 652419Sjulian 752419SjulianGCC is free software; you can redistribute it and/or modify it under 852419Sjulianthe terms of the GNU General Public License as published by the Free 952419SjulianSoftware Foundation; either version 3, or (at your option) any later 1052419Sjulianversion. 1152419Sjulian 1252419SjulianGCC is distributed in the hope that it will be useful, but WITHOUT ANY 1352419SjulianWARRANTY; without even the implied warranty of MERCHANTABILITY or 1452419SjulianFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1552419Sjulianfor more details. 1652419Sjulian 1752419SjulianYou should have received a copy of the GNU General Public License 1852419Sjulianalong with GCC; see the file COPYING3. If not see 1952419Sjulian<http://www.gnu.org/licenses/>. */ 2052419Sjulian 2152419Sjulian%option noinput 2252419Sjulian 2352419Sjulian%{ 2452419Sjulian#ifdef HOST_GENERATOR_FILE 2552419Sjulian#include "config.h" 2652419Sjulian#define GENERATOR_FILE 1 2752419Sjulian#else 2852419Sjulian#include "bconfig.h" 2952419Sjulian#endif 3052419Sjulian#include "system.h" 3152419Sjulian 3252419Sjulian#define malloc xmalloc 3352419Sjulian#define realloc xrealloc 3452419Sjulian 3552419Sjulian#include "gengtype.h" 3652419Sjulian 3752419Sjulian#define YY_DECL int yylex (const char **yylval) 3853913Sarchie#define yyterminate() return EOF_TOKEN 3952419Sjulian 4052419Sjulianstruct fileloc lexer_line; 41158882Sglebiusint lexer_toplevel_done; 42158882Sglebius 43158882Sglebiusstatic void 44158882Sglebiusupdate_lineno (const char *l, size_t len) 45158882Sglebius{ 46158882Sglebius while (len-- > 0) 47158882Sglebius if (*l++ == '\n') 48158882Sglebius lexer_line.line++; 49158882Sglebius} 50158882Sglebius 51158882Sglebius%} 52158882Sglebius 53158882SglebiusCID [[:alpha:]_][[:alnum:]_]* 54161044SglebiusWS [[:space:]]+ 55161044SglebiusHWS [ \t\r\v\f]* 56161044SglebiusIWORD 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 57161044SglebiusITYPE {IWORD}({WS}{IWORD})* 58161044Sglebius /* Include '::' in identifiers to capture C++ scope qualifiers. */ 59158882SglebiusID {CID}({HWS}::{HWS}{CID})* 60158882SglebiusEOID [^[:alnum:]_] 61158882SglebiusCXX_KEYWORD inline|public:|private:|protected:|template|operator|friend|static 6252419Sjulian 6352419Sjulian%x in_struct in_struct_comment in_comment 6453913Sarchie%option warn noyywrap nounput nodefault perf-report 6553913Sarchie%option 8bit never-interactive 6653913Sarchie%% 6753913Sarchie /* Do this on entry to yylex(): */ 6852419Sjulian *yylval = 0; 6952419Sjulian if (lexer_toplevel_done) 7052419Sjulian { 71161071Sglebius BEGIN(INITIAL); 72180076Smtm lexer_toplevel_done = 0; 7352419Sjulian } 7452419Sjulian 7552419Sjulian /* Things we look for in skipping mode: */ 7653913Sarchie<INITIAL>{ 7752419Sjulian^{HWS}typedef/{EOID} { 7852419Sjulian BEGIN(in_struct); 7952419Sjulian return TYPEDEF; 8052419Sjulian} 81161044Sglebius^{HWS}struct/{EOID} { 82161044Sglebius BEGIN(in_struct); 83161044Sglebius return STRUCT; 84161044Sglebius} 85161044Sglebius^{HWS}union/{EOID} { 8652419Sjulian BEGIN(in_struct); 8752419Sjulian return UNION; 8852419Sjulian} 8962471Sphk^{HWS}class/{EOID} { 9052419Sjulian BEGIN(in_struct); 9152419Sjulian return STRUCT; 92124271Sgreen} 9352419Sjulian^{HWS}extern/{EOID} { 9452419Sjulian BEGIN(in_struct); 9552419Sjulian return EXTERN; 9653913Sarchie} 9752419Sjulian^{HWS}static/{EOID} { 9852419Sjulian BEGIN(in_struct); 9952419Sjulian return STATIC; 10052419Sjulian} 10152419Sjulian} 10252419Sjulian 10352419Sjulian /* Parsing inside a struct, union or class declaration. */ 10489674Sarchie<in_struct>{ 10552419Sjulian"/*" { BEGIN(in_struct_comment); } 10652419Sjulian"//".*\n { lexer_line.line++; } 10752419Sjulian 10852419Sjulian{WS} { update_lineno (yytext, yyleng); } 10952419Sjulian\\\n { lexer_line.line++; } 11052419Sjulian 11152419Sjulian"const"/{EOID} /* don't care */ 11252419Sjulian{CXX_KEYWORD}/{EOID} | 11352419Sjulian"~" | 11453913Sarchie"^" | 11553913Sarchie"&" { 11652419Sjulian *yylval = XDUPVAR (const char, yytext, yyleng, yyleng + 1); 11752419Sjulian return IGNORABLE_CXX_KEYWORD; 11852419Sjulian} 11952419Sjulian"GTY"/{EOID} { return GTY_TOKEN; } 12052419Sjulian"union"/{EOID} { return UNION; } 12153913Sarchie"struct"/{EOID} { return STRUCT; } 12253913Sarchie"class"/{EOID} { return STRUCT; } 12352419Sjulian"typedef"/{EOID} { return TYPEDEF; } 12452419Sjulian"enum"/{EOID} { return ENUM; } 12552419Sjulian"ptr_alias"/{EOID} { return PTR_ALIAS; } 12652419Sjulian"nested_ptr"/{EOID} { return NESTED_PTR; } 12752419Sjulian"user"/{EOID} { return USER_GTY; } 12853913Sarchie[0-9]+ { return NUM; } 12953913Sarchie 13052419Sjulian{IWORD}({WS}{IWORD})*/{EOID} | 13152419Sjulian"ENUM_BITFIELD"{WS}?"("{WS}?{ID}{WS}?")" { 13252419Sjulian size_t len; 13352419Sjulian 13452419Sjulian for (len = yyleng; ISSPACE (yytext[len-1]); len--) 13552419Sjulian ; 13652419Sjulian 13752419Sjulian *yylval = XDUPVAR (const char, yytext, len, len+1); 13852419Sjulian update_lineno (yytext, yyleng); 13952419Sjulian return SCALAR; 14052419Sjulian} 141122556Sharti 14252419Sjulian{ID}/{EOID} { 14352419Sjulian *yylval = XDUPVAR (const char, yytext, yyleng, yyleng+1); 144141303Smaxim return ID; 14552419Sjulian} 14652419Sjulian 14752419Sjulian\"([^"\\]|\\.)*\" { 14852419Sjulian *yylval = XDUPVAR (const char, yytext+1, yyleng-2, yyleng-1); 14952419Sjulian return STRING; 150166529Skevlo} 15152419Sjulian /* This "terminal" avoids having to parse integer constant expressions. */ 15252419Sjulian"["[^\[\]]*"]" { 15352419Sjulian *yylval = XDUPVAR (const char, yytext+1, yyleng-2, yyleng-1); 15452419Sjulian return ARRAY; 15552419Sjulian} 15652419Sjulian"'"("\\".|[^\\])"'" { 15752419Sjulian *yylval = XDUPVAR (const char, yytext+1, yyleng-2, yyleng); 15852419Sjulian return CHAR; 15952419Sjulian} 16052419Sjulian 16152419Sjulian"..." { return ELLIPSIS; } 16252419Sjulian[(){},*:<>;=%|+\!\?\.-] { return yytext[0]; } 16352419Sjulian 16452419Sjulian /* ignore pp-directives */ 16552419Sjulian^{HWS}"#"{HWS}[a-z_]+[^\n]*\n {lexer_line.line++;} 16652419Sjulian 16752419Sjulian. { 16852419Sjulian error_at_line (&lexer_line, "unexpected character `%s'", yytext); 16952419Sjulian} 17052419Sjulian} 17152419Sjulian 17252419Sjulian"/*" { BEGIN(in_comment); } 17352419Sjulian"//".*\n { lexer_line.line++; } 17456709Sarchie\n { lexer_line.line++; } 17552419Sjulian{ID} | 176141303Smaxim"'"("\\".|[^\\])"'" | 17752419Sjulian[^"/\n] /* do nothing */ 17852419Sjulian\"([^"\\]|\\.|\\\n)*\" { update_lineno (yytext, yyleng); } 17952419Sjulian"/"/[^*] /* do nothing */ 18052419Sjulian 18152419Sjulian<in_comment,in_struct_comment>{ 18252419Sjulian\n { lexer_line.line++; } 18352419Sjulian[^*\n]{16} | 18452419Sjulian[^*\n] /* do nothing */ 18552419Sjulian"*"/[^/] /* do nothing */ 18652419Sjulian} 18752419Sjulian 18852419Sjulian<in_comment>"*/" { BEGIN(INITIAL); } 18952419Sjulian<in_struct_comment>"*/" { BEGIN(in_struct); } 19052419Sjulian 19152419Sjulian["/] | 19252419Sjulian<in_struct_comment,in_comment>"*" { 19352419Sjulian error_at_line (&lexer_line, 19452419Sjulian "unterminated comment or string; unexpected EOF"); 19552419Sjulian} 19652419Sjulian 19752419Sjulian^{HWS}"#"{HWS}"define"{WS}"GTY(" /* do nothing */ 19852419Sjulian 19952419Sjulian%% 20052419Sjulian 20152419Sjulianvoid 202160002Sglebiusyybegin (const char *fname) 20352419Sjulian{ 20452419Sjulian yyin = fopen (fname, "r"); 20552419Sjulian if (yyin == NULL) 20652419Sjulian { 20752419Sjulian perror (fname); 20852419Sjulian exit (1); 20952419Sjulian } 21052419Sjulian lexer_line.file = input_file_by_name (fname); 21152419Sjulian lexer_line.line = 1; 21252419Sjulian} 21352419Sjulian 21452419Sjulianvoid 21552419Sjulianyyend (void) 21652419Sjulian{ 21752419Sjulian fclose (yyin); 21852419Sjulian} 219160002Sglebius