mirror of
https://github.com/dgibson/dtc.git
synced 2025-10-13 16:27:39 -04:00
This patch applies a couple of tiny cleanups to the lexer. The not-very-useful 'WS' named pattern is removed, and the debugging printf() for single character tokens is moved to the top of the action, which results in less confusing output when LEXDEBUG is switched on (because it goes before the printf()s for possible resulting lexer state changes). Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
329 lines
6.8 KiB
Text
329 lines
6.8 KiB
Text
/*
|
|
* (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
|
|
*
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
|
* USA
|
|
*/
|
|
|
|
%option noyywrap nounput yylineno
|
|
|
|
%x INCLUDE
|
|
%x BYTESTRING
|
|
%x PROPNODENAME
|
|
%s V1
|
|
|
|
PROPNODECHAR [a-zA-Z0-9,._+*#?@-]
|
|
PATHCHAR ({PROPNODECHAR}|[/])
|
|
LEGACYPATHCHAR [a-zA-Z0-9_@/]
|
|
LABEL [a-zA-Z_][a-zA-Z0-9_]*
|
|
|
|
%{
|
|
#include "dtc.h"
|
|
#include "srcpos.h"
|
|
#include "dtc-parser.tab.h"
|
|
|
|
|
|
/*#define LEXDEBUG 1*/
|
|
|
|
#ifdef LEXDEBUG
|
|
#define DPRINT(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
|
|
#else
|
|
#define DPRINT(fmt, ...) do { } while (0)
|
|
#endif
|
|
|
|
static int dts_version; /* = 0 */
|
|
|
|
#define BEGIN_DEFAULT() if (dts_version == 0) { \
|
|
DPRINT("<INITIAL>\n"); \
|
|
BEGIN(INITIAL); \
|
|
} else { \
|
|
DPRINT("<V1>\n"); \
|
|
BEGIN(V1); \
|
|
}
|
|
%}
|
|
|
|
%%
|
|
<*>"/include/" BEGIN(INCLUDE);
|
|
|
|
<INCLUDE>\"[^"\n]*\" {
|
|
yytext[strlen(yytext) - 1] = 0;
|
|
if (!push_input_file(yytext + 1)) {
|
|
/* Some unrecoverable error.*/
|
|
exit(1);
|
|
}
|
|
BEGIN_DEFAULT();
|
|
}
|
|
|
|
|
|
<*><<EOF>> {
|
|
if (!pop_input_file()) {
|
|
yyterminate();
|
|
}
|
|
}
|
|
|
|
<*>\"([^\\"]|\\.)*\" {
|
|
yylloc.filenum = srcpos_filenum;
|
|
yylloc.first_line = yylineno;
|
|
DPRINT("String: %s\n", yytext);
|
|
yylval.data = data_copy_escape_string(yytext+1,
|
|
yyleng-2);
|
|
yylloc.first_line = yylineno;
|
|
return DT_STRING;
|
|
}
|
|
|
|
<*>"/dts-v1/" {
|
|
yylloc.filenum = srcpos_filenum;
|
|
yylloc.first_line = yylineno;
|
|
DPRINT("Keyword: /dts-v1/\n");
|
|
dts_version = 1;
|
|
BEGIN_DEFAULT();
|
|
return DT_V1;
|
|
}
|
|
|
|
<*>"/memreserve/" {
|
|
yylloc.filenum = srcpos_filenum;
|
|
yylloc.first_line = yylineno;
|
|
DPRINT("Keyword: /memreserve/\n");
|
|
BEGIN_DEFAULT();
|
|
return DT_MEMRESERVE;
|
|
}
|
|
|
|
<*>{LABEL}: {
|
|
yylloc.filenum = srcpos_filenum;
|
|
yylloc.first_line = yylineno;
|
|
DPRINT("Label: %s\n", yytext);
|
|
yylval.labelref = strdup(yytext);
|
|
yylval.labelref[yyleng-1] = '\0';
|
|
return DT_LABEL;
|
|
}
|
|
|
|
<INITIAL>[bodh]# {
|
|
yylloc.filenum = srcpos_filenum;
|
|
yylloc.first_line = yylineno;
|
|
if (*yytext == 'b')
|
|
yylval.cbase = 2;
|
|
else if (*yytext == 'o')
|
|
yylval.cbase = 8;
|
|
else if (*yytext == 'd')
|
|
yylval.cbase = 10;
|
|
else
|
|
yylval.cbase = 16;
|
|
DPRINT("Base: %d\n", yylval.cbase);
|
|
return DT_BASE;
|
|
}
|
|
|
|
<INITIAL>[0-9a-fA-F]+ {
|
|
yylloc.filenum = srcpos_filenum;
|
|
yylloc.first_line = yylineno;
|
|
yylval.literal = strdup(yytext);
|
|
DPRINT("Literal: '%s'\n", yylval.literal);
|
|
return DT_LEGACYLITERAL;
|
|
}
|
|
|
|
<V1>[0-9]+|0[xX][0-9a-fA-F]+ {
|
|
yylloc.filenum = srcpos_filenum;
|
|
yylloc.first_line = yylineno;
|
|
yylval.literal = strdup(yytext);
|
|
DPRINT("Literal: '%s'\n", yylval.literal);
|
|
return DT_LITERAL;
|
|
}
|
|
|
|
\&{LABEL} { /* label reference */
|
|
yylloc.filenum = srcpos_filenum;
|
|
yylloc.first_line = yylineno;
|
|
DPRINT("Ref: %s\n", yytext+1);
|
|
yylval.labelref = strdup(yytext+1);
|
|
return DT_REF;
|
|
}
|
|
|
|
"&{/"{PATHCHAR}+\} { /* new-style path reference */
|
|
yylloc.filenum = srcpos_filenum;
|
|
yylloc.first_line = yylineno;
|
|
yytext[yyleng-1] = '\0';
|
|
DPRINT("Ref: %s\n", yytext+2);
|
|
yylval.labelref = strdup(yytext+2);
|
|
return DT_REF;
|
|
}
|
|
|
|
<INITIAL>"&/"{LEGACYPATHCHAR}+ { /* old-style path reference */
|
|
yylloc.filenum = srcpos_filenum;
|
|
yylloc.first_line = yylineno;
|
|
DPRINT("Ref: %s\n", yytext+1);
|
|
yylval.labelref = strdup(yytext+1);
|
|
return DT_REF;
|
|
}
|
|
|
|
<BYTESTRING>[0-9a-fA-F]{2} {
|
|
yylloc.filenum = srcpos_filenum;
|
|
yylloc.first_line = yylineno;
|
|
yylval.byte = strtol(yytext, NULL, 16);
|
|
DPRINT("Byte: %02x\n", (int)yylval.byte);
|
|
return DT_BYTE;
|
|
}
|
|
|
|
<BYTESTRING>"]" {
|
|
yylloc.filenum = srcpos_filenum;
|
|
yylloc.first_line = yylineno;
|
|
DPRINT("/BYTESTRING\n");
|
|
BEGIN_DEFAULT();
|
|
return ']';
|
|
}
|
|
|
|
<PROPNODENAME>{PROPNODECHAR}+ {
|
|
yylloc.filenum = srcpos_filenum;
|
|
yylloc.first_line = yylineno;
|
|
DPRINT("PropNodeName: %s\n", yytext);
|
|
yylval.propnodename = strdup(yytext);
|
|
BEGIN_DEFAULT();
|
|
return DT_PROPNODENAME;
|
|
}
|
|
|
|
|
|
<*>[[:space:]]+ /* eat whitespace */
|
|
|
|
<*>"/*"([^*]|\*+[^*/])*\*+"/" {
|
|
yylloc.filenum = srcpos_filenum;
|
|
yylloc.first_line = yylineno;
|
|
DPRINT("Comment: %s\n", yytext);
|
|
/* eat comments */
|
|
}
|
|
|
|
<*>"//".*\n /* eat line comments */
|
|
|
|
<*>. {
|
|
yylloc.filenum = srcpos_filenum;
|
|
yylloc.first_line = yylineno;
|
|
DPRINT("Char: %c (\\x%02x)\n", yytext[0],
|
|
(unsigned)yytext[0]);
|
|
if (yytext[0] == '[') {
|
|
DPRINT("<BYTESTRING>\n");
|
|
BEGIN(BYTESTRING);
|
|
}
|
|
if ((yytext[0] == '{')
|
|
|| (yytext[0] == ';')) {
|
|
DPRINT("<PROPNODENAME>\n");
|
|
BEGIN(PROPNODENAME);
|
|
}
|
|
return yytext[0];
|
|
}
|
|
|
|
%%
|
|
|
|
|
|
/*
|
|
* Stack of nested include file contexts.
|
|
*/
|
|
|
|
struct incl_file {
|
|
int filenum;
|
|
FILE *file;
|
|
YY_BUFFER_STATE yy_prev_buf;
|
|
int yy_prev_lineno;
|
|
struct incl_file *prev;
|
|
};
|
|
|
|
struct incl_file *incl_file_stack;
|
|
|
|
|
|
/*
|
|
* Detect infinite include recursion.
|
|
*/
|
|
#define MAX_INCLUDE_DEPTH (100)
|
|
|
|
static int incl_depth = 0;
|
|
|
|
|
|
int push_input_file(const char *filename)
|
|
{
|
|
FILE *f;
|
|
struct incl_file *incl_file;
|
|
|
|
if (!filename) {
|
|
yyerror("No include file name given.");
|
|
return 0;
|
|
}
|
|
|
|
if (incl_depth++ >= MAX_INCLUDE_DEPTH) {
|
|
yyerror("Includes nested too deeply");
|
|
return 0;
|
|
}
|
|
|
|
f = dtc_open_file(filename);
|
|
|
|
incl_file = malloc(sizeof(struct incl_file));
|
|
if (!incl_file) {
|
|
yyerror("Can not allocate include file space.");
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Save current context.
|
|
*/
|
|
incl_file->yy_prev_buf = YY_CURRENT_BUFFER;
|
|
incl_file->yy_prev_lineno = yylineno;
|
|
incl_file->filenum = srcpos_filenum;
|
|
incl_file->file = yyin;
|
|
incl_file->prev = incl_file_stack;
|
|
|
|
incl_file_stack = incl_file;
|
|
|
|
/*
|
|
* Establish new context.
|
|
*/
|
|
srcpos_filenum = lookup_file_name(filename, 0);
|
|
yylineno = 1;
|
|
yyin = f;
|
|
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
int pop_input_file(void)
|
|
{
|
|
struct incl_file *incl_file;
|
|
|
|
if (incl_file_stack == 0)
|
|
return 0;
|
|
|
|
fclose(yyin);
|
|
|
|
/*
|
|
* Pop.
|
|
*/
|
|
--incl_depth;
|
|
incl_file = incl_file_stack;
|
|
incl_file_stack = incl_file->prev;
|
|
|
|
/*
|
|
* Recover old context.
|
|
*/
|
|
yy_delete_buffer(YY_CURRENT_BUFFER);
|
|
yy_switch_to_buffer(incl_file->yy_prev_buf);
|
|
yylineno = incl_file->yy_prev_lineno;
|
|
srcpos_filenum = incl_file->filenum;
|
|
yyin = incl_file->file;
|
|
|
|
/*
|
|
* Free old state.
|
|
*/
|
|
free(incl_file);
|
|
|
|
if (YY_CURRENT_BUFFER == 0)
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|