dtc-lexer.l revision 204489
1204431Sraj/*
2204431Sraj * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
3204431Sraj *
4204431Sraj *
5204431Sraj * This program is free software; you can redistribute it and/or
6204431Sraj * modify it under the terms of the GNU General Public License as
7204431Sraj * published by the Free Software Foundation; either version 2 of the
8204431Sraj * License, or (at your option) any later version.
9204431Sraj *
10204431Sraj *  This program is distributed in the hope that it will be useful,
11204431Sraj *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12204431Sraj *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13204431Sraj *  General Public License for more details.
14204431Sraj *
15204431Sraj *  You should have received a copy of the GNU General Public License
16204431Sraj *  along with this program; if not, write to the Free Software
17204431Sraj *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
18204431Sraj *                                                                   USA
19204431Sraj */
20204431Sraj
21204433Sraj%option noyywrap nounput noinput yylineno
22204431Sraj
23204431Sraj%x INCLUDE
24204431Sraj%x BYTESTRING
25204431Sraj%x PROPNODENAME
26204431Sraj%s V1
27204431Sraj
28204431SrajPROPNODECHAR	[a-zA-Z0-9,._+*#?@-]
29204431SrajPATHCHAR	({PROPNODECHAR}|[/])
30204431SrajLABEL		[a-zA-Z_][a-zA-Z0-9_]*
31204431SrajSTRING		\"([^\\"]|\\.)*\"
32204431SrajWS		[[:space:]]
33204431SrajCOMMENT		"/*"([^*]|\*+[^*/])*\*+"/"
34204431SrajLINECOMMENT	"//".*\n
35204431Sraj
36204431Sraj%{
37204431Sraj#include "dtc.h"
38204431Sraj#include "srcpos.h"
39204431Sraj#include "dtc-parser.tab.h"
40204431Sraj
41204489SrajYYLTYPE yylloc;
42204489Sraj
43204433Sraj#define	YY_USER_ACTION \
44204433Sraj	{ \
45204433Sraj		yylloc.file = srcpos_file; \
46204433Sraj		yylloc.first_line = yylineno; \
47204433Sraj	}
48204431Sraj
49204431Sraj/*#define LEXDEBUG	1*/
50204431Sraj
51204431Sraj#ifdef LEXDEBUG
52204431Sraj#define DPRINT(fmt, ...)	fprintf(stderr, fmt, ##__VA_ARGS__)
53204431Sraj#else
54204431Sraj#define DPRINT(fmt, ...)	do { } while (0)
55204431Sraj#endif
56204431Sraj
57204433Srajstatic int dts_version = 1;
58204431Sraj
59204433Sraj#define BEGIN_DEFAULT()		DPRINT("<V1>\n"); \
60204431Sraj				BEGIN(V1); \
61204431Sraj
62204431Srajstatic void push_input_file(const char *filename);
63204431Srajstatic int pop_input_file(void);
64204431Sraj%}
65204431Sraj
66204431Sraj%%
67204431Sraj<*>"/include/"{WS}*{STRING} {
68204431Sraj			char *name = strchr(yytext, '\"') + 1;
69204431Sraj			yytext[yyleng-1] = '\0';
70204431Sraj			push_input_file(name);
71204431Sraj		}
72204431Sraj
73204431Sraj<*><<EOF>>		{
74204431Sraj			if (!pop_input_file()) {
75204431Sraj				yyterminate();
76204431Sraj			}
77204431Sraj		}
78204431Sraj
79204431Sraj<*>{STRING}	{
80204431Sraj			DPRINT("String: %s\n", yytext);
81204431Sraj			yylval.data = data_copy_escape_string(yytext+1,
82204431Sraj					yyleng-2);
83204431Sraj			return DT_STRING;
84204431Sraj		}
85204431Sraj
86204431Sraj<*>"/dts-v1/"	{
87204431Sraj			DPRINT("Keyword: /dts-v1/\n");
88204431Sraj			dts_version = 1;
89204431Sraj			BEGIN_DEFAULT();
90204431Sraj			return DT_V1;
91204431Sraj		}
92204431Sraj
93204431Sraj<*>"/memreserve/"	{
94204431Sraj			DPRINT("Keyword: /memreserve/\n");
95204431Sraj			BEGIN_DEFAULT();
96204431Sraj			return DT_MEMRESERVE;
97204431Sraj		}
98204431Sraj
99204431Sraj<*>{LABEL}:	{
100204431Sraj			DPRINT("Label: %s\n", yytext);
101204433Sraj			yylval.labelref = xstrdup(yytext);
102204431Sraj			yylval.labelref[yyleng-1] = '\0';
103204431Sraj			return DT_LABEL;
104204431Sraj		}
105204431Sraj
106204431Sraj<V1>[0-9]+|0[xX][0-9a-fA-F]+      {
107204433Sraj			yylval.literal = xstrdup(yytext);
108204431Sraj			DPRINT("Literal: '%s'\n", yylval.literal);
109204431Sraj			return DT_LITERAL;
110204431Sraj		}
111204431Sraj
112204431Sraj\&{LABEL}	{	/* label reference */
113204431Sraj			DPRINT("Ref: %s\n", yytext+1);
114204433Sraj			yylval.labelref = xstrdup(yytext+1);
115204431Sraj			return DT_REF;
116204431Sraj		}
117204431Sraj
118204431Sraj"&{/"{PATHCHAR}+\}	{	/* new-style path reference */
119204431Sraj			yytext[yyleng-1] = '\0';
120204431Sraj			DPRINT("Ref: %s\n", yytext+2);
121204433Sraj			yylval.labelref = xstrdup(yytext+2);
122204431Sraj			return DT_REF;
123204431Sraj		}
124204431Sraj
125204431Sraj<BYTESTRING>[0-9a-fA-F]{2} {
126204431Sraj			yylval.byte = strtol(yytext, NULL, 16);
127204431Sraj			DPRINT("Byte: %02x\n", (int)yylval.byte);
128204431Sraj			return DT_BYTE;
129204431Sraj		}
130204431Sraj
131204431Sraj<BYTESTRING>"]"	{
132204431Sraj			DPRINT("/BYTESTRING\n");
133204431Sraj			BEGIN_DEFAULT();
134204431Sraj			return ']';
135204431Sraj		}
136204431Sraj
137204431Sraj<PROPNODENAME>{PROPNODECHAR}+ {
138204431Sraj			DPRINT("PropNodeName: %s\n", yytext);
139204433Sraj			yylval.propnodename = xstrdup(yytext);
140204431Sraj			BEGIN_DEFAULT();
141204431Sraj			return DT_PROPNODENAME;
142204431Sraj		}
143204431Sraj
144204431Sraj"/incbin/"	{
145204431Sraj			DPRINT("Binary Include\n");
146204431Sraj			return DT_INCBIN;
147204431Sraj		}
148204431Sraj
149204431Sraj<*>{WS}+	/* eat whitespace */
150204431Sraj<*>{COMMENT}+	/* eat C-style comments */
151204431Sraj<*>{LINECOMMENT}+ /* eat C++-style comments */
152204431Sraj
153204431Sraj<*>.		{
154204431Sraj			DPRINT("Char: %c (\\x%02x)\n", yytext[0],
155204431Sraj				(unsigned)yytext[0]);
156204431Sraj			if (yytext[0] == '[') {
157204431Sraj				DPRINT("<BYTESTRING>\n");
158204431Sraj				BEGIN(BYTESTRING);
159204431Sraj			}
160204431Sraj			if ((yytext[0] == '{')
161204431Sraj			    || (yytext[0] == ';')) {
162204431Sraj				DPRINT("<PROPNODENAME>\n");
163204431Sraj				BEGIN(PROPNODENAME);
164204431Sraj			}
165204431Sraj			return yytext[0];
166204431Sraj		}
167204431Sraj
168204431Sraj%%
169204431Sraj
170204431Sraj
171204431Sraj/*
172204431Sraj * Stack of nested include file contexts.
173204431Sraj */
174204431Sraj
175204431Srajstruct incl_file {
176204431Sraj	struct dtc_file *file;
177204431Sraj	YY_BUFFER_STATE yy_prev_buf;
178204431Sraj	int yy_prev_lineno;
179204431Sraj	struct incl_file *prev;
180204431Sraj};
181204431Sraj
182204431Srajstatic struct incl_file *incl_file_stack;
183204431Sraj
184204431Sraj
185204431Sraj/*
186204431Sraj * Detect infinite include recursion.
187204431Sraj */
188204431Sraj#define MAX_INCLUDE_DEPTH	(100)
189204431Sraj
190204431Srajstatic int incl_depth = 0;
191204431Sraj
192204431Sraj
193204431Srajstatic void push_input_file(const char *filename)
194204431Sraj{
195204431Sraj	struct incl_file *incl_file;
196204431Sraj	struct dtc_file *newfile;
197204431Sraj	struct search_path search, *searchptr = NULL;
198204431Sraj
199204431Sraj	assert(filename);
200204431Sraj
201204431Sraj	if (incl_depth++ >= MAX_INCLUDE_DEPTH)
202204431Sraj		die("Includes nested too deeply");
203204431Sraj
204204431Sraj	if (srcpos_file) {
205204431Sraj		search.dir = srcpos_file->dir;
206204431Sraj		search.next = NULL;
207204431Sraj		search.prev = NULL;
208204431Sraj		searchptr = &search;
209204431Sraj	}
210204431Sraj
211204431Sraj	newfile = dtc_open_file(filename, searchptr);
212204431Sraj
213204431Sraj	incl_file = xmalloc(sizeof(struct incl_file));
214204431Sraj
215204431Sraj	/*
216204431Sraj	 * Save current context.
217204431Sraj	 */
218204431Sraj	incl_file->yy_prev_buf = YY_CURRENT_BUFFER;
219204431Sraj	incl_file->yy_prev_lineno = yylineno;
220204431Sraj	incl_file->file = srcpos_file;
221204431Sraj	incl_file->prev = incl_file_stack;
222204431Sraj
223204431Sraj	incl_file_stack = incl_file;
224204431Sraj
225204431Sraj	/*
226204431Sraj	 * Establish new context.
227204431Sraj	 */
228204431Sraj	srcpos_file = newfile;
229204431Sraj	yylineno = 1;
230204431Sraj	yyin = newfile->file;
231204431Sraj	yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
232204431Sraj}
233204431Sraj
234204431Sraj
235204431Srajstatic int pop_input_file(void)
236204431Sraj{
237204431Sraj	struct incl_file *incl_file;
238204431Sraj
239204431Sraj	if (incl_file_stack == 0)
240204431Sraj		return 0;
241204431Sraj
242204431Sraj	dtc_close_file(srcpos_file);
243204431Sraj
244204431Sraj	/*
245204431Sraj	 * Pop.
246204431Sraj	 */
247204431Sraj	--incl_depth;
248204431Sraj	incl_file = incl_file_stack;
249204431Sraj	incl_file_stack = incl_file->prev;
250204431Sraj
251204431Sraj	/*
252204431Sraj	 * Recover old context.
253204431Sraj	 */
254204431Sraj	yy_delete_buffer(YY_CURRENT_BUFFER);
255204431Sraj	yy_switch_to_buffer(incl_file->yy_prev_buf);
256204431Sraj	yylineno = incl_file->yy_prev_lineno;
257204431Sraj	srcpos_file = incl_file->file;
258204431Sraj	yyin = incl_file->file ? incl_file->file->file : NULL;
259204431Sraj
260204431Sraj	/*
261204431Sraj	 * Free old state.
262204431Sraj	 */
263204431Sraj	free(incl_file);
264204431Sraj
265204431Sraj	return 1;
266204431Sraj}
267