diff options
author | Masahiro Yamada <yamada.masahiro@socionext.com> | 2018-12-30 22:59:26 +0900 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2019-01-03 10:17:16 +0100 |
commit | 273dbe5f87de8d6129a68ad40e87922fb6e783b6 (patch) | |
tree | 41f19d7c159df88aa1dee4bff084f3e57dfc18db /scripts/dtc | |
parent | c17116dc3818b45cbc3997de72d05e64aab04cbe (diff) | |
download | barebox-273dbe5f87de8d6129a68ad40e87922fb6e783b6.tar.gz barebox-273dbe5f87de8d6129a68ad40e87922fb6e783b6.tar.xz |
kbuild: generate lexer and parser during build instead of shipping
Recent kernel versions run flex and bison to generate lexers and
parsers from real source files such as *.l and *.y . This provides
better maintainability than version-controlling pre-generated C files
with a "_shipped" suffix.
This commit imports flex and bison rules from Linux, and deletes
pre-generated parsers and lexers.
Refer to the following commits in Linux:
- 033dba2ec06c ("kbuild: prepare to remove C files pre-generated by
flex and bison")
- 29c833061c1d ("kconfig: generate lexer and parser during build
instead of shipping")
- e039139be8c2 ("scripts/dtc: generate lexer and parser during
build instead of shipping")
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'scripts/dtc')
-rw-r--r-- | scripts/dtc/dtc-lexer.l | 306 | ||||
-rw-r--r-- | scripts/dtc/dtc-parser.y | 538 |
2 files changed, 0 insertions, 844 deletions
diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l deleted file mode 100644 index fd825ebba6..0000000000 --- a/scripts/dtc/dtc-lexer.l +++ /dev/null @@ -1,306 +0,0 @@ -/* - * (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 noinput never-interactive - -%x BYTESTRING -%x PROPNODENAME -%s V1 - -PROPNODECHAR [a-zA-Z0-9,._+*#?@-] -PATHCHAR ({PROPNODECHAR}|[/]) -LABEL [a-zA-Z_][a-zA-Z0-9_]* -STRING \"([^\\"]|\\.)*\" -CHAR_LITERAL '([^']|\\')*' -WS [[:space:]] -COMMENT "/*"([^*]|\*+[^*/])*\*+"/" -LINECOMMENT "//".*\n - -%{ -#include "dtc.h" -#include "srcpos.h" -#include "dtc-parser.tab.h" - -YYLTYPE yylloc; -extern bool treesource_error; - -/* CAUTION: this will stop working if we ever use yyless() or yyunput() */ -#define YY_USER_ACTION \ - { \ - srcpos_update(&yylloc, yytext, yyleng); \ - } - -/*#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 = 1; - -#define BEGIN_DEFAULT() DPRINT("<V1>\n"); \ - BEGIN(V1); \ - -static void push_input_file(const char *filename); -static bool pop_input_file(void); -static void PRINTF(1, 2) lexical_error(const char *fmt, ...); - -%} - -%% -<*>"/include/"{WS}*{STRING} { - char *name = strchr(yytext, '\"') + 1; - yytext[yyleng-1] = '\0'; - push_input_file(name); - } - -<*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t]+[0-9]+)? { - char *line, *fnstart, *fnend; - struct data fn; - /* skip text before line # */ - line = yytext; - while (!isdigit((unsigned char)*line)) - line++; - - /* regexp ensures that first and list " - * in the whole yytext are those at - * beginning and end of the filename string */ - fnstart = memchr(yytext, '"', yyleng); - for (fnend = yytext + yyleng - 1; - *fnend != '"'; fnend--) - ; - assert(fnstart && fnend && (fnend > fnstart)); - - fn = data_copy_escape_string(fnstart + 1, - fnend - fnstart - 1); - - /* Don't allow nuls in filenames */ - if (memchr(fn.val, '\0', fn.len - 1)) - lexical_error("nul in line number directive"); - - /* -1 since #line is the number of the next line */ - srcpos_set_line(xstrdup(fn.val), atoi(line) - 1); - data_free(fn); - } - -<*><<EOF>> { - if (!pop_input_file()) { - yyterminate(); - } - } - -<*>{STRING} { - DPRINT("String: %s\n", yytext); - yylval.data = data_copy_escape_string(yytext+1, - yyleng-2); - return DT_STRING; - } - -<*>"/dts-v1/" { - DPRINT("Keyword: /dts-v1/\n"); - dts_version = 1; - BEGIN_DEFAULT(); - return DT_V1; - } - -<*>"/plugin/" { - DPRINT("Keyword: /plugin/\n"); - return DT_PLUGIN; - } - -<*>"/memreserve/" { - DPRINT("Keyword: /memreserve/\n"); - BEGIN_DEFAULT(); - return DT_MEMRESERVE; - } - -<*>"/bits/" { - DPRINT("Keyword: /bits/\n"); - BEGIN_DEFAULT(); - return DT_BITS; - } - -<*>"/delete-property/" { - DPRINT("Keyword: /delete-property/\n"); - DPRINT("<PROPNODENAME>\n"); - BEGIN(PROPNODENAME); - return DT_DEL_PROP; - } - -<*>"/delete-node/" { - DPRINT("Keyword: /delete-node/\n"); - DPRINT("<PROPNODENAME>\n"); - BEGIN(PROPNODENAME); - return DT_DEL_NODE; - } - -<*>{LABEL}: { - DPRINT("Label: %s\n", yytext); - yylval.labelref = xstrdup(yytext); - yylval.labelref[yyleng-1] = '\0'; - return DT_LABEL; - } - -<V1>([0-9]+|0[xX][0-9a-fA-F]+)(U|L|UL|LL|ULL)? { - char *e; - DPRINT("Integer Literal: '%s'\n", yytext); - - errno = 0; - yylval.integer = strtoull(yytext, &e, 0); - - if (*e && e[strspn(e, "UL")]) { - lexical_error("Bad integer literal '%s'", - yytext); - } - - if (errno == ERANGE) - lexical_error("Integer literal '%s' out of range", - yytext); - else - /* ERANGE is the only strtoull error triggerable - * by strings matching the pattern */ - assert(errno == 0); - return DT_LITERAL; - } - -<*>{CHAR_LITERAL} { - struct data d; - DPRINT("Character literal: %s\n", yytext); - - d = data_copy_escape_string(yytext+1, yyleng-2); - if (d.len == 1) { - lexical_error("Empty character literal"); - yylval.integer = 0; - } else { - yylval.integer = (unsigned char)d.val[0]; - - if (d.len > 2) - lexical_error("Character literal has %d" - " characters instead of 1", - d.len - 1); - } - - data_free(d); - return DT_CHAR_LITERAL; - } - -<*>\&{LABEL} { /* label reference */ - DPRINT("Ref: %s\n", yytext+1); - yylval.labelref = xstrdup(yytext+1); - return DT_REF; - } - -<*>"&{/"{PATHCHAR}*\} { /* new-style path reference */ - yytext[yyleng-1] = '\0'; - DPRINT("Ref: %s\n", yytext+2); - yylval.labelref = xstrdup(yytext+2); - return DT_REF; - } - -<BYTESTRING>[0-9a-fA-F]{2} { - yylval.byte = strtol(yytext, NULL, 16); - DPRINT("Byte: %02x\n", (int)yylval.byte); - return DT_BYTE; - } - -<BYTESTRING>"]" { - DPRINT("/BYTESTRING\n"); - BEGIN_DEFAULT(); - return ']'; - } - -<PROPNODENAME>\\?{PROPNODECHAR}+ { - DPRINT("PropNodeName: %s\n", yytext); - yylval.propnodename = xstrdup((yytext[0] == '\\') ? - yytext + 1 : yytext); - BEGIN_DEFAULT(); - return DT_PROPNODENAME; - } - -"/incbin/" { - DPRINT("Binary Include\n"); - return DT_INCBIN; - } - -<*>{WS}+ /* eat whitespace */ -<*>{COMMENT}+ /* eat C-style comments */ -<*>{LINECOMMENT}+ /* eat C++-style comments */ - -<*>"<<" { return DT_LSHIFT; }; -<*>">>" { return DT_RSHIFT; }; -<*>"<=" { return DT_LE; }; -<*>">=" { return DT_GE; }; -<*>"==" { return DT_EQ; }; -<*>"!=" { return DT_NE; }; -<*>"&&" { return DT_AND; }; -<*>"||" { return DT_OR; }; - -<*>. { - 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]; - } - -%% - -static void push_input_file(const char *filename) -{ - assert(filename); - - srcfile_push(filename); - - yyin = current_srcfile->f; - - yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE)); -} - - -static bool pop_input_file(void) -{ - if (srcfile_pop() == 0) - return false; - - yypop_buffer_state(); - yyin = current_srcfile->f; - - return true; -} - -static void lexical_error(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - srcpos_verror(&yylloc, "Lexical error", fmt, ap); - va_end(ap); - - treesource_error = true; -} diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y deleted file mode 100644 index 44af170abf..0000000000 --- a/scripts/dtc/dtc-parser.y +++ /dev/null @@ -1,538 +0,0 @@ -/* - * (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 - */ -%{ -#include <stdio.h> -#include <inttypes.h> - -#include "dtc.h" -#include "srcpos.h" - -extern int yylex(void); -extern void yyerror(char const *s); -#define ERROR(loc, ...) \ - do { \ - srcpos_error((loc), "Error", __VA_ARGS__); \ - treesource_error = true; \ - } while (0) - -extern struct dt_info *parser_output; -extern bool treesource_error; -%} - -%union { - char *propnodename; - char *labelref; - uint8_t byte; - struct data data; - - struct { - struct data data; - int bits; - } array; - - struct property *prop; - struct property *proplist; - struct node *node; - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; - unsigned int flags; -} - -%token DT_V1 -%token DT_PLUGIN -%token DT_MEMRESERVE -%token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR -%token DT_BITS -%token DT_DEL_PROP -%token DT_DEL_NODE -%token <propnodename> DT_PROPNODENAME -%token <integer> DT_LITERAL -%token <integer> DT_CHAR_LITERAL -%token <byte> DT_BYTE -%token <data> DT_STRING -%token <labelref> DT_LABEL -%token <labelref> DT_REF -%token DT_INCBIN - -%type <data> propdata -%type <data> propdataprefix -%type <flags> header -%type <flags> headers -%type <re> memreserve -%type <re> memreserves -%type <array> arrayprefix -%type <data> bytestring -%type <prop> propdef -%type <proplist> proplist - -%type <node> devicetree -%type <node> nodedef -%type <node> subnode -%type <nodelist> subnodes - -%type <integer> integer_prim -%type <integer> integer_unary -%type <integer> integer_mul -%type <integer> integer_add -%type <integer> integer_shift -%type <integer> integer_rela -%type <integer> integer_eq -%type <integer> integer_bitand -%type <integer> integer_bitxor -%type <integer> integer_bitor -%type <integer> integer_and -%type <integer> integer_or -%type <integer> integer_trinary -%type <integer> integer_expr - -%% - -sourcefile: - headers memreserves devicetree - { - parser_output = build_dt_info($1, $2, $3, - guess_boot_cpuid($3)); - } - ; - -header: - DT_V1 ';' - { - $$ = DTSF_V1; - } - | DT_V1 ';' DT_PLUGIN ';' - { - $$ = DTSF_V1 | DTSF_PLUGIN; - } - ; - -headers: - header - | header headers - { - if ($2 != $1) - ERROR(&@2, "Header flags don't match earlier ones"); - $$ = $1; - } - ; - -memreserves: - /* empty */ - { - $$ = NULL; - } - | memreserve memreserves - { - $$ = chain_reserve_entry($1, $2); - } - ; - -memreserve: - DT_MEMRESERVE integer_prim integer_prim ';' - { - $$ = build_reserve_entry($2, $3); - } - | DT_LABEL memreserve - { - add_label(&$2->labels, $1); - $$ = $2; - } - ; - -devicetree: - '/' nodedef - { - $$ = name_node($2, ""); - } - | devicetree '/' nodedef - { - $$ = merge_nodes($1, $3); - } - | DT_REF nodedef - { - /* - * We rely on the rule being always: - * versioninfo plugindecl memreserves devicetree - * so $-1 is what we want (plugindecl) - */ - if (!($<flags>-1 & DTSF_PLUGIN)) - ERROR(&@2, "Label or path %s not found", $1); - $$ = add_orphan_node(name_node(build_node(NULL, NULL), ""), $2, $1); - } - | devicetree DT_LABEL DT_REF nodedef - { - struct node *target = get_node_by_ref($1, $3); - - if (target) { - add_label(&target->labels, $2); - merge_nodes(target, $4); - } else - ERROR(&@3, "Label or path %s not found", $3); - $$ = $1; - } - | devicetree DT_REF nodedef - { - struct node *target = get_node_by_ref($1, $2); - - if (target) { - merge_nodes(target, $3); - } else { - /* - * We rely on the rule being always: - * versioninfo plugindecl memreserves devicetree - * so $-1 is what we want (plugindecl) - */ - if ($<flags>-1 & DTSF_PLUGIN) - add_orphan_node($1, $3, $2); - else - ERROR(&@2, "Label or path %s not found", $2); - } - $$ = $1; - } - | devicetree DT_DEL_NODE DT_REF ';' - { - struct node *target = get_node_by_ref($1, $3); - - if (target) - delete_node(target); - else - ERROR(&@3, "Label or path %s not found", $3); - - - $$ = $1; - } - ; - -nodedef: - '{' proplist subnodes '}' ';' - { - $$ = build_node($2, $3); - } - ; - -proplist: - /* empty */ - { - $$ = NULL; - } - | proplist propdef - { - $$ = chain_property($2, $1); - } - ; - -propdef: - DT_PROPNODENAME '=' propdata ';' - { - $$ = build_property($1, $3); - } - | DT_PROPNODENAME ';' - { - $$ = build_property($1, empty_data); - } - | DT_DEL_PROP DT_PROPNODENAME ';' - { - $$ = build_property_delete($2); - } - | DT_LABEL propdef - { - add_label(&$2->labels, $1); - $$ = $2; - } - ; - -propdata: - propdataprefix DT_STRING - { - $$ = data_merge($1, $2); - } - | propdataprefix arrayprefix '>' - { - $$ = data_merge($1, $2.data); - } - | propdataprefix '[' bytestring ']' - { - $$ = data_merge($1, $3); - } - | propdataprefix DT_REF - { - $$ = data_add_marker($1, REF_PATH, $2); - } - | propdataprefix DT_INCBIN '(' DT_STRING ',' integer_prim ',' integer_prim ')' - { - FILE *f = srcfile_relative_open($4.val, NULL); - struct data d; - - if ($6 != 0) - if (fseek(f, $6, SEEK_SET) != 0) - die("Couldn't seek to offset %llu in \"%s\": %s", - (unsigned long long)$6, $4.val, - strerror(errno)); - - d = data_copy_file(f, $8); - - $$ = data_merge($1, d); - fclose(f); - } - | propdataprefix DT_INCBIN '(' DT_STRING ')' - { - FILE *f = srcfile_relative_open($4.val, NULL); - struct data d = empty_data; - - d = data_copy_file(f, -1); - - $$ = data_merge($1, d); - fclose(f); - } - | propdata DT_LABEL - { - $$ = data_add_marker($1, LABEL, $2); - } - ; - -propdataprefix: - /* empty */ - { - $$ = empty_data; - } - | propdata ',' - { - $$ = $1; - } - | propdataprefix DT_LABEL - { - $$ = data_add_marker($1, LABEL, $2); - } - ; - -arrayprefix: - DT_BITS DT_LITERAL '<' - { - unsigned long long bits; - - bits = $2; - - if ((bits != 8) && (bits != 16) && - (bits != 32) && (bits != 64)) { - ERROR(&@2, "Array elements must be" - " 8, 16, 32 or 64-bits"); - bits = 32; - } - - $$.data = empty_data; - $$.bits = bits; - } - | '<' - { - $$.data = empty_data; - $$.bits = 32; - } - | arrayprefix integer_prim - { - if ($1.bits < 64) { - uint64_t mask = (1ULL << $1.bits) - 1; - /* - * Bits above mask must either be all zero - * (positive within range of mask) or all one - * (negative and sign-extended). The second - * condition is true if when we set all bits - * within the mask to one (i.e. | in the - * mask), all bits are one. - */ - if (($2 > mask) && (($2 | mask) != -1ULL)) - ERROR(&@2, "Value out of range for" - " %d-bit array element", $1.bits); - } - - $$.data = data_append_integer($1.data, $2, $1.bits); - } - | arrayprefix DT_REF - { - uint64_t val = ~0ULL >> (64 - $1.bits); - - if ($1.bits == 32) - $1.data = data_add_marker($1.data, - REF_PHANDLE, - $2); - else - ERROR(&@2, "References are only allowed in " - "arrays with 32-bit elements."); - - $$.data = data_append_integer($1.data, val, $1.bits); - } - | arrayprefix DT_LABEL - { - $$.data = data_add_marker($1.data, LABEL, $2); - } - ; - -integer_prim: - DT_LITERAL - | DT_CHAR_LITERAL - | '(' integer_expr ')' - { - $$ = $2; - } - ; - -integer_expr: - integer_trinary - ; - -integer_trinary: - integer_or - | integer_or '?' integer_expr ':' integer_trinary { $$ = $1 ? $3 : $5; } - ; - -integer_or: - integer_and - | integer_or DT_OR integer_and { $$ = $1 || $3; } - ; - -integer_and: - integer_bitor - | integer_and DT_AND integer_bitor { $$ = $1 && $3; } - ; - -integer_bitor: - integer_bitxor - | integer_bitor '|' integer_bitxor { $$ = $1 | $3; } - ; - -integer_bitxor: - integer_bitand - | integer_bitxor '^' integer_bitand { $$ = $1 ^ $3; } - ; - -integer_bitand: - integer_eq - | integer_bitand '&' integer_eq { $$ = $1 & $3; } - ; - -integer_eq: - integer_rela - | integer_eq DT_EQ integer_rela { $$ = $1 == $3; } - | integer_eq DT_NE integer_rela { $$ = $1 != $3; } - ; - -integer_rela: - integer_shift - | integer_rela '<' integer_shift { $$ = $1 < $3; } - | integer_rela '>' integer_shift { $$ = $1 > $3; } - | integer_rela DT_LE integer_shift { $$ = $1 <= $3; } - | integer_rela DT_GE integer_shift { $$ = $1 >= $3; } - ; - -integer_shift: - integer_shift DT_LSHIFT integer_add { $$ = $1 << $3; } - | integer_shift DT_RSHIFT integer_add { $$ = $1 >> $3; } - | integer_add - ; - -integer_add: - integer_add '+' integer_mul { $$ = $1 + $3; } - | integer_add '-' integer_mul { $$ = $1 - $3; } - | integer_mul - ; - -integer_mul: - integer_mul '*' integer_unary { $$ = $1 * $3; } - | integer_mul '/' integer_unary - { - if ($3 != 0) { - $$ = $1 / $3; - } else { - ERROR(&@$, "Division by zero"); - $$ = 0; - } - } - | integer_mul '%' integer_unary - { - if ($3 != 0) { - $$ = $1 % $3; - } else { - ERROR(&@$, "Division by zero"); - $$ = 0; - } - } - | integer_unary - ; - -integer_unary: - integer_prim - | '-' integer_unary { $$ = -$2; } - | '~' integer_unary { $$ = ~$2; } - | '!' integer_unary { $$ = !$2; } - ; - -bytestring: - /* empty */ - { - $$ = empty_data; - } - | bytestring DT_BYTE - { - $$ = data_append_byte($1, $2); - } - | bytestring DT_LABEL - { - $$ = data_add_marker($1, LABEL, $2); - } - ; - -subnodes: - /* empty */ - { - $$ = NULL; - } - | subnode subnodes - { - $$ = chain_node($1, $2); - } - | subnode propdef - { - ERROR(&@2, "Properties must precede subnodes"); - YYERROR; - } - ; - -subnode: - DT_PROPNODENAME nodedef - { - $$ = name_node($2, $1); - } - | DT_DEL_NODE DT_PROPNODENAME ';' - { - $$ = name_node(build_node_delete(), $2); - } - | DT_LABEL subnode - { - add_label(&$2->labels, $1); - $$ = $2; - } - ; - -%% - -void yyerror(char const *s) -{ - ERROR(&yylloc, "%s", s); -} |