Skip to content

Commit

Permalink
libexpr: split yacc prologue & epilogue (NFC)
Browse files Browse the repository at this point in the history
This is an NFC PR that splits epilogue & prologue from parser.

As mentioned in #8812, we can add static checking tools & auto
formatting for these files, but if it is written .y directly, the clang
parser cannot understand the code is actually "C++".
  • Loading branch information
inclyc committed Sep 29, 2023
1 parent 13a9090 commit 6985f96
Show file tree
Hide file tree
Showing 8 changed files with 904 additions and 920 deletions.
93 changes: 1 addition & 92 deletions src/libexpr/lexer.l → src/libexpr/lexer/lexer.l
Original file line number Diff line number Diff line change
Expand Up @@ -15,98 +15,7 @@


%{
#ifdef __clang__
#pragma clang diagnostic ignored "-Wunneeded-internal-declaration"
#endif

#include <boost/lexical_cast.hpp>

#include "nixexpr.hh"
#include "parser-tab.hh"

using namespace nix;

namespace nix {

static inline PosIdx makeCurPos(const YYLTYPE & loc, ParseData * data)
{
return data->state.positions.add(data->origin, loc.first_line, loc.first_column);
}

#define CUR_POS makeCurPos(*yylloc, data)

// backup to recover from yyless(0)
thread_local YYLTYPE prev_yylloc;

static void initLoc(YYLTYPE * loc)
{
loc->first_line = loc->last_line = 1;
loc->first_column = loc->last_column = 1;
}

static void adjustLoc(YYLTYPE * loc, const char * s, size_t len)
{
prev_yylloc = *loc;

loc->first_line = loc->last_line;
loc->first_column = loc->last_column;

for (size_t i = 0; i < len; i++) {
switch (*s++) {
case '\r':
if (*s == '\n') { /* cr/lf */
i++;
s++;
}
/* fall through */
case '\n':
++loc->last_line;
loc->last_column = 1;
break;
default:
++loc->last_column;
}
}
}


// we make use of the fact that the parser receives a private copy of the input
// string and can munge around in it.
static StringToken unescapeStr(SymbolTable & symbols, char * s, size_t length)
{
char * result = s;
char * t = s;
char c;
// the input string is terminated with *two* NULs, so we can safely take
// *one* character after the one being checked against.
while ((c = *s++)) {
if (c == '\\') {
c = *s++;
if (c == 'n') *t = '\n';
else if (c == 'r') *t = '\r';
else if (c == 't') *t = '\t';
else *t = c;
}
else if (c == '\r') {
/* Normalise CR and CR/LF into LF. */
*t = '\n';
if (*s == '\n') s++; /* cr/lf */
}
else *t = c;
t++;
}
return {result, size_t(t - result)};
}


}

#define YY_USER_INIT initLoc(yylloc)
#define YY_USER_ACTION adjustLoc(yylloc, yytext, yyleng);

#define PUSH_STATE(state) yy_push_state(state, yyscanner)
#define POP_STATE() yy_pop_state(yyscanner)

#include "lexer/prologue.cc"
%}


Expand Down
93 changes: 93 additions & 0 deletions src/libexpr/lexer/prologue.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#ifdef __clang__
#pragma clang diagnostic ignored "-Wunneeded-internal-declaration"
#endif

#include <boost/lexical_cast.hpp>

#include "nixexpr.hh"
#include "parser-tab.hh"

using namespace nix;

namespace nix {

static inline PosIdx makeCurPos(const YYLTYPE & loc, ParseData * data)
{
return data->state.positions.add(data->origin, loc.first_line, loc.first_column);
}

#define CUR_POS makeCurPos(*yylloc, data)

// backup to recover from yyless(0)
thread_local YYLTYPE prev_yylloc;

static void initLoc(YYLTYPE * loc)
{
loc->first_line = loc->last_line = 1;
loc->first_column = loc->last_column = 1;
}

static void adjustLoc(YYLTYPE * loc, const char * s, size_t len)
{
prev_yylloc = *loc;

loc->first_line = loc->last_line;
loc->first_column = loc->last_column;

for (size_t i = 0; i < len; i++) {
switch (*s++) {
case '\r':
if (*s == '\n') { /* cr/lf */
i++;
s++;
}
/* fall through */
case '\n':
++loc->last_line;
loc->last_column = 1;
break;
default:
++loc->last_column;
}
}
}

// we make use of the fact that the parser receives a private copy of the input
// string and can munge around in it.
static StringToken unescapeStr(SymbolTable & symbols, char * s, size_t length)
{
char * result = s;
char * t = s;
char c;
// the input string is terminated with *two* NULs, so we can safely take
// *one* character after the one being checked against.
while ((c = *s++)) {
if (c == '\\') {
c = *s++;
if (c == 'n')
*t = '\n';
else if (c == 'r')
*t = '\r';
else if (c == 't')
*t = '\t';
else
*t = c;
} else if (c == '\r') {
/* Normalise CR and CR/LF into LF. */
*t = '\n';
if (*s == '\n')
s++; /* cr/lf */
} else
*t = c;
t++;
}
return {result, size_t(t - result)};
}

}

#define YY_USER_INIT initLoc(yylloc)
#define YY_USER_ACTION adjustLoc(yylloc, yytext, yyleng);

#define PUSH_STATE(state) yy_push_state(state, yyscanner)
#define POP_STATE() yy_pop_state(yyscanner)
4 changes: 2 additions & 2 deletions src/libexpr/local.mk
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ libexpr_LDFLAGS_PROPAGATED = $(BDW_GC_LIBS)

libexpr_ORDER_AFTER := $(d)/parser-tab.cc $(d)/parser-tab.hh $(d)/lexer-tab.cc $(d)/lexer-tab.hh

$(d)/parser-tab.cc $(d)/parser-tab.hh: $(d)/parser.y
$(d)/parser-tab.cc $(d)/parser-tab.hh: $(d)/parser/parser.y $(d)/parser/prologue.cc $(d)/parser/epilogue.cc
$(trace-gen) bison -v -o $(libexpr_DIR)/parser-tab.cc $< -d

$(d)/lexer-tab.cc $(d)/lexer-tab.hh: $(d)/lexer.l
$(d)/lexer-tab.cc $(d)/lexer-tab.hh: $(d)/lexer/lexer.l $(d)/lexer/prologue.cc
$(trace-gen) flex --outfile $(libexpr_DIR)/lexer-tab.cc --header-file=$(libexpr_DIR)/lexer-tab.hh $<

clean-files += $(d)/parser-tab.cc $(d)/parser-tab.hh $(d)/lexer-tab.cc $(d)/lexer-tab.hh
Expand Down
Loading

0 comments on commit 6985f96

Please sign in to comment.