symbian-qemu-0.9.1-12/dtc-trunk/dtc-lexer.l
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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 yylineno
       
    22 
       
    23 %x INCLUDE
       
    24 %x BYTESTRING
       
    25 %x PROPNODENAME
       
    26 %s V1
       
    27 
       
    28 PROPNODECHAR	[a-zA-Z0-9,._+*#?@-]
       
    29 PATHCHAR	({PROPNODECHAR}|[/])
       
    30 LABEL		[a-zA-Z_][a-zA-Z0-9_]*
       
    31 STRING		\"([^\\"]|\\.)*\"
       
    32 WS		[[:space:]]
       
    33 COMMENT		"/*"([^*]|\*+[^*/])*\*+"/"
       
    34 LINECOMMENT	"//".*\n
       
    35 
       
    36 %{
       
    37 #include "dtc.h"
       
    38 #include "srcpos.h"
       
    39 #include "dtc-parser.h"
       
    40 
       
    41 
       
    42 /*#define LEXDEBUG	1*/
       
    43 
       
    44 #ifdef LEXDEBUG
       
    45 #define DPRINT(fmt, ...)	fprintf(stderr, fmt, ##__VA_ARGS__)
       
    46 #else
       
    47 #define DPRINT(fmt, ...)	do { } while (0)
       
    48 #endif
       
    49 
       
    50 static int dts_version; /* = 0 */
       
    51 
       
    52 #define BEGIN_DEFAULT()	if (dts_version == 0) { \
       
    53 				DPRINT("<INITIAL>\n"); \
       
    54 				BEGIN(INITIAL); \
       
    55 			} else { \
       
    56 				DPRINT("<V1>\n"); \
       
    57 				BEGIN(V1); \
       
    58 			}
       
    59 
       
    60 static void push_input_file(const char *filename);
       
    61 static int pop_input_file(void);
       
    62 %}
       
    63 
       
    64 %%
       
    65 <*>"/include/"{WS}*{STRING} {
       
    66 			char *name = strchr(yytext, '\"') + 1;
       
    67 			yytext[yyleng-1] = '\0';
       
    68 			push_input_file(name);
       
    69 		}
       
    70 
       
    71 <*><<EOF>>		{
       
    72 			if (!pop_input_file()) {
       
    73 				yyterminate();
       
    74 			}
       
    75 		}
       
    76 
       
    77 <*>{STRING}	{
       
    78 			yylloc.file = srcpos_file;
       
    79 			yylloc.first_line = yylineno;
       
    80 			DPRINT("String: %s\n", yytext);
       
    81 			yylval.data = data_copy_escape_string(yytext+1,
       
    82 					yyleng-2);
       
    83 			yylloc.first_line = yylineno;
       
    84 			return DT_STRING;
       
    85 		}
       
    86 
       
    87 <*>"/dts-v1/"	{
       
    88 			yylloc.file = srcpos_file;
       
    89 			yylloc.first_line = yylineno;
       
    90 			DPRINT("Keyword: /dts-v1/\n");
       
    91 			dts_version = 1;
       
    92 			BEGIN_DEFAULT();
       
    93 			return DT_V1;
       
    94 		}
       
    95 
       
    96 <*>"/memreserve/"	{
       
    97 			yylloc.file = srcpos_file;
       
    98 			yylloc.first_line = yylineno;
       
    99 			DPRINT("Keyword: /memreserve/\n");
       
   100 			BEGIN_DEFAULT();
       
   101 			return DT_MEMRESERVE;
       
   102 		}
       
   103 
       
   104 <*>{LABEL}:	{
       
   105 			yylloc.file = srcpos_file;
       
   106 			yylloc.first_line = yylineno;
       
   107 			DPRINT("Label: %s\n", yytext);
       
   108 			yylval.labelref = strdup(yytext);
       
   109 			yylval.labelref[yyleng-1] = '\0';
       
   110 			return DT_LABEL;
       
   111 		}
       
   112 
       
   113 <INITIAL>[bodh]# {
       
   114 			yylloc.file = srcpos_file;
       
   115 			yylloc.first_line = yylineno;
       
   116 			if (*yytext == 'b')
       
   117 				yylval.cbase = 2;
       
   118 			else if (*yytext == 'o')
       
   119 				yylval.cbase = 8;
       
   120 			else if (*yytext == 'd')
       
   121 				yylval.cbase = 10;
       
   122 			else
       
   123 				yylval.cbase = 16;
       
   124 			DPRINT("Base: %d\n", yylval.cbase);
       
   125 			return DT_BASE;
       
   126 		}
       
   127 
       
   128 <INITIAL>[0-9a-fA-F]+	{
       
   129 			yylloc.file = srcpos_file;
       
   130 			yylloc.first_line = yylineno;
       
   131 			yylval.literal = strdup(yytext);
       
   132 			DPRINT("Literal: '%s'\n", yylval.literal);
       
   133 			return DT_LEGACYLITERAL;
       
   134 		}
       
   135 
       
   136 <V1>[0-9]+|0[xX][0-9a-fA-F]+      {
       
   137 			yylloc.file = srcpos_file;
       
   138 			yylloc.first_line = yylineno;
       
   139 			yylval.literal = strdup(yytext);
       
   140 			DPRINT("Literal: '%s'\n", yylval.literal);
       
   141 			return DT_LITERAL;
       
   142 		}
       
   143 
       
   144 \&{LABEL}	{	/* label reference */
       
   145 			yylloc.file = srcpos_file;
       
   146 			yylloc.first_line = yylineno;
       
   147 			DPRINT("Ref: %s\n", yytext+1);
       
   148 			yylval.labelref = strdup(yytext+1);
       
   149 			return DT_REF;
       
   150 		}
       
   151 
       
   152 "&{/"{PATHCHAR}+\}	{	/* new-style path reference */
       
   153 			yylloc.file = srcpos_file;
       
   154 			yylloc.first_line = yylineno;
       
   155 			yytext[yyleng-1] = '\0';
       
   156 			DPRINT("Ref: %s\n", yytext+2);
       
   157 			yylval.labelref = strdup(yytext+2);
       
   158 			return DT_REF;
       
   159 		}
       
   160 
       
   161 <INITIAL>"&/"{PATHCHAR}+ {	/* old-style path reference */
       
   162 			yylloc.file = srcpos_file;
       
   163 			yylloc.first_line = yylineno;
       
   164 			DPRINT("Ref: %s\n", yytext+1);
       
   165 			yylval.labelref = strdup(yytext+1);
       
   166 			return DT_REF;
       
   167 		}
       
   168 
       
   169 <BYTESTRING>[0-9a-fA-F]{2} {
       
   170 			yylloc.file = srcpos_file;
       
   171 			yylloc.first_line = yylineno;
       
   172 			yylval.byte = strtol(yytext, NULL, 16);
       
   173 			DPRINT("Byte: %02x\n", (int)yylval.byte);
       
   174 			return DT_BYTE;
       
   175 		}
       
   176 
       
   177 <BYTESTRING>"]"	{
       
   178 			yylloc.file = srcpos_file;
       
   179 			yylloc.first_line = yylineno;
       
   180 			DPRINT("/BYTESTRING\n");
       
   181 			BEGIN_DEFAULT();
       
   182 			return ']';
       
   183 		}
       
   184 
       
   185 <PROPNODENAME>{PROPNODECHAR}+ {
       
   186 			yylloc.file = srcpos_file;
       
   187 			yylloc.first_line = yylineno;
       
   188 			DPRINT("PropNodeName: %s\n", yytext);
       
   189 			yylval.propnodename = strdup(yytext);
       
   190 			BEGIN_DEFAULT();
       
   191 			return DT_PROPNODENAME;
       
   192 		}
       
   193 
       
   194 "/incbin/"	{
       
   195 			yylloc.file = srcpos_file;
       
   196 			yylloc.first_line = yylineno;
       
   197 			DPRINT("Binary Include\n");
       
   198 			return DT_INCBIN;
       
   199 		}
       
   200 
       
   201 <*>{WS}+	/* eat whitespace */
       
   202 <*>{COMMENT}+	/* eat C-style comments */
       
   203 <*>{LINECOMMENT}+ /* eat C++-style comments */
       
   204 
       
   205 <*>.		{
       
   206 			yylloc.file = srcpos_file;
       
   207 			yylloc.first_line = yylineno;
       
   208 			DPRINT("Char: %c (\\x%02x)\n", yytext[0],
       
   209 				(unsigned)yytext[0]);
       
   210 			if (yytext[0] == '[') {
       
   211 				DPRINT("<BYTESTRING>\n");
       
   212 				BEGIN(BYTESTRING);
       
   213 			}
       
   214 			if ((yytext[0] == '{')
       
   215 			    || (yytext[0] == ';')) {
       
   216 				DPRINT("<PROPNODENAME>\n");
       
   217 				BEGIN(PROPNODENAME);
       
   218 			}
       
   219 			return yytext[0];
       
   220 		}
       
   221 
       
   222 %%
       
   223 
       
   224 
       
   225 /*
       
   226  * Stack of nested include file contexts.
       
   227  */
       
   228 
       
   229 struct incl_file {
       
   230 	struct dtc_file *file;
       
   231 	YY_BUFFER_STATE yy_prev_buf;
       
   232 	int yy_prev_lineno;
       
   233 	struct incl_file *prev;
       
   234 };
       
   235 
       
   236 static struct incl_file *incl_file_stack;
       
   237 
       
   238 
       
   239 /*
       
   240  * Detect infinite include recursion.
       
   241  */
       
   242 #define MAX_INCLUDE_DEPTH	(100)
       
   243 
       
   244 static int incl_depth = 0;
       
   245 
       
   246 
       
   247 static void push_input_file(const char *filename)
       
   248 {
       
   249 	struct incl_file *incl_file;
       
   250 	struct dtc_file *newfile;
       
   251 	struct search_path search, *searchptr = NULL;
       
   252 
       
   253 	assert(filename);
       
   254 
       
   255 	if (incl_depth++ >= MAX_INCLUDE_DEPTH)
       
   256 		die("Includes nested too deeply");
       
   257 
       
   258 	if (srcpos_file) {
       
   259 		search.dir = srcpos_file->dir;
       
   260 		search.next = NULL;
       
   261 		search.prev = NULL;
       
   262 		searchptr = &search;
       
   263 	}
       
   264 
       
   265 	newfile = dtc_open_file(filename, searchptr);
       
   266 
       
   267 	incl_file = xmalloc(sizeof(struct incl_file));
       
   268 
       
   269 	/*
       
   270 	 * Save current context.
       
   271 	 */
       
   272 	incl_file->yy_prev_buf = YY_CURRENT_BUFFER;
       
   273 	incl_file->yy_prev_lineno = yylineno;
       
   274 	incl_file->file = srcpos_file;
       
   275 	incl_file->prev = incl_file_stack;
       
   276 
       
   277 	incl_file_stack = incl_file;
       
   278 
       
   279 	/*
       
   280 	 * Establish new context.
       
   281 	 */
       
   282 	srcpos_file = newfile;
       
   283 	yylineno = 1;
       
   284 	yyin = newfile->file;
       
   285 	yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
       
   286 }
       
   287 
       
   288 
       
   289 static int pop_input_file(void)
       
   290 {
       
   291 	struct incl_file *incl_file;
       
   292 
       
   293 	if (incl_file_stack == 0)
       
   294 		return 0;
       
   295 
       
   296 	dtc_close_file(srcpos_file);
       
   297 
       
   298 	/*
       
   299 	 * Pop.
       
   300 	 */
       
   301 	--incl_depth;
       
   302 	incl_file = incl_file_stack;
       
   303 	incl_file_stack = incl_file->prev;
       
   304 
       
   305 	/*
       
   306 	 * Recover old context.
       
   307 	 */
       
   308 	yy_delete_buffer(YY_CURRENT_BUFFER);
       
   309 	yy_switch_to_buffer(incl_file->yy_prev_buf);
       
   310 	yylineno = incl_file->yy_prev_lineno;
       
   311 	srcpos_file = incl_file->file;
       
   312 	yyin = incl_file->file ? incl_file->file->file : NULL;
       
   313 
       
   314 	/*
       
   315 	 * Free old state.
       
   316 	 */
       
   317 	free(incl_file);
       
   318 
       
   319 	return 1;
       
   320 }