Browse Source

Move character literal processing to the lexer

To match the processing of integer literals, character literals are passed
as a string from lexer to parser then interpreted there.  This is just as
awkward as it was for integer literals, without the excuse that we used to
need the information about the dts version to process them correctly.

So, move character literal processing back to the lexer as well, cleaning
things up.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
main
David Gibson 11 years ago
parent
commit
cfc6523619
  1. 20
      dtc-lexer.l
  2. 34
      dtc-parser.y

20
dtc-lexer.l

@ -167,9 +167,23 @@ static void lexical_error(const char *fmt, ...);
} }


<*>{CHAR_LITERAL} { <*>{CHAR_LITERAL} {
yytext[yyleng-1] = '\0'; struct data d;
yylval.literal = xstrdup(yytext+1); DPRINT("Character literal: %s\n", yytext);
DPRINT("Character literal: %s\n", yylval.literal);
d = data_copy_escape_string(yytext+1, yyleng-2);
if (d.len == 1) {
lexical_error("Empty character literal");
yylval.integer = 0;
return DT_CHAR_LITERAL;
}

yylval.integer = (unsigned char)d.val[0];

if (d.len > 2)
lexical_error("Character literal has %d"
" characters instead of 1",
d.len - 1);

return DT_CHAR_LITERAL; return DT_CHAR_LITERAL;
} }



34
dtc-parser.y

@ -32,13 +32,10 @@ extern void yyerror(char const *s);


extern struct boot_info *the_boot_info; extern struct boot_info *the_boot_info;
extern bool treesource_error; extern bool treesource_error;

static unsigned char eval_char_literal(const char *s);
%} %}


%union { %union {
char *propnodename; char *propnodename;
char *literal;
char *labelref; char *labelref;
unsigned int cbase; unsigned int cbase;
uint8_t byte; uint8_t byte;
@ -65,7 +62,7 @@ static unsigned char eval_char_literal(const char *s);
%token DT_DEL_NODE %token DT_DEL_NODE
%token <propnodename> DT_PROPNODENAME %token <propnodename> DT_PROPNODENAME
%token <integer> DT_LITERAL %token <integer> DT_LITERAL
%token <literal> DT_CHAR_LITERAL %token <integer> DT_CHAR_LITERAL
%token <cbase> DT_BASE %token <cbase> DT_BASE
%token <byte> DT_BYTE %token <byte> DT_BYTE
%token <data> DT_STRING %token <data> DT_STRING
@ -336,9 +333,6 @@ arrayprefix:
integer_prim: integer_prim:
DT_LITERAL DT_LITERAL
| DT_CHAR_LITERAL | DT_CHAR_LITERAL
{
$$ = eval_char_literal($1);
}
| '(' integer_expr ')' | '(' integer_expr ')'
{ {
$$ = $2; $$ = $2;
@ -482,29 +476,3 @@ void print_error(char const *fmt, ...)
void yyerror(char const *s) { void yyerror(char const *s) {
print_error("%s", s); print_error("%s", s);
} }

static unsigned char eval_char_literal(const char *s)
{
int i = 1;
char c = s[0];

if (c == '\0')
{
print_error("empty character literal");
return 0;
}

/*
* If the first character in the character literal is a \ then process
* the remaining characters as an escape encoding. If the first
* character is neither an escape or a terminator it should be the only
* character in the literal and will be returned.
*/
if (c == '\\')
c = get_escape_char(s, &i);

if (s[i] != '\0')
print_error("malformed character literal");

return c;
}

Loading…
Cancel
Save