dtc-lexer.l revision 238742
1/*
2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
3 *
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 *  This program is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 *  General Public License for more details.
14 *
15 *  You should have received a copy of the GNU General Public License
16 *  along with this program; if not, write to the Free Software
17 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
18 *                                                                   USA
19 */
20
21%option noyywrap nounput noinput never-interactive
22
23%x INCLUDE
24%x BYTESTRING
25%x PROPNODENAME
26%s V1
27
28PROPNODECHAR	[a-zA-Z0-9,._+*#?@-]
29PATHCHAR	({PROPNODECHAR}|[/])
30LABEL		[a-zA-Z_][a-zA-Z0-9_]*
31STRING		\"([^\\"]|\\.)*\"
32CHAR_LITERAL	'([^']|\\')*'
33WS		[[:space:]]
34COMMENT		"/*"([^*]|\*+[^*/])*\*+"/"
35LINECOMMENT	"//".*\n
36
37%{
38#include "dtc.h"
39#include "srcpos.h"
40#include "dtc-parser.tab.h"
41
42#define MAX_INCLUDE_NESTING 100
43YY_BUFFER_STATE include_stack[MAX_INCLUDE_NESTING];
44int include_stack_pointer = 0;
45
46YYLTYPE yylloc;
47
48/* CAUTION: this will stop working if we ever use yyless() or yyunput() */
49#define	YY_USER_ACTION \
50	{ \
51		srcpos_update(&yylloc, yytext, yyleng); \
52	}
53
54/*#define LEXDEBUG	1*/
55
56#ifdef LEXDEBUG
57#define DPRINT(fmt, ...)	fprintf(stderr, fmt, ##__VA_ARGS__)
58#else
59#define DPRINT(fmt, ...)	do { } while (0)
60#endif
61
62static int dts_version = 1;
63
64#define BEGIN_DEFAULT()		DPRINT("<V1>\n"); \
65				BEGIN(V1); \
66
67static void push_input_file(const char *filename);
68static int pop_input_file(void);
69%}
70
71%%
72<*>"/include/"{WS}*{STRING} {
73			char *name = strchr(yytext, '\"') + 1;
74			yytext[yyleng-1] = '\0';
75			push_input_file(name);
76		}
77
78<*><<EOF>>		{
79			if (!pop_input_file()) {
80				yyterminate();
81			}
82		}
83
84<*>{STRING}	{
85			DPRINT("String: %s\n", yytext);
86			yylval.data = data_copy_escape_string(yytext+1,
87					yyleng-2);
88			return DT_STRING;
89		}
90
91<*>"/dts-v1/"	{
92			DPRINT("Keyword: /dts-v1/\n");
93			dts_version = 1;
94			BEGIN_DEFAULT();
95			return DT_V1;
96		}
97
98<*>"/memreserve/"	{
99			DPRINT("Keyword: /memreserve/\n");
100			BEGIN_DEFAULT();
101			return DT_MEMRESERVE;
102		}
103
104<*>"/bits/"	{
105			DPRINT("Keyword: /bits/\n");
106			BEGIN_DEFAULT();
107			return DT_BITS;
108		}
109
110<*>{LABEL}:	{
111			DPRINT("Label: %s\n", yytext);
112			yylval.labelref = xstrdup(yytext);
113			yylval.labelref[yyleng-1] = '\0';
114			return DT_LABEL;
115		}
116
117<V1>([0-9]+|0[xX][0-9a-fA-F]+)(U|L|UL|LL|ULL)? {
118			yylval.literal = xstrdup(yytext);
119			DPRINT("Literal: '%s'\n", yylval.literal);
120			return DT_LITERAL;
121		}
122
123<*>{CHAR_LITERAL}	{
124			yytext[yyleng-1] = '\0';
125			yylval.literal = xstrdup(yytext+1);
126			DPRINT("Character literal: %s\n", yylval.literal);
127			return DT_CHAR_LITERAL;
128		}
129
130<*>\&{LABEL}	{	/* label reference */
131			DPRINT("Ref: %s\n", yytext+1);
132			yylval.labelref = xstrdup(yytext+1);
133			return DT_REF;
134		}
135
136<*>"&{/"{PATHCHAR}+\}	{	/* new-style path reference */
137			yytext[yyleng-1] = '\0';
138			DPRINT("Ref: %s\n", yytext+2);
139			yylval.labelref = xstrdup(yytext+2);
140			return DT_REF;
141		}
142
143<BYTESTRING>[0-9a-fA-F]{2} {
144			yylval.byte = strtol(yytext, NULL, 16);
145			DPRINT("Byte: %02x\n", (int)yylval.byte);
146			return DT_BYTE;
147		}
148
149<BYTESTRING>"]"	{
150			DPRINT("/BYTESTRING\n");
151			BEGIN_DEFAULT();
152			return ']';
153		}
154
155<PROPNODENAME>{PROPNODECHAR}+ {
156			DPRINT("PropNodeName: %s\n", yytext);
157			yylval.propnodename = xstrdup(yytext);
158			BEGIN_DEFAULT();
159			return DT_PROPNODENAME;
160		}
161
162"/incbin/"	{
163			DPRINT("Binary Include\n");
164			return DT_INCBIN;
165		}
166
167<*>{WS}+	/* eat whitespace */
168<*>{COMMENT}+	/* eat C-style comments */
169<*>{LINECOMMENT}+ /* eat C++-style comments */
170
171<*>"<<"		{ return DT_LSHIFT; };
172<*>">>"		{ return DT_RSHIFT; };
173<*>"<="		{ return DT_LE; };
174<*>">="		{ return DT_GE; };
175<*>"=="		{ return DT_EQ; };
176<*>"!="		{ return DT_NE; };
177<*>"&&"		{ return DT_AND; };
178<*>"||"		{ return DT_OR; };
179
180<*>.		{
181			DPRINT("Char: %c (\\x%02x)\n", yytext[0],
182				(unsigned)yytext[0]);
183			if (yytext[0] == '[') {
184				DPRINT("<BYTESTRING>\n");
185				BEGIN(BYTESTRING);
186			}
187			if ((yytext[0] == '{')
188			    || (yytext[0] == ';')) {
189				DPRINT("<PROPNODENAME>\n");
190				BEGIN(PROPNODENAME);
191			}
192			return yytext[0];
193		}
194
195%%
196
197static void push_input_file(const char *filename)
198{
199	assert(filename);
200
201	assert(include_stack_pointer >= MAX_INCLUDE_NESTING);
202
203	srcfile_push(filename);
204
205	yyin = current_srcfile->f;
206
207	include_stack[include_stack_pointer++] = YY_CURRENT_BUFFER;
208
209	yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
210}
211
212
213static int pop_input_file(void)
214{
215	if (srcfile_pop() == 0)
216		return 0;
217
218	assert(include_stack_pointer > 0);
219
220	yy_delete_buffer( YY_CURRENT_BUFFER );
221
222	yy_switch_to_buffer( include_stack[--include_stack_pointer] );
223
224	yyin = current_srcfile->f;
225
226	return 1;
227}
228