1/* -*- indented-text -*- */
2/* Process source files and output type information.
3   Copyright (C) 2002-2015 Free Software Foundation, Inc.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along 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
40struct fileloc lexer_line;
41int lexer_toplevel_done;
42
43static void
44update_lineno (const char *l, size_t len)
45{
46  while (len-- > 0)
47    if (*l++ == '\n')
48      lexer_line.line++;
49}
50
51%}
52
53CID	[[:alpha:]_][[:alnum:]_]*
54WS	[[:space:]]+
55HWS	[ \t\r\v\f]*
56IWORD	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
57ITYPE	{IWORD}({WS}{IWORD})*
58    /* Include '::' in identifiers to capture C++ scope qualifiers.  */
59ID	{CID}({HWS}::{HWS}{CID})*
60EOID	[^[:alnum:]_]
61CXX_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
201void
202yybegin (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
214void
215yyend (void)
216{
217  fclose (yyin);
218}
219