From: Matthew Fernandez Date: Mon, 14 Sep 2020 03:02:48 +0000 (-0700) Subject: implement string mapping of expr parser's token table using Bison feature X-Git-Tag: 2.46.0~20^2^2~72^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6ca590c9228520498f9a905dc13eee43563217f2;p=graphviz implement string mapping of expr parser's token table using Bison feature This removes some juggling to construct a string table of the tokens in the expr parser, to replace it with native Bison functionality. Loosely related to #1806. --- diff --git a/.gitignore b/.gitignore index 44977ad76..b3f996c79 100644 --- a/.gitignore +++ b/.gitignore @@ -173,7 +173,6 @@ lib/common/htmlparse.c lib/common/htmlparse.h lib/common/ps_font_equiv.h lib/common/svgcolor_lib -lib/expr/exop.h lib/expr/exparse.c lib/expr/exparse.h lib/graph/parser.c diff --git a/lib/expr/Makefile.am b/lib/expr/Makefile.am index f022ec69d..e0912a432 100644 --- a/lib/expr/Makefile.am +++ b/lib/expr/Makefile.am @@ -13,7 +13,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/lib/ast \ -I$(top_srcdir)/lib/cdt -noinst_HEADERS = exgram.h exlib.h expr.h +noinst_HEADERS = exgram.h exlib.h exop.h expr.h noinst_LTLIBRARIES = libexpr_C.la ### expr.h includes ast.h and vmalloc.h which we don't install @@ -43,12 +43,6 @@ libexpr_C_la_LIBADD = \ $(libexpr_C_la_OBJECTS) $(libexpr_la_OBJECTS): \ exparse.h exparse.c exgram.h exop.h -exop.h: exparse.h - echo "static const char* exop[] = {" > exop.h - echo " \"MINTOKEN\"," >> exop.h - $(SED) -e '1,/^[ ]*#[ ]*define[ ][ ]*MINTOKEN/d' -e '/MAXTOKEN/,$$d' -e '/^[ ]*#[ ]*define[ ][ ]*[A-Z]/!d' -e 's/^[ ]*#[ ]*define[ ]*\([A-Z0-9_]*\).*/ "\1",/' < exparse.h >> exop.h - echo "};" >> exop.h - exparse.c: y.tab.c @SED@ "s/fprintf/sfprintf/g" #include +#include #include #include #include #ifdef _WIN32 -#include #define srand48 srand #define drand48 rand #endif @@ -51,14 +51,14 @@ lexname(int op, int subop) static char buf[TOTNAME][MAXNAME]; if (op > MINTOKEN && op < MAXTOKEN) - return (char*)exop[op - MINTOKEN]; + return (char*)exop((size_t)op - MINTOKEN); if (++n >= TOTNAME) n = 0; b = buf[n]; if (op == '=') { if (subop > MINTOKEN && subop < MAXTOKEN) - sfsprintf(b, MAXNAME, "%s=", exop[subop - MINTOKEN]); + sfsprintf(b, MAXNAME, "%s=", exop((size_t)subop - MINTOKEN)); else if (subop > ' ' && subop <= '~') sfsprintf(b, MAXNAME, "%c=", subop); else diff --git a/lib/expr/exlexname.c b/lib/expr/exlexname.c index dbc5aa01e..154374d0f 100644 --- a/lib/expr/exlexname.c +++ b/lib/expr/exlexname.c @@ -19,6 +19,7 @@ #include #include +#include #define TOTNAME 3 #define MAXNAME 16 @@ -32,14 +33,14 @@ exlexname(int op, int subop) static char buf[TOTNAME][MAXNAME]; if (op > MINTOKEN && op < MAXTOKEN) - return (char*)exop[op - MINTOKEN]; + return (char*)exop((size_t)op - MINTOKEN); if (++n > TOTNAME) n = 0; b = buf[n]; if (op == '=') { if (subop > MINTOKEN && subop < MAXTOKEN) - sfsprintf(b, MAXNAME, "%s=", exop[subop - MINTOKEN]); + sfsprintf(b, MAXNAME, "%s=", exop((size_t)subop - MINTOKEN)); else if (subop > ' ' && subop <= '~') sfsprintf(b, MAXNAME, "%c=", subop); else sfsprintf(b, MAXNAME, "(%d)=", subop); diff --git a/lib/expr/exop.h b/lib/expr/exop.h new file mode 100644 index 000000000..e4a5d720d --- /dev/null +++ b/lib/expr/exop.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +/** retrieve a string representation of a lexer token + * + * \param id The numerical identifier of the sought token as an offset from + * MINTOKEN + * \return The string name of the token or NULL if id is invalid + */ +const char *exop(size_t id); diff --git a/lib/expr/exparse.y b/lib/expr/exparse.y index 1a4ef2959..aa375ebcd 100644 --- a/lib/expr/exparse.y +++ b/lib/expr/exparse.y @@ -36,7 +36,11 @@ #endif #endif +#include +#include +#include #include +#include #include #undef RS /* hp.pa grabs this!! */ @@ -171,6 +175,11 @@ %token MAXTOKEN + /* ask Bison to generate a table, yytname, containing string representations + * of all the above tokens + */ +%token-table + %{ #include "exgram.h" @@ -1276,4 +1285,48 @@ initialize : assign %% +const char *exop(size_t index) { + + /* yytname is generated by the %token-table directive */ + + /* find the index of MINTOKEN */ + size_t minid; + for (minid = 0; yytname[minid] != NULL; ++minid) { + if (strcmp(yytname[minid], "MINTOKEN") == 0) { + break; + } + } + + assert(yytname[minid] != NULL + && "failed to find MINTOKEN; incorrect token list in exparse.y?"); + + /* find the requested token */ + { + size_t i, j; + for (i = j = minid; yytname[i] != NULL; ++i) { + + /* if this token is not a word, skip it */ + { + size_t k; + for (k = 0; yytname[i][k] != '\0'; ++k) { + if (yytname[i][k] != '_' && !isalnum(yytname[i][k])) { + break; + } + } + if (yytname[i][k] != '\0') { + continue; + } + } + + if (j == index + minid) { + return yytname[i]; + } + ++j; + } + } + + /* failed to find the requested token */ + return NULL; +} + #include "exgram.h" diff --git a/windows/include/expr/exop.h b/windows/include/expr/exop.h deleted file mode 100644 index f37e9c993..000000000 --- a/windows/include/expr/exop.h +++ /dev/null @@ -1,80 +0,0 @@ -static const char* exop[] = { - "MINTOKEN", - "INTEGER", - "UNSIGNED", - "CHARACTER", - "FLOATING", - "STRING", - "VOIDTYPE", - "STATIC", - "ADDRESS", - "ARRAY", - "BREAK", - "CALL", - "CASE", - "CONSTANT", - "CONTINUE", - "DECLARE", - "DEFAULT", - "DYNAMIC", - "ELSE", - "EXIT", - "FOR", - "FUNCTION", - "GSUB", - "ITERATE", - "ITERATER", - "ID", - "IF", - "LABEL", - "MEMBER", - "NAME", - "POS", - "PRAGMA", - "PRE", - "PRINT", - "PRINTF", - "PROCEDURE", - "QUERY", - "RAND", - "RETURN", - "SCANF", - "SPLIT", - "SPRINTF", - "SRAND", - "SSCANF", - "SUB", - "SUBSTR", - "SWITCH", - "TOKENS", - "UNSET", - "WHILE", - "F2I", - "F2S", - "I2F", - "I2S", - "S2B", - "S2F", - "S2I", - "F2X", - "I2X", - "S2X", - "X2F", - "X2I", - "X2S", - "X2X", - "XPRINT", - "OR", - "AND", - "EQ", - "NE", - "LE", - "GE", - "LS", - "RS", - "IN_OP", - "UNARY", - "INC", - "DEC", - "CAST", -};